Changeset 267
- Timestamp:
- 08/18/08 14:43:44 (4 years ago)
- Location:
- trunk
- Files:
-
- 6 added
- 4 removed
- 46 modified
- 2 copied
-
fm_server/configure (modified) (4 diffs)
-
fm_server/configure.ac (modified) (1 diff)
-
fm_server/src/fm_effect_rubber/Makefile.am (modified) (1 diff)
-
fm_server/src/fm_effect_rubber/Makefile.in (modified) (7 diffs)
-
fm_server/src/fm_effect_rubber/fm_effect_rubber.c (modified) (10 diffs)
-
fm_server/src/fm_effect_rubber/fm_effect_rubber.h (modified) (2 diffs)
-
fm_server/src/fm_effect_rubber/fm_rubber_wrapper.cpp (deleted)
-
fm_server/src/fm_effect_rubber/fm_rubber_wrapper.h (deleted)
-
fm_server/src/fm_input_cdj.c (modified) (1 diff)
-
rubberband/ChangeLog (modified) (1 diff)
-
rubberband/README (modified) (3 diffs)
-
rubberband/configure (modified) (1 diff)
-
rubberband/configure.ac (modified) (1 diff)
-
rubberband/include/Makefile.am (modified) (1 diff)
-
rubberband/include/Makefile.in (modified) (1 diff)
-
rubberband/include/RubberBandStretcher.h (modified) (29 diffs)
-
rubberband/include/TimeStretcher.h (deleted)
-
rubberband/include/rubberband-c.h (added)
-
rubberband/misc/Makefile.osx (deleted)
-
rubberband/rubberband.pc.in (modified) (1 diff)
-
rubberband/src/AudioCurve.cpp (modified) (3 diffs)
-
rubberband/src/AudioCurve.h (modified) (3 diffs)
-
rubberband/src/ConstantAudioCurve.cpp (modified) (2 diffs)
-
rubberband/src/ConstantAudioCurve.h (modified) (2 diffs)
-
rubberband/src/FFT.cpp (modified) (43 diffs)
-
rubberband/src/FFT.h (modified) (3 diffs)
-
rubberband/src/HighFrequencyAudioCurve.cpp (modified) (2 diffs)
-
rubberband/src/HighFrequencyAudioCurve.h (modified) (2 diffs)
-
rubberband/src/Makefile.am (modified) (2 diffs)
-
rubberband/src/Makefile.in (modified) (4 diffs)
-
rubberband/src/PercussiveAudioCurve.cpp (modified) (5 diffs)
-
rubberband/src/PercussiveAudioCurve.h (modified) (2 diffs)
-
rubberband/src/Profiler.cpp (added)
-
rubberband/src/Profiler.h (added)
-
rubberband/src/Resampler.cpp (modified) (8 diffs)
-
rubberband/src/Resampler.h (modified) (4 diffs)
-
rubberband/src/RingBuffer.h (modified) (37 diffs)
-
rubberband/src/RubberBandStretcher.cpp (modified) (3 diffs)
-
rubberband/src/Scavenger.h (modified) (2 diffs)
-
rubberband/src/SilentAudioCurve.cpp (added)
-
rubberband/src/SilentAudioCurve.h (copied) (copied from trunk/rubberband/src/HighFrequencyAudioCurve.h) (2 diffs)
-
rubberband/src/SpectralDifferenceAudioCurve.cpp (modified) (3 diffs)
-
rubberband/src/SpectralDifferenceAudioCurve.h (modified) (2 diffs)
-
rubberband/src/StretchCalculator.cpp (modified) (6 diffs)
-
rubberband/src/StretchCalculator.h (modified) (2 diffs)
-
rubberband/src/StretcherChannelData.cpp (modified) (14 diffs)
-
rubberband/src/StretcherChannelData.h (modified) (8 diffs)
-
rubberband/src/StretcherImpl.cpp (modified) (33 diffs)
-
rubberband/src/StretcherImpl.h (modified) (8 diffs)
-
rubberband/src/StretcherProcess.cpp (modified) (25 diffs)
-
rubberband/src/Thread.cpp (modified) (12 diffs)
-
rubberband/src/Thread.h (modified) (4 diffs)
-
rubberband/src/Window.cpp (copied) (copied from trunk/rubberband/src/AudioCurve.cpp) (2 diffs)
-
rubberband/src/Window.h (modified) (4 diffs)
-
rubberband/src/main.cpp (added)
-
rubberband/src/rubberband-c.cpp (added)
-
rubberband/src/sysutils.cpp (modified) (5 diffs)
-
rubberband/src/sysutils.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/fm_server/configure
r257 r267 25268 25268 else 25269 25269 if test -n "$PKG_CONFIG" && \ 25270 { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"rubberband fftw3 samplerate\"") >&525271 ($PKG_CONFIG --exists --print-errors "rubberband fftw3 samplerate") 2>&525270 { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"rubberband = 1.2 fftw3 samplerate\"") >&5 25271 ($PKG_CONFIG --exists --print-errors "rubberband = 1.2 fftw3 samplerate") 2>&5 25272 25272 ac_status=$? 25273 25273 echo "$as_me:$LINENO: \$? = $ac_status" >&5 25274 25274 (exit $ac_status); }; then 25275 pkg_cv_RUBBERBAND_CFLAGS=`$PKG_CONFIG --cflags "rubberband fftw3 samplerate" 2>/dev/null`25275 pkg_cv_RUBBERBAND_CFLAGS=`$PKG_CONFIG --cflags "rubberband = 1.2 fftw3 samplerate" 2>/dev/null` 25276 25276 else 25277 25277 pkg_failed=yes … … 25286 25286 else 25287 25287 if test -n "$PKG_CONFIG" && \ 25288 { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"rubberband fftw3 samplerate\"") >&525289 ($PKG_CONFIG --exists --print-errors "rubberband fftw3 samplerate") 2>&525288 { (echo "$as_me:$LINENO: \$PKG_CONFIG --exists --print-errors \"rubberband = 1.2 fftw3 samplerate\"") >&5 25289 ($PKG_CONFIG --exists --print-errors "rubberband = 1.2 fftw3 samplerate") 2>&5 25290 25290 ac_status=$? 25291 25291 echo "$as_me:$LINENO: \$? = $ac_status" >&5 25292 25292 (exit $ac_status); }; then 25293 pkg_cv_RUBBERBAND_LIBS=`$PKG_CONFIG --libs "rubberband fftw3 samplerate" 2>/dev/null`25293 pkg_cv_RUBBERBAND_LIBS=`$PKG_CONFIG --libs "rubberband = 1.2 fftw3 samplerate" 2>/dev/null` 25294 25294 else 25295 25295 pkg_failed=yes … … 25310 25310 fi 25311 25311 if test $_pkg_short_errors_supported = yes; then 25312 RUBBERBAND_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "rubberband fftw3 samplerate"`25312 RUBBERBAND_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "rubberband = 1.2 fftw3 samplerate"` 25313 25313 else 25314 RUBBERBAND_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "rubberband fftw3 samplerate"`25314 RUBBERBAND_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "rubberband = 1.2 fftw3 samplerate"` 25315 25315 fi 25316 25316 # Put the nasty error message in config.log where it belongs 25317 25317 echo "$RUBBERBAND_PKG_ERRORS" >&5 25318 25318 25319 { { echo "$as_me:$LINENO: error: Package requirements (rubberband fftw3 samplerate) were not met:25319 { { echo "$as_me:$LINENO: error: Package requirements (rubberband = 1.2 fftw3 samplerate) were not met: 25320 25320 25321 25321 $RUBBERBAND_PKG_ERRORS … … 25328 25328 See the pkg-config man page for more details. 25329 25329 " >&5 25330 echo "$as_me: error: Package requirements (rubberband fftw3 samplerate) were not met:25330 echo "$as_me: error: Package requirements (rubberband = 1.2 fftw3 samplerate) were not met: 25331 25331 25332 25332 $RUBBERBAND_PKG_ERRORS -
trunk/fm_server/configure.ac
r257 r267 65 65 AC_SUBST(SAMPLERATE_CFLAGS) 66 66 67 PKG_CHECK_MODULES(RUBBERBAND, rubberband fftw3 samplerate)67 PKG_CHECK_MODULES(RUBBERBAND, rubberband = 1.2 fftw3 samplerate) 68 68 AC_SUBST(RUBBERBAND_LIBS) 69 69 AC_SUBST(RUBBERBAND_CFLAGS) -
trunk/fm_server/src/fm_effect_rubber/Makefile.am
r238 r267 3 3 4 4 libfm_effect_rubber_la_SOURCES = \ 5 fm_rubber_wrapper.cpp \6 fm_rubber_wrapper.h \7 5 fm_effect_rubber.c \ 8 6 fm_effect_rubber.h 9 7 10 8 11 libfm_effect_rubber_la_C PPFLAGS = \9 libfm_effect_rubber_la_CFLAGS = \ 12 10 $(GLIB_CFLAGS) \ 13 11 $(RGC_SERVER_CFLAGS) \ -
trunk/fm_server/src/fm_effect_rubber/Makefile.in
r257 r267 52 52 $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) 53 53 am_libfm_effect_rubber_la_OBJECTS = \ 54 libfm_effect_rubber_la-fm_rubber_wrapper.lo \55 54 libfm_effect_rubber_la-fm_effect_rubber.lo 56 55 libfm_effect_rubber_la_OBJECTS = $(am_libfm_effect_rubber_la_OBJECTS) 56 libfm_effect_rubber_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ 57 $(LIBTOOLFLAGS) --mode=link $(CCLD) \ 58 $(libfm_effect_rubber_la_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ 59 $(LDFLAGS) -o $@ 57 60 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) 58 61 depcomp = $(SHELL) $(top_srcdir)/depcomp … … 66 69 LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ 67 70 --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ 68 $(LDFLAGS) -o $@69 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \70 $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)71 LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \72 --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \73 $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)74 CXXLD = $(CXX)75 CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \76 --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \77 71 $(LDFLAGS) -o $@ 78 72 SOURCES = $(libfm_effect_rubber_la_SOURCES) … … 240 234 noinst_LTLIBRARIES = libfm_effect_rubber.la 241 235 libfm_effect_rubber_la_SOURCES = \ 242 fm_rubber_wrapper.cpp \243 fm_rubber_wrapper.h \244 236 fm_effect_rubber.c \ 245 237 fm_effect_rubber.h 246 238 247 libfm_effect_rubber_la_C PPFLAGS = \239 libfm_effect_rubber_la_CFLAGS = \ 248 240 $(GLIB_CFLAGS) \ 249 241 $(RGC_SERVER_CFLAGS) \ … … 258 250 259 251 .SUFFIXES: 260 .SUFFIXES: .c . cpp .lo .o .obj252 .SUFFIXES: .c .lo .o .obj 261 253 $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) 262 254 @for dep in $?; do \ … … 298 290 done 299 291 libfm_effect_rubber.la: $(libfm_effect_rubber_la_OBJECTS) $(libfm_effect_rubber_la_DEPENDENCIES) 300 $( CXXLINK) $(libfm_effect_rubber_la_OBJECTS) $(libfm_effect_rubber_la_LIBADD) $(LIBS)292 $(libfm_effect_rubber_la_LINK) $(libfm_effect_rubber_la_OBJECTS) $(libfm_effect_rubber_la_LIBADD) $(LIBS) 301 293 302 294 mostlyclean-compile: … … 307 299 308 300 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfm_effect_rubber_la-fm_effect_rubber.Plo@am__quote@ 309 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfm_effect_rubber_la-fm_rubber_wrapper.Plo@am__quote@310 301 311 302 .c.o: … … 331 322 332 323 libfm_effect_rubber_la-fm_effect_rubber.lo: fm_effect_rubber.c 333 @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $( libfm_effect_rubber_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libfm_effect_rubber_la-fm_effect_rubber.lo -MD -MP -MF $(DEPDIR)/libfm_effect_rubber_la-fm_effect_rubber.Tpo -c -o libfm_effect_rubber_la-fm_effect_rubber.lo `test -f 'fm_effect_rubber.c' || echo '$(srcdir)/'`fm_effect_rubber.c324 @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfm_effect_rubber_la_CFLAGS) $(CFLAGS) -MT libfm_effect_rubber_la-fm_effect_rubber.lo -MD -MP -MF $(DEPDIR)/libfm_effect_rubber_la-fm_effect_rubber.Tpo -c -o libfm_effect_rubber_la-fm_effect_rubber.lo `test -f 'fm_effect_rubber.c' || echo '$(srcdir)/'`fm_effect_rubber.c 334 325 @am__fastdepCC_TRUE@ mv -f $(DEPDIR)/libfm_effect_rubber_la-fm_effect_rubber.Tpo $(DEPDIR)/libfm_effect_rubber_la-fm_effect_rubber.Plo 335 326 @AMDEP_TRUE@@am__fastdepCC_FALSE@ source='fm_effect_rubber.c' object='libfm_effect_rubber_la-fm_effect_rubber.lo' libtool=yes @AMDEPBACKSLASH@ 336 327 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 337 @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfm_effect_rubber_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libfm_effect_rubber_la-fm_effect_rubber.lo `test -f 'fm_effect_rubber.c' || echo '$(srcdir)/'`fm_effect_rubber.c 338 339 .cpp.o: 340 @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< 341 @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po 342 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ 343 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 344 @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< 345 346 .cpp.obj: 347 @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` 348 @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po 349 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ 350 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 351 @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` 352 353 .cpp.lo: 354 @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< 355 @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo 356 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ 357 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 358 @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< 359 360 libfm_effect_rubber_la-fm_rubber_wrapper.lo: fm_rubber_wrapper.cpp 361 @am__fastdepCXX_TRUE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfm_effect_rubber_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libfm_effect_rubber_la-fm_rubber_wrapper.lo -MD -MP -MF $(DEPDIR)/libfm_effect_rubber_la-fm_rubber_wrapper.Tpo -c -o libfm_effect_rubber_la-fm_rubber_wrapper.lo `test -f 'fm_rubber_wrapper.cpp' || echo '$(srcdir)/'`fm_rubber_wrapper.cpp 362 @am__fastdepCXX_TRUE@ mv -f $(DEPDIR)/libfm_effect_rubber_la-fm_rubber_wrapper.Tpo $(DEPDIR)/libfm_effect_rubber_la-fm_rubber_wrapper.Plo 363 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='fm_rubber_wrapper.cpp' object='libfm_effect_rubber_la-fm_rubber_wrapper.lo' libtool=yes @AMDEPBACKSLASH@ 364 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 365 @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libfm_effect_rubber_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libfm_effect_rubber_la-fm_rubber_wrapper.lo `test -f 'fm_rubber_wrapper.cpp' || echo '$(srcdir)/'`fm_rubber_wrapper.cpp 328 @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libfm_effect_rubber_la_CFLAGS) $(CFLAGS) -c -o libfm_effect_rubber_la-fm_effect_rubber.lo `test -f 'fm_effect_rubber.c' || echo '$(srcdir)/'`fm_effect_rubber.c 366 329 367 330 mostlyclean-libtool: -
trunk/fm_server/src/fm_effect_rubber/fm_effect_rubber.c
r246 r267 29 29 #include <rgc_server.h> 30 30 31 #include <rubberband-c.h> 32 31 33 #include "../fm_buffer.h" 32 34 #include "../fm_element.h" 33 35 #include "../fm_input.h" 34 36 #include "../fm_effect.h" 35 #include "fm_rubber_wrapper.h"36 37 #include "fm_effect_rubber.h" 37 38 … … 138 139 fm_effect_rubber_init (FmEffectRubber *rubber) 139 140 { 140 rubber-> wrap= NULL;141 rubber->state = NULL; 141 142 rubber->temp_buffer = NULL; 142 143 rubber->time_ratio = 1.0; … … 166 167 return FALSE; 167 168 168 rubber-> wrap = fm_rubber_wrapper_new ();169 rubber->state = rubberband_new (44100, 2, RubberBandOptionProcessRealTime, 1.0, 1.0); /* FIXME: 44100 */ 169 170 rubber->temp_buffer = fm_buffer_new (16384, FM_CHANNELS_STEREO); 170 171 rubber->channel_ptr = g_new (gfloat *, FM_CHANNELS_STEREO); … … 181 182 g_free (rubber->channel_ptr); 182 183 fm_buffer_destroy (rubber->temp_buffer); 183 fm_rubber_wrapper_destroy (rubber->wrap);184 rubberband_delete (rubber->state); 184 185 185 186 return TRUE; … … 196 197 197 198 if (rubber->change_time_ratio > -1) { 198 fm_rubber_wrapper_set_time_ratio (rubber->wrap, rubber->change_time_ratio);199 rubberband_set_time_ratio (rubber->state, rubber->change_time_ratio); 199 200 rubber->time_ratio = rubber->change_time_ratio; 200 201 rubber->change_time_ratio = -1; 201 rubber->latency = fm_rubber_wrapper_get_latency (rubber->wrap);202 rubber->latency = rubberband_get_latency (rubber->state); 202 203 } 203 204 204 205 if (rubber->change_pitch_scale > -1) { 205 fm_rubber_wrapper_set_pitch_scale (rubber->wrap, rubber->change_pitch_scale);206 rubberband_set_pitch_scale (rubber->state, rubber->change_pitch_scale); 206 207 rubber->pitch_scale = rubber->change_pitch_scale; 207 208 rubber->change_pitch_scale = -1; 208 rubber->latency = fm_rubber_wrapper_get_latency (rubber->wrap);209 rubber->latency = rubberband_get_latency (rubber->state); 209 210 } 210 211 … … 218 219 219 220 while (samples_needed > 0) { 220 guint samples_avail = fm_rubber_wrapper_available (rubber->wrap);221 guint samples_avail = rubberband_available (rubber->state); 221 222 222 223 if (samples_avail) { … … 226 227 ask_for = samples_needed; 227 228 228 guint retrieved = fm_rubber_wrapper_retrieve (rubber->wrap, rubber->channel_ptr, ask_for);229 guint retrieved = rubberband_retrieve (rubber->state, rubber->channel_ptr, ask_for); 229 230 samples_needed -= retrieved; 230 231 … … 241 242 } else { 242 243 /* ask for another buffer from our source */ 243 guint samples_req = fm_rubber_wrapper_get_samples_required (rubber->wrap);244 guint samples_req = rubberband_get_samples_required (rubber->state); 244 245 245 246 //g_print ("Requested %u samples\n", samples_req); … … 250 251 if (rubber->temp_buffer->discont == TRUE) { 251 252 g_print ("***************** DISCONT!!!!\n"); 252 fm_rubber_wrapper_reset (rubber->wrap);253 rubberband_reset (rubber->state); 253 254 start_timestamp = rubber->temp_buffer->timestamp_ns; 254 255 … … 261 262 rubber->temp_timestamp_ns = rubber->temp_buffer->timestamp_ns; 262 263 263 fm_rubber_wrapper_process (rubber->wrap,rubber->temp_buffer->channel_data, samples_req, FALSE);264 rubberband_process (rubber->state, (const float *const *) rubber->temp_buffer->channel_data, samples_req, FALSE); 264 265 } 265 266 -
trunk/fm_server/src/fm_effect_rubber/fm_effect_rubber.h
r245 r267 32 32 #define FM_EFFECT_RUBBER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), FM_TYPE_EFFECT_RUBBER, FmEffectRubberClass)) 33 33 34 /* Avoid the need of including "rubberband-c.h" from other plugins */ 35 #ifndef RubberBandState 36 #define RubberBandState void* 37 #endif 38 34 39 35 40 typedef struct _FmEffectRubber FmEffectRubber; … … 40 45 FmEffect effect; 41 46 42 FmRubberWrapper *wrap;47 RubberBandState state; 43 48 44 49 FmBuffer *temp_buffer; -
trunk/fm_server/src/fm_input_cdj.c
r266 r267 31 31 #include "fm_input_gst/fm_input_gst_common.h" 32 32 #include "fm_input_gst/fm_input_gst.h" 33 //#include "fm_effect_rate.h"34 #include "fm_effect_rubber/fm_rubber_wrapper.h"35 33 #include "fm_effect_rubber/fm_effect_rubber.h" 36 34 #include "fm_output.h" -
trunk/rubberband/ChangeLog
r234 r267 1 2 Changes since Rubber Band v1.0.1 3 4 * Added an initial "formant preservation" option when pitch shifting 5 * Real-time pitch shifting now uses a faster method by default, with 6 less variation in CPU usage 7 * The code is more amenable to compiler auto-vectorization (through 8 e.g. gcc --ftree-vectorize). 9 -
trunk/rubberband/README
r234 r267 5 5 An audio time-stretching and pitch-shifting library and utility program. 6 6 7 Copyright 200 7Chris Cannam, cannam@all-day-breakfast.com.7 Copyright 2008 Chris Cannam, cannam@all-day-breakfast.com. 8 8 9 9 Distributed under the GNU General Public License. … … 20 20 21 21 Rubber Band is a phase-vocoder-based frequency domain time 22 stretcher with p artial phase locking to peak frequencies and phase23 resynchronisation at noisy transients. It is suitable for most24 m usical uses with its default settings, and has a range of options25 for fine tuning.22 stretcher with phase resynchronisation at noisy transients and a 23 phase lamination technique to reduce phasiness. It is suitable for 24 most musical uses with its default settings, and has a range of 25 options for fine tuning. 26 26 27 27 * Real-time capable … … 143 143 There is extensive documentation in the class header. 144 144 145 A header with C language bindings is also provided in 146 <rubberband/rubberband-c.h>. This is a wrapper around the C++ 147 implementation, and as the implementation is the same, it also 148 requires linkage against the C++ standard libraries. It is not yet 149 documented separately from the C++ header. You should include only 150 one of the two headers, not both. 151 145 152 The source code for the command-line utility (src/main.cpp) provides a 146 153 good example of how to use Rubber Band in offline mode; the LADSPA -
trunk/rubberband/configure
r257 r267 21300 21300 21301 21301 if test "x$GCC" = "xyes"; then 21302 case " $CFLAGS " in 21303 *[\ \ ]-fPIC\ -Wall[\ \ ]*) ;; 21304 *) CFLAGS="$CFLAGS -fPIC -Wall" ;; 21305 esac 21302 21306 case " $CXXFLAGS " in 21303 21307 *[\ \ ]-fPIC\ -Wall[\ \ ]*) ;; -
trunk/rubberband/configure.ac
r236 r267 29 29 changequote(,)dnl 30 30 if test "x$GCC" = "xyes"; then 31 case " $CFLAGS " in 32 *[\ \ ]-fPIC\ -Wall[\ \ ]*) ;; 33 *) CFLAGS="$CFLAGS -fPIC -Wall" ;; 34 esac 31 35 case " $CXXFLAGS " in 32 36 *[\ \ ]-fPIC\ -Wall[\ \ ]*) ;; -
trunk/rubberband/include/Makefile.am
r235 r267 2 2 3 3 librubberband_include_DATA = \ 4 TimeStretcher.h \4 rubberband-c.h \ 5 5 RubberBandStretcher.h 6 6 -
trunk/rubberband/include/Makefile.in
r257 r267 168 168 librubberband_includedir = $(pkgincludedir) 169 169 librubberband_include_DATA = \ 170 TimeStretcher.h \170 rubberband-c.h \ 171 171 RubberBandStretcher.h 172 172 -
trunk/rubberband/include/RubberBandStretcher.h
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 15 15 #ifndef _RUBBERBANDSTRETCHER_H_ 16 16 #define _RUBBERBANDSTRETCHER_H_ 17 18 #include "TimeStretcher.h" 17 18 #define RUBBERBAND_VERSION "1.2.0-gpl" 19 #define RUBBERBAND_API_MAJOR_VERSION 2 20 #define RUBBERBAND_API_MINOR_VERSION 0 19 21 20 22 #include <vector> 23 24 /** 25 * @mainpage RubberBand 26 * 27 * The Rubber Band API is contained in the single class 28 * RubberBand::RubberBandStretcher. 29 * 30 * Threading notes for real-time applications: 31 * 32 * Multiple instances of RubberBandStretcher may be created and used 33 * in separate threads concurrently. However, for any single instance 34 * of RubberBandStretcher, you may not call process() more than once 35 * concurrently, and you may not change the time or pitch ratio while 36 * a process() call is being executed (if the stretcher was created in 37 * "real-time mode"; in "offline mode" you can't change the ratios 38 * during use anyway). 39 * 40 * So you can run process() in its own thread if you like, but if you 41 * want to change ratios dynamically from a different thread, you will 42 * need some form of mutex in your code. Changing the time or pitch 43 * ratio is real-time safe except in extreme circumstances, so for 44 * most applications that may change these dynamically it probably 45 * makes most sense to do so from the same thread as calls process(), 46 * even if that is a real-time thread. 47 */ 21 48 22 49 namespace RubberBand 23 50 { 24 51 25 class RubberBandStretcher : public TimeStretcher52 class RubberBandStretcher 26 53 { 27 54 public: 28 29 55 /** 30 56 * Processing options for the timestretcher. The preferred … … 103 129 * any time. 104 130 * 105 * \li \c OptionPhaseAdaptive - Lock the adjustments of phase 106 * for frequencies close to peak frequencies to those of the 107 * peak, but reduce the degree of locking as the stretch ratio 108 * gets longer. This, the default setting, should give a good 109 * balance between clarity and smoothness in most situations. 110 * 111 * \li \c OptionPhasePeakLocked - Lock the adjustments of phase 112 * for frequencies close to peak frequencies to those of the 113 * peak. This should give a clear result in situations with 114 * relatively low stretch ratios, but a relatively metallic 115 * sound at longer stretches. 116 * 117 * \li \c OptionPhaseIndependent - Do not lock phase adjustments 118 * to peak frequencies. This usually results in a softer, 119 * phasier sound. 131 * \li \c OptionPhaseLaminar - Adjust phases when stretching in 132 * such a way as to try to retain the continuity of phase 133 * relationships between adjacent frequency bins whose phases 134 * are behaving in similar ways. This, the default setting, 135 * should give good results in most situations. 136 * 137 * \li \c OptionPhaseIndependent - Adjust the phase in each 138 * frequency bin independently from its neighbours. This 139 * usually results in a slightly softer, phasier sound. 120 140 * 121 141 * 5. Flags prefixed \c OptionThreading control the threading … … 152 172 * likely to result in a smoother sound at the expense of 153 173 * clarity and timing. 154 */ 174 * 175 * 7. Flags prefixed \c OptionFormant control the handling of 176 * formant shape (spectral envelope) when pitch-shifting. These 177 * options may be changed at any time. 178 * 179 * \li \c OptionFormantShifted - Apply no special formant 180 * processing. The spectral envelope will be pitch shifted as 181 * normal. 182 * 183 * \li \c OptionFormantPreserved - Preserve the spectral 184 * envelope of the unshifted signal. This permits shifting the 185 * note frequency without so substantially affecting the 186 * perceived pitch profile of the voice or instrument. 187 * 188 * 8. Flags prefixed \c OptionPitch control the method used for 189 * pitch shifting. These options may be changed at any time. 190 * They are only effective in realtime mode; in offline mode, the 191 * pitch-shift method is fixed. 192 * 193 * \li \c OptionPitchHighSpeed - Use a method with a CPU cost 194 * that is relatively moderate and predictable. This may 195 * sound less clear than OptionPitchHighQuality, especially 196 * for large pitch shifts. 197 198 * \li \c OptionPitchHighQuality - Use the highest quality 199 * method for pitch shifting. This method has a CPU cost 200 * approximately proportional to the required frequency shift. 201 202 * \li \c OptionPitchHighConsistency - Use the method that gives 203 * greatest consistency when used to create small variations in 204 * pitch around the 1.0-ratio level. Unlike the previous two 205 * options, this avoids discontinuities when moving across the 206 * 1.0 pitch scale in real-time; it also consumes more CPU than 207 * the others in the case where the pitch scale is exactly 1.0. 208 */ 209 210 enum Option { 211 212 OptionProcessOffline = 0x00000000, 213 OptionProcessRealTime = 0x00000001, 214 215 OptionStretchElastic = 0x00000000, 216 OptionStretchPrecise = 0x00000010, 217 218 OptionTransientsCrisp = 0x00000000, 219 OptionTransientsMixed = 0x00000100, 220 OptionTransientsSmooth = 0x00000200, 221 222 OptionPhaseLaminar = 0x00000000, 223 OptionPhaseIndependent = 0x00002000, 224 225 OptionThreadingAuto = 0x00000000, 226 OptionThreadingNever = 0x00010000, 227 OptionThreadingAlways = 0x00020000, 228 229 OptionWindowStandard = 0x00000000, 230 OptionWindowShort = 0x00100000, 231 OptionWindowLong = 0x00200000, 232 233 OptionFormantShifted = 0x00000000, 234 OptionFormantPreserved = 0x01000000, 235 236 OptionPitchHighSpeed = 0x00000000, 237 OptionPitchHighQuality = 0x02000000, 238 OptionPitchHighConsistency = 0x04000000 239 }; 240 155 241 typedef int Options; 156 157 static const int OptionProcessOffline = 0x00000000; 158 static const int OptionProcessRealTime = 0x00000001; 159 160 static const int OptionStretchElastic = 0x00000000; 161 static const int OptionStretchPrecise = 0x00000010; 162 163 static const int OptionTransientsCrisp = 0x00000000; 164 static const int OptionTransientsMixed = 0x00000100; 165 static const int OptionTransientsSmooth = 0x00000200; 166 167 static const int OptionPhaseAdaptive = 0x00000000; 168 static const int OptionPhasePeakLocked = 0x00001000; 169 static const int OptionPhaseIndependent = 0x00002000; 170 171 static const int OptionThreadingAuto = 0x00000000; 172 static const int OptionThreadingNever = 0x00010000; 173 static const int OptionThreadingAlways = 0x00020000; 174 175 static const int OptionWindowStandard = 0x00000000; 176 static const int OptionWindowShort = 0x00100000; 177 static const int OptionWindowLong = 0x00200000; 178 179 static const int DefaultOptions = 0x00000000; 180 static const int PercussiveOptions = OptionWindowShort | \ 181 OptionPhaseIndependent; 242 243 enum PresetOption { 244 DefaultOptions = 0x00000000, 245 PercussiveOptions = 0x00102000 246 }; 182 247 183 248 /** … … 194 259 double initialTimeRatio = 1.0, 195 260 double initialPitchScale = 1.0); 196 virtual~RubberBandStretcher();261 ~RubberBandStretcher(); 197 262 198 263 /** … … 201 266 * (although retaining the current time and pitch ratio). 202 267 */ 203 v irtual void reset();268 void reset(); 204 269 205 270 /** … … 224 289 * run at once (there is no internal mutex for this purpose). 225 290 */ 226 v irtual void setTimeRatio(double ratio);291 void setTimeRatio(double ratio); 227 292 228 293 /** … … 251 316 * run at once (there is no internal mutex for this purpose). 252 317 */ 253 v irtual void setPitchScale(double scale);318 void setPitchScale(double scale); 254 319 255 320 /** … … 257 322 * construction or with setTimeRatio()). 258 323 */ 259 virtualdouble getTimeRatio() const;324 double getTimeRatio() const; 260 325 261 326 /** … … 263 328 * on construction or with setPitchScale()). 264 329 */ 265 virtualdouble getPitchScale() const;330 double getPitchScale() const; 266 331 267 332 /** … … 274 339 * ratio and other options. 275 340 */ 276 virtualsize_t getLatency() const;341 size_t getLatency() const; 277 342 278 343 /** … … 282 347 * construction). 283 348 */ 284 v irtual void setTransientsOption(Options options);349 void setTransientsOption(Options options); 285 350 286 351 /** … … 292 357 * way when this function is called. 293 358 */ 294 virtual void setPhaseOption(Options options); 359 void setPhaseOption(Options options); 360 361 /** 362 * Change an OptionFormant configuration setting. This may be 363 * called at any time in any mode. 364 * 365 * Note that if running multi-threaded in Offline mode, the change 366 * may not take effect immediately if processing is already under 367 * way when this function is called. 368 */ 369 void setFormantOption(Options options); 370 371 /** 372 * Change an OptionPitch configuration setting. This may be 373 * called at any time in RealTime mode. It may not be called in 374 * Offline mode (for which the transients option is fixed on 375 * construction). 376 */ 377 void setPitchOption(Options options); 295 378 296 379 /** … … 301 384 * possible and this value is ignored. 302 385 */ 303 v irtual void setExpectedInputDuration(size_t samples);386 void setExpectedInputDuration(size_t samples); 304 387 305 388 /** … … 315 398 * and from which there is no output). 316 399 */ 317 virtualsize_t getSamplesRequired() const;400 size_t getSamplesRequired() const; 318 401 319 402 /** … … 332 415 * and from which there is no output). 333 416 */ 334 v irtual void setMaxProcessSize(size_t samples);417 void setMaxProcessSize(size_t samples); 335 418 336 419 /** … … 351 434 * be provided to study() before the first process() call. 352 435 */ 353 v irtual void study(const float *const *input, size_t samples, bool final);436 void study(const float *const *input, size_t samples, bool final); 354 437 355 438 /** … … 359 442 * Set "final" to true if this is the last block of input data. 360 443 */ 361 v irtual void process(const float *const *input, size_t samples, bool final);444 void process(const float *const *input, size_t samples, bool final); 362 445 363 446 /** … … 374 457 * and all output read, and the stretch process is now finished. 375 458 */ 376 virtualint available() const;459 int available() const; 377 460 378 461 /** … … 383 466 * retrieved. 384 467 */ 385 virtualsize_t retrieve(float *const *output, size_t samples) const;468 size_t retrieve(float *const *output, size_t samples) const; 386 469 387 470 /** … … 390 473 * This function is not for general use. 391 474 */ 392 virtualfloat getFrequencyCutoff(int n) const;475 float getFrequencyCutoff(int n) const; 393 476 394 477 /** … … 397 480 * This function is not for general use. 398 481 */ 399 v irtual void setFrequencyCutoff(int n, float f);482 void setFrequencyCutoff(int n, float f); 400 483 401 484 /** … … 404 487 * This function is provided for diagnostic purposes only. 405 488 */ 406 virtualsize_t getInputIncrement() const;489 size_t getInputIncrement() const; 407 490 408 491 /** … … 415 498 * This function is provided for diagnostic purposes only. 416 499 */ 417 virtualstd::vector<int> getOutputIncrements() const;500 std::vector<int> getOutputIncrements() const; 418 501 419 502 /** … … 426 509 * This function is provided for diagnostic purposes only. 427 510 */ 428 virtualstd::vector<float> getPhaseResetCurve() const;511 std::vector<float> getPhaseResetCurve() const; 429 512 430 513 /** … … 436 519 * This function is provided for diagnostic purposes only. 437 520 */ 438 virtualstd::vector<int> getExactTimePoints() const;521 std::vector<int> getExactTimePoints() const; 439 522 440 523 /** … … 442 525 * with. 443 526 */ 444 virtualsize_t getChannelCount() const;527 size_t getChannelCount() const; 445 528 446 529 /** … … 451 534 * This function is provided for diagnostic purposes only. 452 535 */ 453 v irtual void calculateStretch();536 void calculateStretch(); 454 537 455 538 /** … … 460 543 * called. 461 544 */ 462 v irtual void setDebugLevel(int level);545 void setDebugLevel(int level); 463 546 464 547 /** -
trunk/rubberband/rubberband.pc.in
r238 r267 2 2 exec_prefix=@exec_prefix@ 3 3 libdir=@libdir@ 4 includedir=@includedir@ /rubberband4 includedir=@includedir@ 5 5 6 6 Name: rubberband 7 Version: 1. 07 Version: 1.2 8 8 Description: 9 Requires: fftw3, samplerate 10 Libs: -L@libdir@ -lrubberband 11 Cflags: -I@includedir@/rubberband 9 Libs: -L${libdir} -lrubberband 10 Cflags: -I${includedir}/rubberband -
trunk/rubberband/src/AudioCurve.cpp
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 14 14 15 15 #include "AudioCurve.h" 16 17 #include <iostream> 18 using namespace std; 16 19 17 20 namespace RubberBand … … 28 31 } 29 32 33 float 34 AudioCurve::process(const double *R__ mag, size_t increment) 35 { 36 cerr << "WARNING: Using inefficient AudioCurve::process(double)" << endl; 37 float *tmp = new float[m_windowSize]; 38 for (int i = 0; i < int(m_windowSize); ++i) tmp[i] = float(mag[i]); 39 float df = process(tmp, increment); 40 delete[] tmp; 41 return df; 42 } 30 43 31 44 } -
trunk/rubberband/src/AudioCurve.h
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 18 18 #include <sys/types.h> 19 19 20 #include "sysutils.h" 21 20 22 namespace RubberBand 21 23 { … … 29 31 virtual void setWindowSize(size_t newSize) = 0; 30 32 31 virtual float process(float *mag, size_t increment) = 0; 33 virtual float process(const float *R__ mag, size_t increment) = 0; 34 virtual float process(const double *R__ mag, size_t increment); 32 35 virtual void reset() = 0; 33 36 -
trunk/rubberband/src/ConstantAudioCurve.cpp
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 39 39 40 40 float 41 ConstantAudioCurve::process( float *, size_t)41 ConstantAudioCurve::process(const float *R__, size_t) 42 42 { 43 43 return 1.f; -
trunk/rubberband/src/ConstantAudioCurve.h
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 29 29 virtual void setWindowSize(size_t newSize); 30 30 31 virtual float process( float *mag, size_t increment);31 virtual float process(const float *R__ mag, size_t increment); 32 32 virtual void reset(); 33 33 }; -
trunk/rubberband/src/FFT.cpp
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 15 15 #include "FFT.h" 16 16 #include "Thread.h" 17 18 17 #include "Profiler.h" 18 19 //#define FFT_MEASUREMENT 1 20 21 22 #ifdef HAVE_FFTW3 19 23 #include <fftw3.h> 24 #endif 25 26 #ifdef USE_KISSFFT 27 #include "bsd-3rdparty/kissfft/kiss_fftr.h" 28 #endif 29 30 #ifndef HAVE_FFTW3 31 #ifndef USE_KISSFFT 32 #ifndef USE_BUILTIN_FFT 33 #error No FFT implementation selected! 34 #endif 35 #endif 36 #endif 20 37 21 38 #include <cmath> … … 23 40 #include <map> 24 41 #include <cstdio> 42 #include <cstdlib> 25 43 #include <vector> 26 44 … … 35 53 virtual void initDouble() = 0; 36 54 37 virtual void forward(double *realIn, double *realOut, double *imagOut) = 0; 38 virtual void forwardPolar(double *realIn, double *magOut, double *phaseOut) = 0; 39 virtual void forwardMagnitude(double *realIn, double *magOut) = 0; 40 41 virtual void forward(float *realIn, float *realOut, float *imagOut) = 0; 42 virtual void forwardPolar(float *realIn, float *magOut, float *phaseOut) = 0; 43 virtual void forwardMagnitude(float *realIn, float *magOut) = 0; 44 45 virtual void inverse(double *realIn, double *imagIn, double *realOut) = 0; 46 virtual void inversePolar(double *magIn, double *phaseIn, double *realOut) = 0; 47 48 virtual void inverse(float *realIn, float *imagIn, float *realOut) = 0; 49 virtual void inversePolar(float *magIn, float *phaseIn, float *realOut) = 0; 55 virtual void forward(const double *R__ realIn, double *R__ realOut, double *R__ imagOut) = 0; 56 virtual void forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut) = 0; 57 virtual void forwardMagnitude(const double *R__ realIn, double *R__ magOut) = 0; 58 59 virtual void forward(const float *R__ realIn, float *R__ realOut, float *R__ imagOut) = 0; 60 virtual void forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut) = 0; 61 virtual void forwardMagnitude(const float *R__ realIn, float *R__ magOut) = 0; 62 63 virtual void inverse(const double *R__ realIn, const double *R__ imagIn, double *R__ realOut) = 0; 64 virtual void inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut) = 0; 65 virtual void inverseCepstral(const double *R__ magIn, double *R__ cepOut) = 0; 66 67 virtual void inverse(const float *R__ realIn, const float *R__ imagIn, float *R__ realOut) = 0; 68 virtual void inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut) = 0; 69 virtual void inverseCepstral(const float *R__ magIn, float *R__ cepOut) = 0; 50 70 51 71 virtual float *getFloatTimeBuffer() = 0; … … 53 73 }; 54 74 55 56 75 namespace FFTs { 76 77 78 #ifdef HAVE_FFTW3 57 79 58 80 // Define FFTW_DOUBLE_ONLY to make all uses of FFTW functions be … … 80 102 81 103 #ifdef FFTW_DOUBLE_ONLY 104 #define fft_float_type double 82 105 #define fftwf_complex fftw_complex 83 106 #define fftwf_plan fftw_plan … … 92 115 #define cosf cos 93 116 #define sinf sin 117 #else 118 #define fft_float_type float 94 119 #endif /* FFTW_DOUBLE_ONLY */ 95 120 96 121 #ifdef FFTW_FLOAT_ONLY 122 #define fft_double_type float 97 123 #define fftw_complex fftwf_complex 98 124 #define fftw_plan fftwf_plan … … 106 132 #define sqrt sqrtf 107 133 #define cos cosf 108 #define sif sinf 134 #define sin sinf 135 #else 136 #define fft_double_type double 109 137 #endif /* FFTW_FLOAT_ONLY */ 110 138 … … 112 140 { 113 141 public: 114 D_FFTW( unsignedint size) : m_fplanf(0)142 D_FFTW(int size) : m_fplanf(0) 115 143 #ifdef FFTW_DOUBLE_ONLY 116 144 , m_frb(0) … … 130 158 if (m_extantf > 0 && --m_extantf == 0) save = true; 131 159 m_extantMutex.unlock(); 160 #ifndef FFTW_DOUBLE_ONLY 132 161 if (save) saveWisdom('f'); 162 #endif 133 163 fftwf_destroy_plan(m_fplanf); 134 164 fftwf_destroy_plan(m_fplani); … … 144 174 if (m_extantd > 0 && --m_extantd == 0) save = true; 145 175 m_extantMutex.unlock(); 176 #ifndef FFTW_FLOAT_ONLY 146 177 if (save) saveWisdom('d'); 178 #endif 147 179 fftw_destroy_plan(m_dplanf); 148 180 fftw_destroy_plan(m_dplani); … … 163 195 #ifdef FFTW_DOUBLE_ONLY 164 196 if (load) loadWisdom('d'); 165 m_fbuf = (double *)fftw_malloc(m_size * sizeof(double));166 197 #else 167 198 if (load) loadWisdom('f'); 168 m_fbuf = (float *)fftwf_malloc(m_size * sizeof(float)); 169 #endif 199 #endif 200 m_fbuf = (fft_float_type *)fftw_malloc(m_size * sizeof(fft_float_type)); 170 201 m_fpacked = (fftwf_complex *)fftw_malloc 171 202 ((m_size/2 + 1) * sizeof(fftwf_complex)); … … 184 215 #ifdef FFTW_FLOAT_ONLY 185 216 if (load) loadWisdom('f'); 186 m_dbuf = (float *)fftwf_malloc(m_size * sizeof(float));187 217 #else 188 218 if (load) loadWisdom('d'); 189 m_dbuf = (double *)fftw_malloc(m_size * sizeof(double)); 190 #endif 219 #endif 220 m_dbuf = (fft_double_type *)fftw_malloc(m_size * sizeof(fft_double_type)); 191 221 m_dpacked = (fftw_complex *)fftw_malloc 192 222 ((m_size/2 + 1) * sizeof(fftw_complex)); … … 251 281 } 252 282 253 void packFloat(float *re, float *im) { 254 for (unsigned int i = 0; i <= m_size/2; ++i) { 255 m_fpacked[i][0] = re[i]; 256 m_fpacked[i][1] = im[i]; 257 } 258 } 259 260 void packDouble(double *re, double *im) { 261 for (unsigned int i = 0; i <= m_size/2; ++i) { 262 m_dpacked[i][0] = re[i]; 263 m_dpacked[i][1] = im[i]; 264 } 265 } 266 267 void unpackFloat(float *re, float *im) { 268 for (unsigned int i = 0; i <= m_size/2; ++i) { 283 void packFloat(const float *R__ re, const float *R__ im) { 284 const int hs = m_size/2; 285 fftwf_complex *const R__ fpacked = m_fpacked; 286 for (int i = 0; i <= hs; ++i) { 287 fpacked[i][0] = re[i]; 288 } 289 if (im) { 290 for (int i = 0; i <= hs; ++i) { 291 fpacked[i][1] = im[i]; 292 } 293 } else { 294 for (int i = 0; i <= hs; ++i) { 295 fpacked[i][1] = 0.f; 296 } 297 } 298 } 299 300 void packDouble(const double *R__ re, const double *R__ im) { 301 const int hs = m_size/2; 302 fftw_complex *const R__ dpacked = m_dpacked; 303 for (int i = 0; i <= hs; ++i) { 304 dpacked[i][0] = re[i]; 305 } 306 if (im) { 307 for (int i = 0; i <= hs; ++i) { 308 dpacked[i][1] = im[i]; 309 } 310 } else { 311 for (int i = 0; i <= hs; ++i) { 312 dpacked[i][1] = 0.0; 313 } 314 } 315 } 316 317 void unpackFloat(float *R__ re, float *R__ im) { 318 const int hs = m_size/2; 319 for (int i = 0; i <= hs; ++i) { 269 320 re[i] = m_fpacked[i][0]; 270 im[i] = m_fpacked[i][1]; 321 } 322 if (im) { 323 for (int i = 0; i <= hs; ++i) { 324 im[i] = m_fpacked[i][1]; 325 } 271 326 } 272 327 } 273 328 274 void unpackDouble(double *re, double *im) { 275 for (unsigned int i = 0; i <= m_size/2; ++i) { 329 void unpackDouble(double *R__ re, double *R__ im) { 330 const int hs = m_size/2; 331 for (int i = 0; i <= hs; ++i) { 276 332 re[i] = m_dpacked[i][0]; 277 im[i] = m_dpacked[i][1]; 333 } 334 if (im) { 335 for (int i = 0; i <= hs; ++i) { 336 im[i] = m_dpacked[i][1]; 337 } 278 338 } 279 339 } 280 340 281 void forward( double *realIn, double *realOut, double *imagOut) {341 void forward(const double *R__ realIn, double *R__ realOut, double *R__ imagOut) { 282 342 if (!m_dplanf) initDouble(); 343 const int sz = m_size; 344 fft_double_type *const R__ dbuf = m_dbuf; 283 345 #ifndef FFTW_FLOAT_ONLY 284 if (realIn != m_dbuf)285 #endif 286 for ( unsigned int i = 0; i < m_size; ++i) {287 m_dbuf[i] = realIn[i];346 if (realIn != dbuf) 347 #endif 348 for (int i = 0; i < sz; ++i) { 349 dbuf[i] = realIn[i]; 288 350 } 289 351 fftw_execute(m_dplanf); … … 291 353 } 292 354 293 void forwardPolar( double *realIn, double *magOut, double *phaseOut) {355 void forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut) { 294 356 if (!m_dplanf) initDouble(); 357 fft_double_type *const R__ dbuf = m_dbuf; 358 const int sz = m_size; 359 #ifndef FFTW_FLOAT_ONLY 360 if (realIn != dbuf) 361 #endif 362 for (int i = 0; i < sz; ++i) { 363 dbuf[i] = realIn[i]; 364 } 365 fftw_execute(m_dplanf); 366 const int hs = m_size/2; 367 for (int i = 0; i <= hs; ++i) { 368 magOut[i] = sqrt(m_dpacked[i][0] * m_dpacked[i][0] + 369 m_dpacked[i][1] * m_dpacked[i][1]); 370 } 371 for (int i = 0; i <= hs; ++i) { 372 phaseOut[i] = atan2(m_dpacked[i][1], m_dpacked[i][0]); 373 } 374 } 375 376 void forwardMagnitude(const double *R__ realIn, double *R__ magOut) { 377 if (!m_dplanf) initDouble(); 378 fft_double_type *const R__ dbuf = m_dbuf; 379 const int sz = m_size; 295 380 #ifndef FFTW_FLOAT_ONLY 296 381 if (realIn != m_dbuf) 297 382 #endif 298 for ( unsigned int i = 0; i < m_size; ++i) {299 m_dbuf[i] = realIn[i];383 for (int i = 0; i < sz; ++i) { 384 dbuf[i] = realIn[i]; 300 385 } 301 386 fftw_execute(m_dplanf); 302 for (unsigned int i = 0; i <= m_size/2; ++i) { 387 const int hs = m_size/2; 388 for (int i = 0; i <= hs; ++i) { 303 389 magOut[i] = sqrt(m_dpacked[i][0] * m_dpacked[i][0] + 304 390 m_dpacked[i][1] * m_dpacked[i][1]); 305 391 } 306 for (unsigned int i = 0; i <= m_size/2; ++i) { 307 phaseOut[i] = atan2(m_dpacked[i][1], m_dpacked[i][0]); 308 } 309 } 310 311 void forwardMagnitude(double *realIn, double *magOut) { 312 if (!m_dplanf) initDouble(); 313 #ifndef FFTW_FLOAT_ONLY 314 if (realIn != m_dbuf) 315 #endif 316 for (unsigned int i = 0; i < m_size; ++i) { 317 m_dbuf[i] = realIn[i]; 318 } 319 fftw_execute(m_dplanf); 320 for (unsigned int i = 0; i <= m_size/2; ++i) { 321 magOut[i] = sqrt(m_dpacked[i][0] * m_dpacked[i][0] + 322 m_dpacked[i][1] * m_dpacked[i][1]); 323 } 324 } 325 326 void forward(float *realIn, float *realOut, float *imagOut) { 392 } 393 394 void forward(const float *R__ realIn, float *R__ realOut, float *R__ imagOut) { 327 395 if (!m_fplanf) initFloat(); 396 fft_float_type *const R__ fbuf = m_fbuf; 397 const int sz = m_size; 328 398 #ifndef FFTW_DOUBLE_ONLY 329 if (realIn != m_fbuf)330 #endif 331 for ( unsigned int i = 0; i < m_size; ++i) {332 m_fbuf[i] = realIn[i];399 if (realIn != fbuf) 400 #endif 401 for (int i = 0; i < sz; ++i) { 402 fbuf[i] = realIn[i]; 333 403 } 334 404 fftwf_execute(m_fplanf); … … 336 406 } 337 407 338 void forwardPolar( float *realIn, float *magOut, float *phaseOut) {408 void forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut) { 339 409 if (!m_fplanf) initFloat(); 410 fft_float_type *const R__ fbuf = m_fbuf; 411 const int sz = m_size; 340 412 #ifndef FFTW_DOUBLE_ONLY 341 if (realIn != m_fbuf)342 #endif 343 for ( unsigned int i = 0; i < m_size; ++i) {344 m_fbuf[i] = realIn[i];413 if (realIn != fbuf) 414 #endif 415 for (int i = 0; i < sz; ++i) { 416 fbuf[i] = realIn[i]; 345 417 } 346 418 fftwf_execute(m_fplanf); 347 for (unsigned int i = 0; i <= m_size/2; ++i) { 419 const int hs = m_size/2; 420 for (int i = 0; i <= hs; ++i) { 348 421 magOut[i] = sqrtf(m_fpacked[i][0] * m_fpacked[i][0] + 349 422 m_fpacked[i][1] * m_fpacked[i][1]); 350 423 } 351 for ( unsigned int i = 0; i <= m_size/2; ++i) {352 phaseOut[i] = atan2f(m_fpacked[i][1], m_fpacked[i][0]) ;353 } 354 } 355 356 void forwardMagnitude( float *realIn, float *magOut) {424 for (int i = 0; i <= hs; ++i) { 425 phaseOut[i] = atan2f(m_fpacked[i][1], m_fpacked[i][0]) ; 426 } 427 } 428 429 void forwardMagnitude(const float *R__ realIn, float *R__ magOut) { 357 430 if (!m_fplanf) initFloat(); 431 fft_float_type *const R__ fbuf = m_fbuf; 432 const int sz = m_size; 358 433 #ifndef FFTW_DOUBLE_ONLY 359 if (realIn != m_fbuf)360 #endif 361 for ( unsigned int i = 0; i < m_size; ++i) {362 m_fbuf[i] = realIn[i];434 if (realIn != fbuf) 435 #endif 436 for (int i = 0; i < sz; ++i) { 437 fbuf[i] = realIn[i]; 363 438 } 364 439 fftwf_execute(m_fplanf); 365 for (unsigned int i = 0; i <= m_size/2; ++i) { 440 const int hs = m_size/2; 441 for (int i = 0; i <= hs; ++i) { 366 442 magOut[i] = sqrtf(m_fpacked[i][0] * m_fpacked[i][0] + 367 443 m_fpacked[i][1] * m_fpacked[i][1]); … … 369 445 } 370 446 371 void inverse( double *realIn, double *imagIn, double *realOut) {447 void inverse(const double *R__ realIn, const double *R__ imagIn, double *R__ realOut) { 372 448 if (!m_dplanf) initDouble(); 373 449 packDouble(realIn, imagIn); 374 450 fftw_execute(m_dplani); 451 const int sz = m_size; 452 fft_double_type *const R__ dbuf = m_dbuf; 375 453 #ifndef FFTW_FLOAT_ONLY 376 if (realOut != m_dbuf)377 #endif 378 for ( unsigned int i = 0; i < m_size; ++i) {379 realOut[i] = m_dbuf[i];380 } 381 } 382 383 void inversePolar( double *magIn, double *phaseIn, double *realOut) {454 if (realOut != dbuf) 455 #endif 456 for (int i = 0; i < sz; ++i) { 457 realOut[i] = dbuf[i]; 458 } 459 } 460 461 void inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut) { 384 462 if (!m_dplanf) initDouble(); 385 for (unsigned int i = 0; i <= m_size/2; ++i) { 386 m_dpacked[i][0] = magIn[i] * cos(phaseIn[i]); 387 m_dpacked[i][1] = magIn[i] * sin(phaseIn[i]); 463 const int hs = m_size/2; 464 fftw_complex *const R__ dpacked = m_dpacked; 465 for (int i = 0; i <= hs; ++i) { 466 dpacked[i][0] = magIn[i] * cos(phaseIn[i]); 467 } 468 for (int i = 0; i <= hs; ++i) { 469 dpacked[i][1] = magIn[i] * sin(phaseIn[i]); 388 470 } 389 471 fftw_execute(m_dplani); 472 const int sz = m_size; 473 fft_double_type *const R__ dbuf = m_dbuf; 390 474 #ifndef FFTW_FLOAT_ONLY 391 if (realOut != m_dbuf) 392 #endif 393 for (unsigned int i = 0; i < m_size; ++i) { 394 realOut[i] = m_dbuf[i]; 395 } 396 } 397 398 void inverse(float *realIn, float *imagIn, float *realOut) { 475 if (realOut != dbuf) 476 #endif 477 for (int i = 0; i < sz; ++i) { 478 realOut[i] = dbuf[i]; 479 } 480 } 481 482 void inverseCepstral(const double *R__ magIn, double *R__ cepOut) { 483 if (!m_dplanf) initDouble(); 484 fft_double_type *const R__ dbuf = m_dbuf; 485 fftw_complex *const R__ dpacked = m_dpacked; 486 const int hs = m_size/2; 487 for (int i = 0; i <= hs; ++i) { 488 dpacked[i][0] = log(magIn[i] + 0.000001); 489 } 490 for (int i = 0; i <= hs; ++i) { 491 dpacked[i][1] = 0.0; 492 } 493 fftw_execute(m_dplani); 494 const int sz = m_size; 495 #ifndef FFTW_FLOAT_ONLY 496 if (cepOut != dbuf) 497 #endif 498 for (int i = 0; i < sz; ++i) { 499 cepOut[i] = dbuf[i]; 500 } 501 } 502 503 void inverse(const float *R__ realIn, const float *R__ imagIn, float *R__ realOut) { 399 504 if (!m_fplanf) initFloat(); 400 505 packFloat(realIn, imagIn); 401 506 fftwf_execute(m_fplani); 507 const int sz = m_size; 508 fft_float_type *const R__ fbuf = m_fbuf; 402 509 #ifndef FFTW_DOUBLE_ONLY 403 if (realOut != m_fbuf)404 #endif 405 for ( unsigned int i = 0; i < m_size; ++i) {406 realOut[i] = m_fbuf[i];407 } 408 } 409 410 void inversePolar( float *magIn, float *phaseIn, float *realOut) {510 if (realOut != fbuf) 511 #endif 512 for (int i = 0; i < sz; ++i) { 513 realOut[i] = fbuf[i]; 514 } 515 } 516 517 void inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut) { 411 518 if (!m_fplanf) initFloat(); 412 for (unsigned int i = 0; i <= m_size/2; ++i) { 413 m_fpacked[i][0] = magIn[i] * cosf(phaseIn[i]); 414 m_fpacked[i][1] = magIn[i] * sinf(phaseIn[i]); 519 const int hs = m_size/2; 520 fftwf_complex *const R__ fpacked = m_fpacked; 521 for (int i = 0; i <= hs; ++i) { 522 fpacked[i][0] = magIn[i] * cosf(phaseIn[i]); 523 } 524 for (int i = 0; i <= hs; ++i) { 525 fpacked[i][1] = magIn[i] * sinf(phaseIn[i]); 415 526 } 416 527 fftwf_execute(m_fplani); 528 const int sz = m_size; 529 fft_float_type *const R__ fbuf = m_fbuf; 417 530 #ifndef FFTW_DOUBLE_ONLY 418 if (realOut != m_fbuf) 419 #endif 420 for (unsigned int i = 0; i < m_size; ++i) { 421 realOut[i] = m_fbuf[i]; 531 if (realOut != fbuf) 532 #endif 533 for (int i = 0; i < sz; ++i) { 534 realOut[i] = fbuf[i]; 535 } 536 } 537 538 void inverseCepstral(const float *R__ magIn, float *R__ cepOut) { 539 if (!m_fplanf) initFloat(); 540 const int hs = m_size/2; 541 fftwf_complex *const R__ fpacked = m_fpacked; 542 for (int i = 0; i <= hs; ++i) { 543 fpacked[i][0] = logf(magIn[i] + 0.000001f); 544 } 545 for (int i = 0; i <= hs; ++i) { 546 fpacked[i][1] = 0.f; 547 } 548 fftwf_execute(m_fplani); 549 const int sz = m_size; 550 fft_float_type *const R__ fbuf = m_fbuf; 551 #ifndef FFTW_DOUBLE_ONLY 552 if (cepOut != fbuf) 553 #endif 554 for (int i = 0; i < sz; ++i) { 555 cepOut[i] = fbuf[i]; 422 556 } 423 557 } … … 461 595 double *m_dbuf; 462 596 #endif 463 fftw_complex * m_dpacked;464 unsignedint m_size;465 static unsignedint m_extantf;466 static unsignedint m_extantd;597 fftw_complex * m_dpacked; 598 const int m_size; 599 static int m_extantf; 600 static int m_extantd; 467 601 static Mutex m_extantMutex; 468 602 }; 469 603 470 unsignedint604 int 471 605 D_FFTW::m_extantf = 0; 472 606 473 unsignedint607 int 474 608 D_FFTW::m_extantd = 0; 475 609 … … 477 611 D_FFTW::m_extantMutex; 478 612 613 #endif /* HAVE_FFTW3 */ 614 615 #ifdef USE_KISSFFT 616 617 class D_KISSFFT : public FFTImpl 618 { 619 public: 620 D_KISSFFT(int size) : 621 m_size(size), 622 m_frb(0), 623 m_drb(0), 624 m_fplanf(0), 625 m_fplani(0) 626 { 627 #ifdef FIXED_POINT 628 #error KISSFFT is not configured for float values 629 #endif 630 if (sizeof(kiss_fft_scalar) != sizeof(float)) { 631 std::cerr << "ERROR: KISSFFT is not configured for float values" 632 << std::endl; 633 } 634 635 m_fbuf = new kiss_fft_scalar[m_size + 2]; 636 m_fpacked = new kiss_fft_cpx[m_size + 2]; 637 m_fplanf = kiss_fftr_alloc(m_size, 0, NULL, NULL); 638 m_fplani = kiss_fftr_alloc(m_size, 1, NULL, NULL); 639 } 640 641 ~D_KISSFFT() { 642 kiss_fftr_free(m_fplanf); 643 kiss_fftr_free(m_fplani); 644 kiss_fft_cleanup(); 645 646 delete[] m_fbuf; 647 delete[] m_fpacked; 648 649 if (m_frb) delete[] m_frb; 650 if (m_drb) delete[] m_drb; 651 } 652 653 void initFloat() { } 654 void initDouble() { } 655 656 void packFloat(const float *R__ re, const float *R__ im) { 657 const int hs = m_size/2; 658 for (int i = 0; i <= hs; ++i) { 659 m_fpacked[i].r = re[i]; 660 m_fpacked[i].i = im[i]; 661 } 662 } 663 664 void unpackFloat(float *R__ re, float *R__ im) { 665 const int hs = m_size/2; 666 for (int i = 0; i <= hs; ++i) { 667 re[i] = m_fpacked[i].r; 668 im[i] = m_fpacked[i].i; 669 } 670 } 671 672 void packDouble(const double *R__ re, const double *R__ im) { 673 const int hs = m_size/2; 674 for (int i = 0; i <= hs; ++i) { 675 m_fpacked[i].r = float(re[i]); 676 m_fpacked[i].i = float(im[i]); 677 } 678 } 679 680 void unpackDouble(double *R__ re, double *R__ im) { 681 const int hs = m_size/2; 682 for (int i = 0; i <= hs; ++i) { 683 re[i] = double(m_fpacked[i].r); 684 im[i] = double(m_fpacked[i].i); 685 } 686 } 687 688 void forward(const double *R__ realIn, double *R__ realOut, double *R__ imagOut) { 689 690 for (int i = 0; i < m_size; ++i) { 691 m_fbuf[i] = float(realIn[i]); 692 } 693 694 kiss_fftr(m_fplanf, m_fbuf, m_fpacked); 695 unpackDouble(realOut, imagOut); 696 } 697 698 void forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut) { 699 700 for (int i = 0; i < m_size; ++i) { 701 m_fbuf[i] = float(realIn[i]); 702 } 703 704 kiss_fftr(m_fplanf, m_fbuf, m_fpacked); 705 706 const int hs = m_size/2; 707 708 for (int i = 0; i <= hs; ++i) { 709 magOut[i] = sqrt(double(m_fpacked[i].r) * double(m_fpacked[i].r) + 710 double(m_fpacked[i].i) * double(m_fpacked[i].i)); 711 } 712 713 for (int i = 0; i <= hs; ++i) { 714 phaseOut[i] = atan2(double(m_fpacked[i].i), double(m_fpacked[i].r)); 715 } 716 } 717 718 void forwardMagnitude(const double *R__ realIn, double *R__ magOut) { 719 720 for (int i = 0; i < m_size; ++i) { 721 m_fbuf[i] = float(realIn[i]); 722 } 723 724 kiss_fftr(m_fplanf, m_fbuf, m_fpacked); 725 726 const int hs = m_size/2; 727 728 for (int i = 0; i <= hs; ++i) { 729 magOut[i] = sqrt(double(m_fpacked[i].r) * double(m_fpacked[i].r) + 730 double(m_fpacked[i].i) * double(m_fpacked[i].i)); 731 } 732 } 733 734 void forward(const float *R__ realIn, float *R__ realOut, float *R__ imagOut) { 735 736 kiss_fftr(m_fplanf, realIn, m_fpacked); 737 unpackFloat(realOut, imagOut); 738 } 739 740 void forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut) { 741 742 kiss_fftr(m_fplanf, realIn, m_fpacked); 743 744 const int hs = m_size/2; 745 746 for (int i = 0; i <= hs; ++i) { 747 magOut[i] = sqrtf(m_fpacked[i].r * m_fpacked[i].r + 748 m_fpacked[i].i * m_fpacked[i].i); 749 } 750 751 for (int i = 0; i <= hs; ++i) { 752 phaseOut[i] = atan2f(m_fpacked[i].i, m_fpacked[i].r); 753 } 754 } 755 756 void forwardMagnitude(const float *R__ realIn, float *R__ magOut) { 757 758 kiss_fftr(m_fplanf, realIn, m_fpacked); 759 760 const int hs = m_size/2; 761 762 for (int i = 0; i <= hs; ++i) { 763 magOut[i] = sqrtf(m_fpacked[i].r * m_fpacked[i].r + 764 m_fpacked[i].i * m_fpacked[i].i); 765 } 766 } 767 768 void inverse(const double *R__ realIn, const double *R__ imagIn, double *R__ realOut) { 769 770 packDouble(realIn, imagIn); 771 772 kiss_fftri(m_fplani, m_fpacked, m_fbuf); 773 774 for (int i = 0; i < m_size; ++i) { 775 realOut[i] = m_fbuf[i]; 776 } 777 } 778 779 void inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut) { 780 781 const int hs = m_size/2; 782 783 for (int i = 0; i <= hs; ++i) { 784 m_fpacked[i].r = float(magIn[i] * cos(phaseIn[i])); 785 m_fpacked[i].i = float(magIn[i] * sin(phaseIn[i])); 786 } 787 788 kiss_fftri(m_fplani, m_fpacked, m_fbuf); 789 790 for (int i = 0; i < m_size; ++i) { 791 realOut[i] = m_fbuf[i]; 792 } 793 } 794 795 void inverseCepstral(const double *R__ magIn, double *R__ cepOut) { 796 797 const int hs = m_size/2; 798 799 for (int i = 0; i <= hs; ++i) { 800 m_fpacked[i].r = float(log(magIn[i] + 0.000001)); 801 m_fpacked[i].i = 0.0f; 802 } 803 804 kiss_fftri(m_fplani, m_fpacked, m_fbuf); 805 806 for (int i = 0; i < m_size; ++i) { 807 cepOut[i] = m_fbuf[i]; 808 } 809 } 810 811 void inverse(const float *R__ realIn, const float *R__ imagIn, float *R__ realOut) { 812 813 packFloat(realIn, imagIn); 814 kiss_fftri(m_fplani, m_fpacked, realOut); 815 } 816 817 void inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut) { 818 819 const int hs = m_size/2; 820 821 for (int i = 0; i <= hs; ++i) { 822 m_fpacked[i].r = magIn[i] * cosf(phaseIn[i]); 823 m_fpacked[i].i = magIn[i] * sinf(phaseIn[i]); 824 } 825 826 kiss_fftri(m_fplani, m_fpacked, realOut); 827 } 828 829 void inverseCepstral(const float *R__ magIn, float *R__ cepOut) { 830 831 const int hs = m_size/2; 832 833 for (int i = 0; i <= hs; ++i) { 834 m_fpacked[i].r = logf(magIn[i] + 0.000001f); 835 m_fpacked[i].i = 0.0f; 836 } 837 838 kiss_fftri(m_fplani, m_fpacked, cepOut); 839 } 840 841 float *getFloatTimeBuffer() { 842 if (!m_frb) m_frb = new float[m_size]; 843 return m_frb; 844 } 845 846 double *getDoubleTimeBuffer() { 847 if (!m_drb) m_drb = new double[m_size]; 848 return m_drb; 849 } 850 851 private: 852 const int m_size; 853 float* m_frb; 854 double* m_drb; 855 kiss_fftr_cfg m_fplanf; 856 kiss_fftr_cfg m_fplani; 857 kiss_fft_scalar *m_fbuf; 858 kiss_fft_cpx *m_fpacked; 859 }; 860 861 #endif /* USE_KISSFFT */ 862 863 #ifdef USE_BUILTIN_FFT 479 864 480 865 class D_Cross : public FFTImpl 481 866 { 482 867 public: 483 D_Cross( unsignedint size) : m_size(size), m_table(0), m_frb(0), m_drb(0) {868 D_Cross(int size) : m_size(size), m_table(0), m_frb(0), m_drb(0) { 484 869 485 870 m_a = new double[size]; … … 490 875 m_table = new int[m_size]; 491 876 492 unsignedint bits;493 unsignedint i, j, k, m;877 int bits; 878 int i, j, k, m; 494 879 495 880 for (i = 0; ; ++i) { … … 526 911 void initDouble() { } 527 912 528 void forward( double *realIn, double *realOut, double *imagOut) {913 void forward(const double *R__ realIn, double *R__ realOut, double *R__ imagOut) { 529 914 basefft(false, realIn, 0, m_c, m_d); 530 for (size_t i = 0; i <= m_size/2; ++i) realOut[i] = m_c[i]; 531 for (size_t i = 0; i <= m_size/2; ++i) imagOut[i] = m_d[i]; 532 } 533 534 void forwardPolar(double *realIn, double *magOut, double *phaseOut) { 915 const int hs = m_size/2; 916 for (int i = 0; i <= hs; ++i) realOut[i] = m_c[i]; 917 if (imagOut) { 918 for (int i = 0; i <= hs; ++i) imagOut[i] = m_d[i]; 919 } 920 } 921 922 void forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut) { 535 923 basefft(false, realIn, 0, m_c, m_d); 536 for (unsigned int i = 0; i <= m_size/2; ++i) { 924 const int hs = m_size/2; 925 for (int i = 0; i <= hs; ++i) { 537 926 magOut[i] = sqrt(m_c[i] * m_c[i] + m_d[i] * m_d[i]); 538 927 phaseOut[i] = atan2(m_d[i], m_c[i]) ; … … 540 929 } 541 930 542 void forwardMagnitude( double *realIn, double *magOut) {931 void forwardMagnitude(const double *R__ realIn, double *R__ magOut) { 543 932 basefft(false, realIn, 0, m_c, m_d); 544 for (unsigned int i = 0; i <= m_size/2; ++i) { 933 const int hs = m_size/2; 934 for (int i = 0; i <= hs; ++i) { 545 935 magOut[i] = sqrt(m_c[i] * m_c[i] + m_d[i] * m_d[i]); 546 936 } 547 937 } 548 938 549 void forward( float *realIn, float *realOut, float *imagOut) {550 for ( size_t i = 0; i < m_size; ++i) m_a[i] = realIn[i];939 void forward(const float *R__ realIn, float *R__ realOut, float *R__ imagOut) { 940 for (int i = 0; i < m_size; ++i) m_a[i] = realIn[i]; 551 941 basefft(false, m_a, 0, m_c, m_d); 552 for (size_t i = 0; i <= m_size/2; ++i) realOut[i] = m_c[i]; 553 for (size_t i = 0; i <= m_size/2; ++i) imagOut[i] = m_d[i]; 554 } 555 556 void forwardPolar(float *realIn, float *magOut, float *phaseOut) { 557 for (size_t i = 0; i < m_size; ++i) m_a[i] = realIn[i]; 942 const int hs = m_size/2; 943 for (int i = 0; i <= hs; ++i) realOut[i] = m_c[i]; 944 if (imagOut) { 945 for (int i = 0; i <= hs; ++i) imagOut[i] = m_d[i]; 946 } 947 } 948 949 void forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut) { 950 for (int i = 0; i < m_size; ++i) m_a[i] = realIn[i]; 558 951 basefft(false, m_a, 0, m_c, m_d); 559 for (unsigned int i = 0; i <= m_size/2; ++i) { 952 const int hs = m_size/2; 953 for (int i = 0; i <= hs; ++i) { 560 954 magOut[i] = sqrt(m_c[i] * m_c[i] + m_d[i] * m_d[i]); 561 955 phaseOut[i] = atan2(m_d[i], m_c[i]) ; … … 563 957 } 564 958 565 void forwardMagnitude( float *realIn, float *magOut) {566 for ( size_t i = 0; i < m_size; ++i) m_a[i] = realIn[i];959 void forwardMagnitude(const float *R__ realIn, float *R__ magOut) { 960 for (int i = 0; i < m_size; ++i) m_a[i] = realIn[i]; 567 961 basefft(false, m_a, 0, m_c, m_d); 568 for (unsigned int i = 0; i <= m_size/2; ++i) { 962 const int hs = m_size/2; 963 for (int i = 0; i <= hs; ++i) { 569 964 magOut[i] = sqrt(m_c[i] * m_c[i] + m_d[i] * m_d[i]); 570 965 } 571 966 } 572 967 573 void inverse(double *realIn, double *imagIn, double *realOut) { 574 for (unsigned int i = 0; i <= m_size/2; ++i) { 968 void inverse(const double *R__ realIn, const double *R__ imagIn, double *R__ realOut) { 969 const int hs = m_size/2; 970 for (int i = 0; i <= hs; ++i) { 575 971 double real = realIn[i]; 576 972 double imag = imagIn[i]; … … 585 981 } 586 982 587 void inversePolar(double *magIn, double *phaseIn, double *realOut) { 588 for (unsigned int i = 0; i <= m_size/2; ++i) { 983 void inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut) { 984 const int hs = m_size/2; 985 for (int i = 0; i <= hs; ++i) { 589 986 double real = magIn[i] * cos(phaseIn[i]); 590 987 double imag = magIn[i] * sin(phaseIn[i]); … … 599 996 } 600 997 601 void inverse(float *realIn, float *imagIn, float *realOut) { 602 for (unsigned int i = 0; i <= m_size/2; ++i) { 998 void inverseCepstral(const double *R__ magIn, double *R__ cepOut) { 999 const int hs = m_size/2; 1000 for (int i = 0; i <= hs; ++i) { 1001 double real = log(magIn[i] + 0.000001); 1002 m_a[i] = real; 1003 m_b[i] = 0.0; 1004 if (i > 0) { 1005 m_a[m_size-i] = real; 1006 m_b[m_size-i] = 0.0; 1007 } 1008 } 1009 basefft(true, m_a, m_b, cepOut, m_d); 1010 } 1011 1012 void inverse(const float *R__ realIn, const float *R__ imagIn, float *R__ realOut) { 1013 const int hs = m_size/2; 1014 for (int i = 0; i <= hs; ++i) { 603 1015 float real = realIn[i]; 604 1016 float imag = imagIn[i]; … … 611 1023 } 612 1024 basefft(true, m_a, m_b, m_c, m_d); 613 for (unsigned int i = 0; i < m_size; ++i) realOut[i] = m_c[i]; 614 } 615 616 void inversePolar(float *magIn, float *phaseIn, float *realOut) { 617 for (unsigned int i = 0; i <= m_size/2; ++i) { 1025 for (int i = 0; i < m_size; ++i) realOut[i] = m_c[i]; 1026 } 1027 1028 void inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut) { 1029 const int hs = m_size/2; 1030 for (int i = 0; i <= hs; ++i) { 618 1031 float real = magIn[i] * cosf(phaseIn[i]); 619 1032 float imag = magIn[i] * sinf(phaseIn[i]); … … 626 1039 } 627 1040 basefft(true, m_a, m_b, m_c, m_d); 628 for (unsigned int i = 0; i < m_size; ++i) realOut[i] = m_c[i]; 1041 for (int i = 0; i < m_size; ++i) realOut[i] = m_c[i]; 1042 } 1043 1044 void inverseCepstral(const float *R__ magIn, float *R__ cepOut) { 1045 const int hs = m_size/2; 1046 for (int i = 0; i <= hs; ++i) { 1047 float real = logf(magIn[i] + 0.000001); 1048 m_a[i] = real; 1049 m_b[i] = 0.0; 1050 if (i > 0) { 1051 m_a[m_size-i] = real; 1052 m_b[m_size-i] = 0.0; 1053 } 1054 } 1055 basefft(true, m_a, m_b, m_c, m_d); 1056 for (int i = 0; i < m_size; ++i) cepOut[i] = m_c[i]; 629 1057 } 630 1058 … … 640 1068 641 1069 private: 642 unsignedint m_size;1070 const int m_size; 643 1071 int *m_table; 644 1072 float *m_frb; … … 648 1076 double *m_c; 649 1077 double *m_d; 650 void basefft(bool inverse, double *ri, double *ii, double *ro, double *io);1078 void basefft(bool inverse, const double *R__ ri, const double *R__ ii, double *R__ ro, double *R__ io); 651 1079 }; 652 1080 653 1081 void 654 D_Cross::basefft(bool inverse, double *ri, double *ii, double *ro, double *io)1082 D_Cross::basefft(bool inverse, const double *R__ ri, const double *R__ ii, double *R__ ro, double *R__ io) 655 1083 { 656 1084 if (!ri || !ro || !io) return; 657 1085 658 unsignedint i, j, k, m;659 unsignedint blockSize, blockEnd;1086 int i, j, k, m; 1087 int blockSize, blockEnd; 660 1088 661 1089 double tr, ti; … … 664 1092 if (inverse) angle = -angle; 665 1093 666 const unsignedint n = m_size;1094 const int n = m_size; 667 1095 668 1096 if (ii) { 669 1097 for (i = 0; i < n; ++i) { 670 1098 ro[m_table[i]] = ri[i]; 1099 } 1100 for (i = 0; i < n; ++i) { 671 1101 io[m_table[i]] = ii[i]; 672 1102 } … … 674 1104 for (i = 0; i < n; ++i) { 675 1105 ro[m_table[i]] = ri[i]; 1106 } 1107 for (i = 0; i < n; ++i) { 676 1108 io[m_table[i]] = 0.0; 677 1109 } … … 737 1169 } 738 1170 1171 #endif /* USE_BUILTIN_FFT */ 1172 1173 } /* end namespace FFTs */ 1174 739 1175 int 740 1176 FFT::m_method = -1; 741 1177 742 FFT::FFT(unsigned int size) 743 { 744 if (size < 2) throw InvalidSize; 745 if (size & (size-1)) throw InvalidSize; 1178 FFT::FFT(int size, int debugLevel) 1179 { 1180 if ((size < 2) || 1181 (size & (size-1))) { 1182 std::cerr << "FFT::FFT(" << size << "): power-of-two sizes only supported, minimum size 2" << std::endl; 1183 throw InvalidSize; 1184 } 746 1185 747 1186 if (m_method == -1) { 1187 m_method = 3; 1188 #ifdef USE_KISSFFT 1189 m_method = 2; 1190 #endif 1191 #ifdef HAVE_FFTW3 748 1192 m_method = 1; 1193 #endif 749 1194 } 750 1195 … … 752 1197 753 1198 case 0: 754 d = new D_Cross(size); 1199 std::cerr << "FFT::FFT(" << size << "): WARNING: Selected implemention not available" << std::endl; 1200 #ifdef USE_BUILTIN_FFT 1201 d = new FFTs::D_Cross(size); 1202 #else 1203 std::cerr << "FFT::FFT(" << size << "): ERROR: Fallback implementation not available!" << std::endl; 1204 abort(); 1205 #endif 755 1206 break; 756 1207 757 1208 case 1: 758 // std::cerr << "FFT::FFT(" << size << "): using FFTW3 implementation" 759 // << std::endl; 760 d = new D_FFTW(size); 1209 #ifdef HAVE_FFTW3 1210 if (debugLevel > 0) { 1211 std::cerr << "FFT::FFT(" << size << "): using FFTW3 implementation" 1212 << std::endl; 1213 } 1214 d = new FFTs::D_FFTW(size); 1215 #else 1216 std::cerr << "FFT::FFT(" << size << "): WARNING: Selected implemention not available" << std::endl; 1217 #ifdef USE_BUILTIN_FFT 1218 d = new FFTs::D_Cross(size); 1219 #else 1220 std::cerr << "FFT::FFT(" << size << "): ERROR: Fallback implementation not available!" << std::endl; 1221 abort(); 1222 #endif 1223 #endif 761 1224 break; 762 1225 1226 case 2: 1227 #ifdef USE_KISSFFT 1228 if (debugLevel > 0) { 1229 std::cerr << "FFT::FFT(" << size << "): using KISSFFT implementation" 1230 << std::endl; 1231 } 1232 d = new FFTs::D_KISSFFT(size); 1233 #else 1234 std::cerr << "FFT::FFT(" << size << "): WARNING: Selected implemention not available" << std::endl; 1235 #ifdef USE_BUILTIN_FFT 1236 d = new FFTs::D_Cross(size); 1237 #else 1238 std::cerr << "FFT::FFT(" << size << "): ERROR: Fallback implementation not available!" << std::endl; 1239 abort(); 1240 #endif 1241 #endif 1242 break; 1243 763 1244 default: 764 std::cerr << "FFT::FFT(" << size << "): WARNING: using slow built-in implementation" 765 << std::endl; 766 d = new D_Cross(size); 1245 #ifdef USE_BUILTIN_FFT 1246 std::cerr << "FFT::FFT(" << size << "): WARNING: using slow built-in implementation" << std::endl; 1247 d = new FFTs::D_Cross(size); 1248 #else 1249 std::cerr << "FFT::FFT(" << size << "): ERROR: Fallback implementation not available!" << std::endl; 1250 abort(); 1251 #endif 767 1252 break; 768 1253 } … … 775 1260 776 1261 void 777 FFT::forward( double *realIn, double *realOut, double *imagOut)1262 FFT::forward(const double *R__ realIn, double *R__ realOut, double *R__ imagOut) 778 1263 { 779 1264 d->forward(realIn, realOut, imagOut); … … 781 1266 782 1267 void 783 FFT::forwardPolar( double *realIn, double *magOut, double *phaseOut)1268 FFT::forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut) 784 1269 { 785 1270 d->forwardPolar(realIn, magOut, phaseOut); … … 787 1272 788 1273 void 789 FFT::forwardMagnitude( double *realIn, double *magOut)1274 FFT::forwardMagnitude(const double *R__ realIn, double *R__ magOut) 790 1275 { 791 1276 d->forwardMagnitude(realIn, magOut); … … 793 1278 794 1279 void 795 FFT::forward( float *realIn, float *realOut, float *imagOut)1280 FFT::forward(const float *R__ realIn, float *R__ realOut, float *R__ imagOut) 796 1281 { 797 1282 d->forward(realIn, realOut, imagOut); … … 799 1284 800 1285 void 801 FFT::forwardPolar( float *realIn, float *magOut, float *phaseOut)1286 FFT::forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut) 802 1287 { 803 1288 d->forwardPolar(realIn, magOut, phaseOut); … … 805 1290 806 1291 void 807 FFT::forwardMagnitude( float *realIn, float *magOut)1292 FFT::forwardMagnitude(const float *R__ realIn, float *R__ magOut) 808 1293 { 809 1294 d->forwardMagnitude(realIn, magOut); … … 811 1296 812 1297 void 813 FFT::inverse( double *realIn, double *imagIn, double *realOut)1298 FFT::inverse(const double *R__ realIn, const double *R__ imagIn, double *R__ realOut) 814 1299 { 815 1300 d->inverse(realIn, imagIn, realOut); … … 817 1302 818 1303 void 819 FFT::inversePolar( double *magIn, double *phaseIn, double *realOut)1304 FFT::inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut) 820 1305 { 821 1306 d->inversePolar(magIn, phaseIn, realOut); … … 823 1308 824 1309 void 825 FFT::inverse(float *realIn, float *imagIn, float *realOut) 1310 FFT::inverseCepstral(const double *R__ magIn, double *R__ cepOut) 1311 { 1312 d->inverseCepstral(magIn, cepOut); 1313 } 1314 1315 void 1316 FFT::inverse(const float *R__ realIn, const float *R__ imagIn, float *R__ realOut) 826 1317 { 827 1318 d->inverse(realIn, imagIn, realOut); … … 829 1320 830 1321 void 831 FFT::inversePolar( float *magIn, float *phaseIn, float *realOut)1322 FFT::inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut) 832 1323 { 833 1324 d->inversePolar(magIn, phaseIn, realOut); 1325 } 1326 1327 void 1328 FFT::inverseCepstral(const float *R__ magIn, float *R__ cepOut) 1329 { 1330 d->inverseCepstral(magIn, cepOut); 834 1331 } 835 1332 -
trunk/rubberband/src/FFT.h
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 15 15 #ifndef _RUBBERBAND_FFT_H_ 16 16 #define _RUBBERBAND_FFT_H_ 17 18 #include "sysutils.h" 17 19 18 20 namespace RubberBand { … … 37 39 enum Exception { InvalidSize }; 38 40 39 FFT( unsigned int size); // may throw InvalidSize41 FFT(int size, int debugLevel = 0); // may throw InvalidSize 40 42 ~FFT(); 41 43 42 void forward( double *realIn, double *realOut, double *imagOut);43 void forwardPolar( double *realIn, double *magOut, double *phaseOut);44 void forwardMagnitude( double *realIn, double *magOut);44 void forward(const double *R__ realIn, double *R__ realOut, double *R__ imagOut); 45 void forwardPolar(const double *R__ realIn, double *R__ magOut, double *R__ phaseOut); 46 void forwardMagnitude(const double *R__ realIn, double *R__ magOut); 45 47 46 void forward( float *realIn, float *realOut, float *imagOut);47 void forwardPolar( float *realIn, float *magOut, float *phaseOut);48 void forwardMagnitude( float *realIn, float *magOut);48 void forward(const float *R__ realIn, float *R__ realOut, float *R__ imagOut); 49 void forwardPolar(const float *R__ realIn, float *R__ magOut, float *R__ phaseOut); 50 void forwardMagnitude(const float *R__ realIn, float *R__ magOut); 49 51 50 void inverse(double *realIn, double *imagIn, double *realOut); 51 void inversePolar(double *magIn, double *phaseIn, double *realOut); 52 void inverse(const double *R__ realIn, const double *R__ imagIn, double *R__ realOut); 53 void inversePolar(const double *R__ magIn, const double *R__ phaseIn, double *R__ realOut); 54 void inverseCepstral(const double *R__ magIn, double *R__ cepOut); 52 55 53 void inverse(float *realIn, float *imagIn, float *realOut); 54 void inversePolar(float *magIn, float *phaseIn, float *realOut); 56 void inverse(const float *R__ realIn, const float *R__ imagIn, float *R__ realOut); 57 void inversePolar(const float *R__ magIn, const float *R__ phaseIn, float *R__ realOut); 58 void inverseCepstral(const float *R__ magIn, float *R__ cepOut); 55 59 56 60 // Calling one or both of these is optional -- if neither is -
trunk/rubberband/src/HighFrequencyAudioCurve.cpp
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 39 39 40 40 float 41 HighFrequencyAudioCurve::process( float *mag, size_t increment)41 HighFrequencyAudioCurve::process(const float *R__ mag, size_t increment) 42 42 { 43 43 float result = 0.0; 44 44 45 for (size_t n = 0; n <= m_windowSize / 2; ++n) { 46 result += mag[n] * n; 45 const int sz = m_windowSize / 2; 46 47 for (int n = 0; n <= sz; ++n) { 48 result = result + mag[n] * n; 47 49 } 48 50 -
trunk/rubberband/src/HighFrequencyAudioCurve.h
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 31 31 virtual void setWindowSize(size_t newSize); 32 32 33 virtual float process( float *mag, size_t increment);33 virtual float process(const float *R__ mag, size_t increment); 34 34 virtual void reset(); 35 35 }; -
trunk/rubberband/src/Makefile.am
r234 r267 1 AM_CPPFLAGS= -D FFTW_DOUBLE_ONLY $(SRC_CFLAGS) $(FFTW_CFLAGS) $(OPTFLAGS) -I$(srcdir)/../include1 AM_CPPFLAGS= -DHAVE_FFTW3 -DFFTW_DOUBLE_ONLY $(SRC_CFLAGS) $(FFTW_CFLAGS) $(OPTFLAGS) -I$(srcdir)/../include 2 2 3 3 … … 9 9 10 10 librubberband_la_SOURCES = \ 11 AudioCurve.cpp \ 11 12 AudioCurve.h \ 13 ConstantAudioCurve.cpp \ 12 14 ConstantAudioCurve.h \ 15 FFT.cpp \ 13 16 FFT.h \ 17 HighFrequencyAudioCurve.cpp \ 14 18 HighFrequencyAudioCurve.h \ 19 PercussiveAudioCurve.cpp \ 15 20 PercussiveAudioCurve.h \ 21 HighFrequencyAudioCurve.h \ 22 Profiler.cpp \ 23 Profiler.h \ 24 Resampler.cpp \ 16 25 Resampler.h \ 17 26 RingBuffer.h \ 27 rubberband-c.cpp \ 28 RubberBandStretcher.cpp \ 18 29 Scavenger.h \ 30 SilentAudioCurve.cpp \ 31 SilentAudioCurve.h \ 32 SpectralDifferenceAudioCurve.cpp \ 19 33 SpectralDifferenceAudioCurve.h \ 34 StretchCalculator.cpp \ 20 35 StretchCalculator.h \ 36 StretcherChannelData.h \ 37 StretcherImpl.cpp \ 21 38 StretcherImpl.h \ 22 StretcherChannelData.h \23 Thread.h \24 Window.h \25 sysutils.h \26 RubberBandStretcher.cpp \27 ConstantAudioCurve.cpp \28 HighFrequencyAudioCurve.cpp \29 PercussiveAudioCurve.cpp \30 AudioCurve.cpp \31 Resampler.cpp \32 SpectralDifferenceAudioCurve.cpp \33 StretchCalculator.cpp \34 StretcherImpl.cpp \35 39 StretcherProcess.cpp \ 36 40 StretcherChannelData.cpp \ 37 FFT.cpp \38 41 Thread.cpp \ 39 sysutils.cpp 42 Thread.h \ 43 Window.cpp \ 44 Window.h \ 45 sysutils.cpp \ 46 sysutils.h 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 -
trunk/rubberband/src/Makefile.in
r257 r267 51 51 LTLIBRARIES = $(lib_LTLIBRARIES) 52 52 librubberband_la_LIBADD = 53 am_librubberband_la_OBJECTS = RubberBandStretcher.lo \ 54 ConstantAudioCurve.lo HighFrequencyAudioCurve.lo \ 55 PercussiveAudioCurve.lo AudioCurve.lo Resampler.lo \ 53 am_librubberband_la_OBJECTS = AudioCurve.lo ConstantAudioCurve.lo \ 54 FFT.lo HighFrequencyAudioCurve.lo PercussiveAudioCurve.lo \ 55 Profiler.lo Resampler.lo rubberband-c.lo \ 56 RubberBandStretcher.lo SilentAudioCurve.lo \ 56 57 SpectralDifferenceAudioCurve.lo StretchCalculator.lo \ 57 58 StretcherImpl.lo StretcherProcess.lo StretcherChannelData.lo \ 58 FFT.lo Thread.lo sysutils.lo59 Thread.lo Window.lo sysutils.lo 59 60 librubberband_la_OBJECTS = $(am_librubberband_la_OBJECTS) 60 61 librubberband_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ … … 200 201 top_builddir = @top_builddir@ 201 202 top_srcdir = @top_srcdir@ 202 AM_CPPFLAGS = -D FFTW_DOUBLE_ONLY $(SRC_CFLAGS) $(FFTW_CFLAGS) $(OPTFLAGS) -I$(srcdir)/../include203 AM_CPPFLAGS = -DHAVE_FFTW3 -DFFTW_DOUBLE_ONLY $(SRC_CFLAGS) $(FFTW_CFLAGS) $(OPTFLAGS) -I$(srcdir)/../include 203 204 lib_LTLIBRARIES = librubberband.la 204 205 librubberband_la_LDFLAGS = -lpthread 205 206 librubberband_la_SOURCES = \ 207 AudioCurve.cpp \ 206 208 AudioCurve.h \ 209 ConstantAudioCurve.cpp \ 207 210 ConstantAudioCurve.h \ 211 FFT.cpp \ 208 212 FFT.h \ 213 HighFrequencyAudioCurve.cpp \ 209 214 HighFrequencyAudioCurve.h \ 215 PercussiveAudioCurve.cpp \ 210 216 PercussiveAudioCurve.h \ 217 HighFrequencyAudioCurve.h \ 218 Profiler.cpp \ 219 Profiler.h \ 220 Resampler.cpp \ 211 221 Resampler.h \ 212 222 RingBuffer.h \ 223 rubberband-c.cpp \ 224 RubberBandStretcher.cpp \ 213 225 Scavenger.h \ 226 SilentAudioCurve.cpp \ 227 SilentAudioCurve.h \ 228 SpectralDifferenceAudioCurve.cpp \ 214 229 SpectralDifferenceAudioCurve.h \ 230 StretchCalculator.cpp \ 215 231 StretchCalculator.h \ 232 StretcherChannelData.h \ 233 StretcherImpl.cpp \ 216 234 StretcherImpl.h \ 217 StretcherChannelData.h \218 Thread.h \219 Window.h \220 sysutils.h \221 RubberBandStretcher.cpp \222 ConstantAudioCurve.cpp \223 HighFrequencyAudioCurve.cpp \224 PercussiveAudioCurve.cpp \225 AudioCurve.cpp \226 Resampler.cpp \227 SpectralDifferenceAudioCurve.cpp \228 StretchCalculator.cpp \229 StretcherImpl.cpp \230 235 StretcherProcess.cpp \ 231 236 StretcherChannelData.cpp \ 232 FFT.cpp \233 237 Thread.cpp \ 234 sysutils.cpp 238 Thread.h \ 239 Window.cpp \ 240 Window.h \ 241 sysutils.cpp \ 242 sysutils.h 235 243 236 244 all: all-am … … 308 316 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/HighFrequencyAudioCurve.Plo@am__quote@ 309 317 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PercussiveAudioCurve.Plo@am__quote@ 318 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Profiler.Plo@am__quote@ 310 319 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Resampler.Plo@am__quote@ 311 320 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RubberBandStretcher.Plo@am__quote@ 321 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SilentAudioCurve.Plo@am__quote@ 312 322 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SpectralDifferenceAudioCurve.Plo@am__quote@ 313 323 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StretchCalculator.Plo@am__quote@ … … 316 326 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StretcherProcess.Plo@am__quote@ 317 327 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Thread.Plo@am__quote@ 328 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Window.Plo@am__quote@ 329 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rubberband-c.Plo@am__quote@ 318 330 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sysutils.Plo@am__quote@ 319 331 -
trunk/rubberband/src/PercussiveAudioCurve.cpp
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 15 15 #include "PercussiveAudioCurve.h" 16 16 17 #include "Profiler.h" 18 17 19 #include <cmath> 20 18 21 19 22 namespace RubberBand … … 23 26 AudioCurve(sampleRate, windowSize) 24 27 { 25 m_prevMag = new double[m_windowSize/2 + 1];28 m_prevMag = new float[m_windowSize/2 + 1]; 26 29 27 30 for (size_t i = 0; i <= m_windowSize/2; ++i) { … … 46 49 PercussiveAudioCurve::setWindowSize(size_t newSize) 47 50 { 51 m_windowSize = newSize; 52 48 53 delete[] m_prevMag; 49 m_windowSize = newSize; 50 51 m_prevMag = new double[m_windowSize/2 + 1]; 54 m_prevMag = new float[m_windowSize/2 + 1]; 52 55 53 56 reset(); … … 55 58 56 59 float 57 PercussiveAudioCurve::process( float *mag, size_t increment)60 PercussiveAudioCurve::process(const float *R__ mag, size_t increment) 58 61 { 59 static float threshold = pow (10, 0.3);60 static float zeroThresh = pow (10, -16);62 static float threshold = powf(10.f, 0.15f); // 3dB rise in square of magnitude 63 static float zeroThresh = powf(10.f, -8); 61 64 62 65 size_t count = 0; 63 66 size_t nonZeroCount = 0; 64 67 65 for (size_t n = 1; n <= m_windowSize / 2; ++n) { 66 float sqrmag = mag[n] * mag[n]; 67 bool above = ((sqrmag / m_prevMag[n]) >= threshold); 68 const int sz = m_windowSize / 2; 69 70 for (int n = 1; n <= sz; ++n) { 71 bool above = ((mag[n] / m_prevMag[n]) >= threshold); 68 72 if (above) ++count; 69 if (sqrmag > zeroThresh) ++nonZeroCount; 70 m_prevMag[n] = sqrmag; 73 if (mag[n] > zeroThresh) ++nonZeroCount; 74 } 75 76 for (int n = 1; n <= sz; ++n) { 77 m_prevMag[n] = mag[n]; 78 } 79 80 if (nonZeroCount == 0) return 0; 81 else return float(count) / float(nonZeroCount); 82 } 83 84 float 85 PercussiveAudioCurve::process(const double *R__ mag, size_t increment) 86 { 87 Profiler profiler("PercussiveAudioCurve::process"); 88 89 static double threshold = pow(10.0, 0.15); // 3dB rise in square of magnitude 90 static double zeroThresh = pow(10.0, -8); 91 92 size_t count = 0; 93 size_t nonZeroCount = 0; 94 95 const int sz = m_windowSize / 2; 96 97 for (int n = 1; n <= sz; ++n) { 98 bool above = ((mag[n] / m_prevMag[n]) >= threshold); 99 if (above) ++count; 100 if (mag[n] > zeroThresh) ++nonZeroCount; 101 } 102 103 for (int n = 1; n <= sz; ++n) { 104 m_prevMag[n] = mag[n]; 71 105 } 72 106 -
trunk/rubberband/src/PercussiveAudioCurve.h
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 30 30 virtual void setWindowSize(size_t newSize); 31 31 32 virtual float process(float *mag, size_t increment); 32 virtual float process(const float *R__ mag, size_t increment); 33 virtual float process(const double *R__ mag, size_t increment); 33 34 virtual void reset(); 34 35 35 36 protected: 36 double *m_prevMag;37 float *R__ m_prevMag; 37 38 }; 38 39 -
trunk/rubberband/src/Resampler.cpp
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 15 15 #include "Resampler.h" 16 16 17 #include "Profiler.h" 18 17 19 #include <cstdlib> 18 20 #include <cmath> … … 23 25 #include <samplerate.h> 24 26 27 28 25 29 namespace RubberBand { 26 30 27 class Resampler ::D31 class ResamplerImpl 28 32 { 29 33 public: 30 D(Quality quality, size_t channels, size_t maxBufferSize); 31 ~D(); 32 33 size_t resample(float **in, float **out, 34 size_t incount, float ratio, bool final); 34 virtual ~ResamplerImpl() { } 35 36 virtual int resample(const float *const R__ *const R__ in, 37 float *const R__ *const R__ out, 38 int incount, 39 float ratio, 40 bool final) = 0; 41 42 virtual void reset() = 0; 43 }; 44 45 namespace Resamplers { 46 47 48 49 class D_SRC : public ResamplerImpl 50 { 51 public: 52 D_SRC(Resampler::Quality quality, int channels, int maxBufferSize, 53 int m_debugLevel); 54 ~D_SRC(); 55 56 int resample(const float *const R__ *const R__ in, 57 float *const R__ *const R__ out, 58 int incount, 59 float ratio, 60 bool final); 35 61 36 62 void reset(); … … 40 66 float *m_iin; 41 67 float *m_iout; 42 size_t m_channels; 43 size_t m_iinsize; 44 size_t m_ioutsize; 68 float m_lastRatio; 69 int m_channels; 70 int m_iinsize; 71 int m_ioutsize; 72 int m_debugLevel; 45 73 }; 46 74 47 Resampler::D::D(Quality quality, size_t channels, size_t maxBufferSize) : 75 D_SRC::D_SRC(Resampler::Quality quality, int channels, int maxBufferSize, 76 int debugLevel) : 48 77 m_src(0), 49 78 m_iin(0), 50 79 m_iout(0), 80 m_lastRatio(1.f), 51 81 m_channels(channels), 52 82 m_iinsize(0), 53 m_ioutsize(0) 54 { 55 // std::cerr << "Resampler::Resampler: using libsamplerate implementation" 56 // << std::endl; 83 m_ioutsize(0), 84 m_debugLevel(debugLevel) 85 { 86 if (m_debugLevel > 0) { 87 std::cerr << "Resampler::Resampler: using libsamplerate implementation" 88 << std::endl; 89 } 57 90 58 91 int err = 0; 59 m_src = src_new(quality == Best ? SRC_SINC_BEST_QUALITY :60 quality == Fastest ? SRC_LINEAR :92 m_src = src_new(quality == Resampler::Best ? SRC_SINC_BEST_QUALITY : 93 quality == Resampler::Fastest ? SRC_LINEAR : 61 94 SRC_SINC_FASTEST, 62 95 channels, &err); 63 96 64 //!!! check err, throw 97 if (err) { 98 std::cerr << "Resampler::Resampler: failed to create libsamplerate resampler: " 99 << src_strerror(err) << std::endl; 100 throw Resampler::ImplementationError; //!!! of course, need to catch this! 101 } 65 102 66 103 if (maxBufferSize > 0 && m_channels > 1) { 67 //!!! alignment?68 104 m_iinsize = maxBufferSize * m_channels; 69 105 m_ioutsize = maxBufferSize * m_channels * 2; 70 m_iin = (float *)malloc(m_iinsize * sizeof(float)); 71 m_iout = (float *)malloc(m_ioutsize * sizeof(float)); 72 } 73 } 74 75 Resampler::D::~D() 106 m_iin = allocFloat(m_iinsize); 107 m_iout = allocFloat(m_ioutsize); 108 } 109 110 reset(); 111 } 112 113 D_SRC::~D_SRC() 76 114 { 77 115 src_delete(m_src); … … 84 122 } 85 123 86 size_t 87 Resampler::D::resample(float **in, float **out, size_t incount, float ratio, 88 bool final) 124 int 125 D_SRC::resample(const float *const R__ *const R__ in, 126 float *const R__ *const R__ out, 127 int incount, 128 float ratio, 129 bool final) 89 130 { 90 131 SRC_DATA data; 91 132 92 size_t outcount = lrintf(ceilf(incount * ratio));133 int outcount = lrintf(ceilf(incount * ratio)); 93 134 94 135 if (m_channels == 1) { 95 data.data_in = *in;136 data.data_in = const_cast<float *>(*in); //!!!??? 96 137 data.data_out = *out; 97 138 } else { 98 139 if (incount * m_channels > m_iinsize) { 99 m_iinsize = incount * m_channels; 100 m_iin = (float *)realloc(m_iin, m_iinsize * sizeof(float)); 140 m_iin = allocFloat(m_iin, m_iinsize); 101 141 } 102 142 if (outcount * m_channels > m_ioutsize) { 103 m_ioutsize = outcount * m_channels; 104 m_iout = (float *)realloc(m_iout, m_ioutsize * sizeof(float)); 105 } 106 for (size_t i = 0; i < incount; ++i) { 107 for (size_t c = 0; c < m_channels; ++c) { 143 m_iout = allocFloat(m_iout, m_ioutsize); 144 } 145 for (int i = 0; i < incount; ++i) { 146 for (int c = 0; c < m_channels; ++c) { 108 147 m_iin[i * m_channels + c] = in[c][i]; 109 148 } … … 118 157 data.end_of_input = (final ? 1 : 0); 119 158 120 src_process(m_src, &data); 121 122 //!!! check err, respond appropriately 159 int err = src_process(m_src, &data); 160 161 if (err) { 162 std::cerr << "Resampler::process: libsamplerate error: " 163 << src_strerror(err) << std::endl; 164 throw Resampler::ImplementationError; //!!! of course, need to catch this! 165 } 123 166 124 167 if (m_channels > 1) { 125 168 for (int i = 0; i < data.output_frames_gen; ++i) { 126 for ( size_t c = 0; c < m_channels; ++c) {169 for (int c = 0; c < m_channels; ++c) { 127 170 out[c][i] = m_iout[i * m_channels + c]; 128 171 } … … 130 173 } 131 174 175 m_lastRatio = ratio; 176 132 177 return data.output_frames_gen; 133 178 } 134 179 135 180 void 136 Resampler::D::reset()181 D_SRC::reset() 137 182 { 138 183 src_reset(m_src); 139 184 } 140 185 141 } // end namespace 142 143 144 namespace RubberBand { 145 146 Resampler::Resampler(Quality quality, size_t channels, size_t maxBufferSize) 147 { 148 m_d = new D(quality, channels, maxBufferSize); 186 187 188 } /* end namespace Resamplers */ 189 190 Resampler::Resampler(Resampler::Quality quality, int channels, 191 int maxBufferSize, int debugLevel) 192 { 193 m_method = -1; 194 195 switch (quality) { 196 197 case Resampler::Best: 198 m_method = 1; 199 break; 200 201 case Resampler::FastestTolerable: 202 m_method = 1; 203 break; 204 205 case Resampler::Fastest: 206 m_method = 1; 207 break; 208 } 209 210 if (m_method == -1) { 211 std::cerr << "Resampler::Resampler(" << quality << ", " << channels 212 << ", " << maxBufferSize << "): No implementation available!" 213 << std::endl; 214 abort(); 215 } 216 217 switch (m_method) { 218 case 0: 219 std::cerr << "Resampler::Resampler(" << quality << ", " << channels 220 << ", " << maxBufferSize << "): No implementation available!" 221 << std::endl; 222 abort(); 223 break; 224 225 case 1: 226 d = new Resamplers::D_SRC(quality, channels, maxBufferSize, debugLevel); 227 break; 228 229 case 2: 230 std::cerr << "Resampler::Resampler(" << quality << ", " << channels 231 << ", " << maxBufferSize << "): No implementation available!" 232 << std::endl; 233 abort(); 234 break; 235 } 149 236 } 150 237 151 238 Resampler::~Resampler() 152 239 { 153 delete m_d; 154 } 155 156 size_t 157 Resampler::resample(float **in, float **out, 158 size_t incount, float ratio, bool final) 159 { 160 return m_d->resample(in, out, incount, ratio, final); 240 delete d; 241 } 242 243 int 244 Resampler::resample(const float *const R__ *const R__ in, 245 float *const R__ *const R__ out, 246 int incount, float ratio, bool final) 247 { 248 Profiler profiler("Resampler::resample"); 249 return d->resample(in, out, incount, ratio, final); 161 250 } 162 251 … … 164 253 Resampler::reset() 165 254 { 166 m_d->reset();167 } 168 169 } 255 d->reset(); 256 } 257 258 } -
trunk/rubberband/src/Resampler.h
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 18 18 #include <sys/types.h> 19 19 20 #include "sysutils.h" 21 20 22 namespace RubberBand { 23 24 class ResamplerImpl; 21 25 22 26 class Resampler … … 24 28 public: 25 29 enum Quality { Best, FastestTolerable, Fastest }; 30 enum Exception { ImplementationError }; 26 31 27 32 /** … … 31 36 * resampler needs to reallocate its internal buffers. 32 37 */ 33 Resampler(Quality quality, size_t channels, size_t maxBufferSize = 0); 38 Resampler(Quality quality, int channels, int maxBufferSize = 0, 39 int debugLevel = 0); 34 40 ~Resampler(); 35 41 36 size_t resample(float **in, float **out, 37 size_t incount, float ratio, bool final = false); 42 int resample(const float *const R__ *const R__ in, 43 float *const R__ *const R__ out, 44 int incount, 45 float ratio, 46 bool final = false); 38 47 39 48 void reset(); 40 49 41 50 protected: 42 class D;43 D *m_d;51 ResamplerImpl *d; 52 int m_method; 44 53 }; 45 54 -
trunk/rubberband/src/RingBuffer.h
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 18 18 #include <sys/types.h> 19 19 20 #include <cstring> 21 20 22 #ifndef _WIN32 21 23 #include <sys/mman.h> … … 23 25 24 26 #include "Scavenger.h" 27 #include "Profiler.h" 28 25 29 26 30 //#define DEBUG_RINGBUFFER 1 … … 58 62 * minus one. 59 63 */ 60 RingBuffer( size_t n);64 RingBuffer(int n); 61 65 62 66 virtual ~RingBuffer(); … … 66 70 * (This is the argument n passed to the constructor.) 67 71 */ 68 size_t getSize() const;72 int getSize() const; 69 73 70 74 /** … … 74 78 * delay. Should be called from the write thread. 75 79 */ 76 void resize( size_t newSize);80 void resize(int newSize); 77 81 78 82 /** … … 84 88 * size, the contents are undefined. 85 89 */ 86 RingBuffer<T, N> *resized( size_t newSize, int R = 0) const;90 RingBuffer<T, N> *resized(int newSize, int R = 0) const; 87 91 88 92 /** … … 102 106 * samples. 103 107 */ 104 size_t getReadSpace(int R = 0) const;108 int getReadSpace(int R = 0) const; 105 109 106 110 /** 107 111 * Return the amount of space available for writing, in samples. 108 112 */ 109 size_t getWriteSpace() const;113 int getWriteSpace() const; 110 114 111 115 /** … … 114 118 * number of samples actually read. 115 119 */ 116 size_t read(T *destination, size_t n, int R = 0);120 int read(T *R__ destination, int n, int R = 0); 117 121 118 122 /** … … 122 126 * read. 123 127 */ 124 size_t readAdding(T *destination, size_t n, int R = 0);128 int readAdding(T *R__ destination, int n, int R = 0); 125 129 126 130 /** … … 140 144 * number of samples actually read. 141 145 */ 142 size_t peek(T *destination, size_t n, int R = 0) const;146 int peek(T *R__ destination, int n, int R = 0) const; 143 147 144 148 /** … … 156 160 * discarding. 157 161 */ 158 size_t skip(size_t n, int R = 0);162 int skip(int n, int R = 0); 159 163 160 164 /** … … 163 167 * the number of samples actually written. 164 168 */ 165 size_t write(const T *source, size_t n);169 int write(const T *source, int n); 166 170 167 171 /** … … 170 174 * Returns the number of zeroes actually written. 171 175 */ 172 size_t zero(size_t n);176 int zero(int n); 173 177 174 178 protected: 175 T *m_buffer;176 volatile size_tm_writer;177 volatile size_tm_readers[N];178 size_tm_size;179 T *R__ m_buffer; 180 volatile int m_writer; 181 volatile int m_readers[N]; 182 int m_size; 179 183 bool m_mlocked; 180 184 … … 190 194 191 195 template <typename T, int N> 192 RingBuffer<T, N>::RingBuffer( size_t n) :196 RingBuffer<T, N>::RingBuffer(int n) : 193 197 m_buffer(new T[n + 1]), 194 198 m_writer(0), … … 221 225 222 226 template <typename T, int N> 223 size_t227 int 224 228 RingBuffer<T, N>::getSize() const 225 229 { … … 233 237 template <typename T, int N> 234 238 void 235 RingBuffer<T, N>::resize( size_t newSize)239 RingBuffer<T, N>::resize(int newSize) 236 240 { 237 241 #ifdef DEBUG_RINGBUFFER … … 260 264 template <typename T, int N> 261 265 RingBuffer<T, N> * 262 RingBuffer<T, N>::resized( size_t newSize, int R) const266 RingBuffer<T, N>::resized(int newSize, int R) const 263 267 { 264 268 RingBuffer<T, N> *newBuffer = new RingBuffer<T, N>(newSize); 265 269 266 size_t w = m_writer;267 size_t r = m_readers[R];270 int w = m_writer; 271 int r = m_readers[R]; 268 272 269 273 while (r != w) { … … 298 302 299 303 template <typename T, int N> 300 size_t304 int 301 305 RingBuffer<T, N>::getReadSpace(int R) const 302 306 { 303 size_t writer = m_writer;304 size_t reader = m_readers[R];305 size_t space;307 int writer = m_writer; 308 int reader = m_readers[R]; 309 int space; 306 310 307 311 #ifdef DEBUG_RINGBUFFER … … 321 325 322 326 template <typename T, int N> 323 size_t327 int 324 328 RingBuffer<T, N>::getWriteSpace() const 325 329 { 326 size_t space = 0;330 int space = 0; 327 331 for (int i = 0; i < N; ++i) { 328 size_t writer = m_writer;329 size_t reader = m_readers[i];330 size_t here = (reader + m_size - writer - 1);332 int writer = m_writer; 333 int reader = m_readers[i]; 334 int here = (reader + m_size - writer - 1); 331 335 if (here >= m_size) here -= m_size; 332 336 if (i == 0 || here < space) space = here; … … 334 338 335 339 #ifdef DEBUG_RINGBUFFER 336 size_t rs(getReadSpace()), rp(m_readers[0]);340 int rs(getReadSpace()), rp(m_readers[0]); 337 341 338 342 std::cerr << "RingBuffer: write space " << space << ", read space " … … 349 353 350 354 template <typename T, int N> 351 size_t 352 RingBuffer<T, N>::read(T *destination, size_t n, int R) 353 { 355 int 356 RingBuffer<T, N>::read(T *R__ destination, int n, int R) 357 { 358 Profiler profiler("RingBuffer::read"); 359 354 360 #ifdef DEBUG_RINGBUFFER 355 361 std::cerr << "RingBuffer<T," << N << ">[" << this << "]::read(dest, " << n << ", " << R << ")" << std::endl; 356 362 #endif 357 363 358 size_t available = getReadSpace(R);364 int available = getReadSpace(R); 359 365 if (n > available) { 360 366 #ifdef DEBUG_RINGBUFFER … … 362 368 << std::endl; 363 369 #endif 364 for ( size_t i = available; i < n; ++i) {370 for (int i = available; i < n; ++i) { 365 371 destination[i] = 0; 366 372 } … … 369 375 if (n == 0) return n; 370 376 371 size_t reader = m_readers[R]; 372 size_t here = m_size - reader; 377 int reader = m_readers[R]; 378 int here = m_size - reader; 379 T *const R__ bufbase = m_buffer + reader; 373 380 374 381 if (here >= n) { 375 for ( size_t i = 0; i < n; ++i) {376 destination[i] = (m_buffer + reader)[i];382 for (int i = 0; i < n; ++i) { 383 destination[i] = bufbase[i]; 377 384 } 378 385 } else { 379 for (size_t i = 0; i < here; ++i) { 380 destination[i] = (m_buffer + reader)[i]; 381 } 382 for (size_t i = 0; i < (n - here); ++i) { 383 destination[i + here] = m_buffer[i]; 386 for (int i = 0; i < here; ++i) { 387 destination[i] = bufbase[i]; 388 } 389 T *const R__ destbase = destination + here; 390 const int nh = n - here; 391 for (int i = 0; i < nh; ++i) { 392 destbase[i] = m_buffer[i]; 384 393 } 385 394 } … … 397 406 398 407 template <typename T, int N> 399 size_t 400 RingBuffer<T, N>::readAdding(T *destination, size_t n, int R) 401 { 408 int 409 RingBuffer<T, N>::readAdding(T *R__ destination, int n, int R) 410 { 411 Profiler profiler("RingBuffer::readAdding"); 412 402 413 #ifdef DEBUG_RINGBUFFER 403 414 std::cerr << "RingBuffer<T," << N << ">[" << this << "]::readAdding(dest, " << n << ", " << R << ")" << std::endl; 404 415 #endif 405 416 406 size_t available = getReadSpace(R);417 int available = getReadSpace(R); 407 418 if (n > available) { 408 419 #ifdef DEBUG_RINGBUFFER … … 414 425 if (n == 0) return n; 415 426 416 size_t reader = m_readers[R]; 417 size_t here = m_size - reader; 427 int reader = m_readers[R]; 428 int here = m_size - reader; 429 const T *const R__ bufbase = m_buffer + reader; 418 430 419 431 if (here >= n) { 420 for ( size_t i = 0; i < n; ++i) {421 destination[i] += (m_buffer + reader)[i];432 for (int i = 0; i < n; ++i) { 433 destination[i] += bufbase[i]; 422 434 } 423 435 } else { 424 for ( size_t i = 0; i < here; ++i) {425 destination[i] += (m_buffer + reader)[i];436 for (int i = 0; i < here; ++i) { 437 destination[i] += bufbase[i]; 426 438 } 427 for (size_t i = 0; i < (n - here); ++i) { 428 destination[i + here] += m_buffer[i]; 439 T *const R__ destbase = destination + here; 440 const int nh = n - here; 441 for (int i = 0; i < nh; ++i) { 442 destbase[i] += m_buffer[i]; 429 443 } 430 444 } … … 451 465 return 0; 452 466 } 453 size_t reader = m_readers[R];467 int reader = m_readers[R]; 454 468 T value = m_buffer[reader]; 455 469 if (++reader == m_size) reader = 0; … … 459 473 460 474 template <typename T, int N> 461 size_t 462 RingBuffer<T, N>::peek(T *destination, size_t n, int R) const 463 { 475 int 476 RingBuffer<T, N>::peek(T *R__ destination, int n, int R) const 477 { 478 Profiler profiler("RingBuffer::peek"); 479 464 480 #ifdef DEBUG_RINGBUFFER 465 481 std::cerr << "RingBuffer<T," << N << ">[" << this << "]::peek(dest, " << n << ", " << R << ")" << std::endl; 466 482 #endif 467 483 468 size_t available = getReadSpace(R);484 int available = getReadSpace(R); 469 485 if (n > available) { 470 486 #ifdef DEBUG_RINGBUFFER … … 477 493 if (n == 0) return n; 478 494 479 size_t reader = m_readers[R]; 480 size_t here = m_size - reader; 495 int reader = m_readers[R]; 496 int here = m_size - reader; 497 const T *const R__ bufbase = m_buffer + reader; 481 498 482 499 if (here >= n) { 483 for ( size_t i = 0; i < n; ++i) {484 destination[i] = (m_buffer + reader)[i];500 for (int i = 0; i < n; ++i) { 501 destination[i] = bufbase[i]; 485 502 } 486 503 } else { 487 for (size_t i = 0; i < here; ++i) { 488 destination[i] = (m_buffer + reader)[i]; 489 } 490 for (size_t i = 0; i < (n - here); ++i) { 491 destination[i + here] = m_buffer[i]; 504 for (int i = 0; i < here; ++i) { 505 destination[i] = bufbase[i]; 506 } 507 T *const R__ destbase = destination + here; 508 const int nh = n - here; 509 for (int i = 0; i < nh; ++i) { 510 destbase[i] = m_buffer[i]; 492 511 } 493 512 } … … 520 539 521 540 template <typename T, int N> 522 size_t523 RingBuffer<T, N>::skip( size_t n, int R)541 int 542 RingBuffer<T, N>::skip(int n, int R) 524 543 { 525 544 #ifdef DEBUG_RINGBUFFER … … 527 546 #endif 528 547 529 size_t available = getReadSpace(R);548 int available = getReadSpace(R); 530 549 if (n > available) { 531 550 #ifdef DEBUG_RINGBUFFER … … 537 556 if (n == 0) return n; 538 557 539 size_t reader = m_readers[R];558 int reader = m_readers[R]; 540 559 reader += n; 541 560 while (reader >= m_size) reader -= m_size; … … 545 564 546 565 template <typename T, int N> 547 size_t 548 RingBuffer<T, N>::write(const T *source, size_t n) 549 { 566 int 567 RingBuffer<T, N>::write(const T *source, int n) 568 { 569 Profiler profiler("RingBuffer::write"); 570 550 571 #ifdef DEBUG_RINGBUFFER 551 572 std::cerr << "RingBuffer<T," << N << ">[" << this << "]::write(" << n << ")" << std::endl; 552 573 #endif 553 574 554 size_t available = getWriteSpace();575 int available = getWriteSpace(); 555 576 if (n > available) { 556 577 #ifdef DEBUG_RINGBUFFER … … 562 583 if (n == 0) return n; 563 584 564 size_t writer = m_writer; 565 size_t here = m_size - writer; 585 int writer = m_writer; 586 int here = m_size - writer; 587 T *const R__ bufbase = m_buffer + writer; 588 566 589 if (here >= n) { 567 for ( size_t i = 0; i < n; ++i) {568 (m_buffer + writer)[i] = source[i];590 for (int i = 0; i < n; ++i) { 591 bufbase[i] = source[i]; 569 592 } 570 593 } else { 571 for (size_t i = 0; i < here; ++i) { 572 (m_buffer + writer)[i] = source[i]; 573 } 574 for (size_t i = 0; i < (n - here); ++i) { 575 m_buffer[i] = (source + here)[i]; 594 for (int i = 0; i < here; ++i) { 595 bufbase[i] = source[i]; 596 } 597 const int nh = n - here; 598 const T *const R__ srcbase = source + here; 599 T *const R__ buf = m_buffer; 600 for (int i = 0; i < nh; ++i) { 601 buf[i] = srcbase[i]; 576 602 } 577 603 } … … 589 615 590 616 template <typename T, int N> 591 size_t 592 RingBuffer<T, N>::zero(size_t n) 593 { 617 int 618 RingBuffer<T, N>::zero(int n) 619 { 620 Profiler profiler("RingBuffer::zero"); 621 594 622 #ifdef DEBUG_RINGBUFFER 595 623 std::cerr << "RingBuffer<T," << N << ">[" << this << "]::zero(" << n << ")" << std::endl; 596 624 #endif 597 625 598 size_t available = getWriteSpace();626 int available = getWriteSpace(); 599 627 if (n > available) { 600 628 #ifdef DEBUG_RINGBUFFER … … 606 634 if (n == 0) return n; 607 635 608 size_t writer = m_writer; 609 size_t here = m_size - writer; 636 int writer = m_writer; 637 int here = m_size - writer; 638 T *const R__ bufbase = m_buffer + writer; 639 610 640 if (here >= n) { 611 for ( size_t i = 0; i < n; ++i) {612 (m_buffer + writer)[i] = 0;641 for (int i = 0; i < n; ++i) { 642 bufbase[i] = 0; 613 643 } 614 644 } else { 615 for (size_t i = 0; i < here; ++i) { 616 (m_buffer + writer)[i] = 0; 617 } 618 for (size_t i = 0; i < (n - here); ++i) { 645 for (int i = 0; i < here; ++i) { 646 bufbase[i] = 0; 647 } 648 const int nh = n - here; 649 for (int i = 0; i < nh; ++i) { 619 650 m_buffer[i] = 0; 620 651 } … … 634 665 } 635 666 667 //#include "RingBuffer.cpp" 668 636 669 #endif // _RINGBUFFER_H_ -
trunk/rubberband/src/RubberBandStretcher.cpp
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 23 23 double initialTimeRatio, 24 24 double initialPitchScale) : 25 TimeStretcher(sampleRate, channels), 26 m_d(new Impl(this, sampleRate, channels, options, 25 m_d(new Impl(sampleRate, channels, options, 27 26 initialTimeRatio, initialPitchScale)) 28 27 { … … 83 82 84 83 void 84 RubberBandStretcher::setFormantOption(Options options) 85 { 86 m_d->setFormantOption(options); 87 } 88 89 void 90 RubberBandStretcher::setPitchOption(Options options) 91 { 92 m_d->setPitchOption(options); 93 } 94 95 void 85 96 RubberBandStretcher::setExpectedInputDuration(size_t samples) 86 97 { -
trunk/rubberband/src/Scavenger.h
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 18 18 #include <vector> 19 19 #include <list> 20 #include <iostream> 21 22 #ifndef WIN32 20 23 #include <sys/time.h> 21 # include <iostream>24 #endif 22 25 23 26 #include "Thread.h" -
trunk/rubberband/src/SilentAudioCurve.h
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 13 13 */ 14 14 15 #ifndef _ HIGHFREQUENCY_AUDIO_CURVE_H_16 #define _ HIGHFREQUENCY_AUDIO_CURVE_H_15 #ifndef _SILENT_AUDIO_CURVE_H_ 16 #define _SILENT_AUDIO_CURVE_H_ 17 17 18 18 #include "AudioCurve.h" 19 #include "Window.h"20 19 21 20 namespace RubberBand 22 21 { 23 22 24 class HighFrequencyAudioCurve : public AudioCurve23 class SilentAudioCurve : public AudioCurve 25 24 { 26 25 public: 27 HighFrequencyAudioCurve(size_t sampleRate, size_t windowSize); 28 29 virtual ~HighFrequencyAudioCurve(); 26 SilentAudioCurve(size_t sampleRate, size_t windowSize); 27 virtual ~SilentAudioCurve(); 30 28 31 29 virtual void setWindowSize(size_t newSize); 32 30 33 virtual float process(float *mag, size_t increment); 31 virtual float process(const float *R__ mag, size_t increment); 32 virtual float process(const double *R__ mag, size_t increment); 34 33 virtual void reset(); 35 34 }; -
trunk/rubberband/src/SpectralDifferenceAudioCurve.cpp
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 21 21 AudioCurve(sampleRate, windowSize) 22 22 { 23 m_prevMag = new double[m_windowSize/2 + 1];23 m_prevMag = new float[m_windowSize/2 + 1]; 24 24 25 25 for (size_t i = 0; i <= m_windowSize/2; ++i) { … … 44 44 SpectralDifferenceAudioCurve::setWindowSize(size_t newSize) 45 45 { 46 delete[] m_prevMag; 46 47 m_windowSize = newSize; 48 49 m_prevMag = new float[m_windowSize/2 + 1]; 50 51 reset(); 47 52 } 48 53 49 54 float 50 SpectralDifferenceAudioCurve::process( float *mag, size_t increment)55 SpectralDifferenceAudioCurve::process(const float *R__ mag, size_t increment) 51 56 { 52 57 float result = 0.0; -
trunk/rubberband/src/SpectralDifferenceAudioCurve.h
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 31 31 virtual void setWindowSize(size_t newSize); 32 32 33 virtual float process( float *mag, size_t increment);33 virtual float process(const float *R__ mag, size_t increment); 34 34 virtual void reset(); 35 35 36 36 protected: 37 double *m_prevMag;37 float *R__ m_prevMag; 38 38 }; 39 39 -
trunk/rubberband/src/StretchCalculator.cpp
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 20 20 #include <set> 21 21 #include <cassert> 22 #include <algorithm> 23 24 #include "sysutils.h" 22 25 23 26 namespace RubberBand … … 163 166 int 164 167 StretchCalculator::calculateSingle(double ratio, 165 size_t inputDurationSoFar, 166 float df) 167 { 168 float df, 169 size_t increment) 170 { 171 if (increment == 0) increment = m_increment; 172 168 173 bool isTransient = false; 169 174 … … 177 182 // works well in common situations. 178 183 179 float transientThreshold = 0.35 ;180 if (ratio > 1) transientThreshold = 0.25 ;181 182 if (m_useHardPeaks && df > m_prevDf * 1.1 && df > transientThreshold) {184 float transientThreshold = 0.35f; 185 if (ratio > 1) transientThreshold = 0.25f; 186 187 if (m_useHardPeaks && df > m_prevDf * 1.1f && df > transientThreshold) { 183 188 isTransient = true; 184 189 } … … 191 196 m_prevDf = df; 192 197 198 bool ratioChanged = (ratio != m_prevRatio); 199 m_prevRatio = ratio; 200 193 201 if (isTransient && m_transientAmnesty == 0) { 194 202 if (m_debugLevel > 1) { 195 std::cerr << "StretchCalculator::calculateSingle: transient found at"196 << inputDurationSoFar <<std::endl;197 } 198 m_divergence += m_increment - (m_increment * ratio);203 std::cerr << "StretchCalculator::calculateSingle: transient" 204 << std::endl; 205 } 206 m_divergence += increment - (increment * ratio); 199 207 200 208 // as in offline mode, 0.05 sec approx min between transients 201 209 m_transientAmnesty = 202 lrint(ceil(double(m_sampleRate) / (20 * double(m_increment)))); 203 204 m_recovery = m_divergence / ((m_sampleRate / 10.0) / m_increment); 205 return -m_increment; 206 } 207 208 if (m_prevRatio != ratio) { 209 m_recovery = m_divergence / ((m_sampleRate / 10.0) / m_increment); 210 m_prevRatio = ratio; 210 lrint(ceil(double(m_sampleRate) / (20 * double(increment)))); 211 212 m_recovery = m_divergence / ((m_sampleRate / 10.0) / increment); 213 return -int(increment); 214 } 215 216 if (ratioChanged) { 217 m_recovery = m_divergence / ((m_sampleRate / 10.0) / increment); 211 218 } 212 219 213 220 if (m_transientAmnesty > 0) --m_transientAmnesty; 214 221 215 int incr = lrint( m_increment * ratio - m_recovery);222 int incr = lrint(increment * ratio - m_recovery); 216 223 if (m_debugLevel > 2 || (m_debugLevel > 1 && m_divergence != 0)) { 217 224 std::cerr << "divergence = " << m_divergence << ", recovery = " << m_recovery << ", incr = " << incr << ", "; 218 225 } 219 if (incr < lrint(( m_increment * ratio) / 2)) {220 incr = lrint(( m_increment * ratio) / 2);221 } else if (incr > lrint( m_increment * ratio * 2)) {222 incr = lrint( m_increment * ratio * 2);223 } 224 225 double divdiff = ( m_increment * ratio) - incr;226 if (incr < lrint((increment * ratio) / 2)) { 227 incr = lrint((increment * ratio) / 2); 228 } else if (incr > lrint(increment * ratio * 2)) { 229 incr = lrint(increment * ratio * 2); 230 } 231 232 double divdiff = (increment * ratio) - incr; 226 233 227 234 if (m_debugLevel > 2 || (m_debugLevel > 1 && m_divergence != 0)) { … … 233 240 if ((prevDivergence < 0 && m_divergence > 0) || 234 241 (prevDivergence > 0 && m_divergence < 0)) { 235 m_recovery = m_divergence / ((m_sampleRate / 10.0) / m_increment);242 m_recovery = m_divergence / ((m_sampleRate / 10.0) / increment); 236 243 } 237 244 -
trunk/rubberband/src/StretchCalculator.h
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 46 46 * StretchCalculator object; call reset() to reset it. This uses 47 47 * a less sophisticated method than the offline calculate(). 48 * 49 * If increment is non-zero, use it for the input increment for 50 * this block in preference to m_increment. 48 51 */ 49 virtual int calculateSingle(double ratio, size_t inputDurationSoFar,50 float curveValue);52 virtual int calculateSingle(double ratio, float curveValue, 53 size_t increment = 0); 51 54 52 55 void setUseHardPeaks(bool use) { m_useHardPeaks = use; } -
trunk/rubberband/src/StretcherChannelData.cpp
r234 r267 1 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 2 2 3 /* 4 Rubber Band 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007-2008 Chris Cannam. 7 8 This program is free software; you can redistribute it and/or 9 modify it under the terms of the GNU General Public License as 10 published by the Free Software Foundation; either version 2 of the 11 License, or (at your option) any later version. See the file 12 COPYING included with this distribution for more information. 13 */ 14 3 15 #include "StretcherChannelData.h" 4 16 5 17 #include "Resampler.h" 6 18 19 7 20 namespace RubberBand 8 21 { 9 22 10 23 RubberBandStretcher::Impl::ChannelData::ChannelData(size_t windowSize, 11 size_t outbufSize) 24 int overSample, 25 size_t outbufSize) : 26 oversample(overSample) 12 27 { 13 28 std::set<size_t> s; … … 16 31 17 32 RubberBandStretcher::Impl::ChannelData::ChannelData(const std::set<size_t> &windowSizes, 33 int overSample, 18 34 size_t initialWindowSize, 19 size_t outbufSize) 35 size_t outbufSize) : 36 oversample(overSample) 20 37 { 21 38 construct(windowSizes, initialWindowSize, outbufSize); … … 38 55 } 39 56 40 size_t realSize = maxSize/2 + 1; // size of the real "half" of freq data 57 // max size of the real "half" of freq data 58 size_t realSize = (maxSize * oversample)/2 + 1; 41 59 42 60 // std::cerr << "ChannelData::construct([" << windowSizes.size() << "], " << maxSize << ", " << outbufSize << ")" << std::endl; … … 47 65 outbuf = new RingBuffer<float>(outbufSize); 48 66 49 mag = new double[realSize]; 50 phase = new double[realSize]; 51 prevPhase = new double[realSize]; 52 unwrappedPhase = new double[realSize]; 67 mag = allocDouble(realSize); 68 phase = allocDouble(realSize); 69 prevPhase = allocDouble(realSize); 70 prevError = allocDouble(realSize); 71 unwrappedPhase = allocDouble(realSize); 72 envelope = allocDouble(realSize); 73 53 74 freqPeak = new size_t[realSize]; 54 75 55 accumulator = new float[maxSize];56 windowAccumulator = new float[maxSize]; 57 58 fltbuf = new float[maxSize];76 fltbuf = allocFloat(maxSize); 77 78 accumulator = allocFloat(maxSize); 79 windowAccumulator = allocFloat(maxSize); 59 80 60 81 for (std::set<size_t>::const_iterator i = windowSizes.begin(); 61 82 i != windowSizes.end(); ++i) { 62 ffts[*i] = new FFT(*i );83 ffts[*i] = new FFT(*i * oversample); 63 84 ffts[*i]->initDouble(); 64 85 } 65 86 if (windowSizes.find(initialWindowSize) == windowSizes.end()) { 66 ffts[initialWindowSize] = new FFT(initialWindowSize );87 ffts[initialWindowSize] = new FFT(initialWindowSize * oversample); 67 88 ffts[initialWindowSize]->initDouble(); 68 89 } … … 78 99 79 100 for (size_t i = 0; i < realSize; ++i) { 80 mag[i] = 0.0;81 phase[i] = 0.0;82 prevPhase[i] = 0.0;83 unwrappedPhase[i] = 0.0;84 101 freqPeak[i] = 0; 85 102 } 86 103 87 for (size_t i = 0; i < initialWindowSize ; ++i) {104 for (size_t i = 0; i < initialWindowSize * oversample; ++i) { 88 105 dblbuf[i] = 0.0; 89 106 } 90 91 for (size_t i = 0; i < maxSize; ++i) {92 accumulator[i] = 0.f;93 windowAccumulator[i] = 0.f;94 fltbuf[i] = 0.0;95 }96 107 } 97 108 … … 100 111 { 101 112 size_t oldSize = inbuf->getSize(); 102 size_t realSize = windowSize/2 + 1;113 size_t realSize = (windowSize * oversample) / 2 + 1; 103 114 104 115 // std::cerr << "ChannelData::setWindowSize(" << windowSize << ") [from " << oldSize << "]" << std::endl; … … 115 126 //!!! this also requires a lock, but it shouldn't occur in 116 127 //RT mode with proper initialisation 117 ffts[windowSize] = new FFT(windowSize );128 ffts[windowSize] = new FFT(windowSize * oversample); 118 129 ffts[windowSize]->initDouble(); 119 130 } … … 123 134 dblbuf = fft->getDoubleTimeBuffer(); 124 135 125 for (size_t i = 0; i < windowSize ; ++i) {136 for (size_t i = 0; i < windowSize * oversample; ++i) { 126 137 dblbuf[i] = 0.0; 127 138 } … … 131 142 phase[i] = 0.0; 132 143 prevPhase[i] = 0.0; 144 prevError[i] = 0.0; 133 145 unwrappedPhase[i] = 0.0; 134 146 freqPeak[i] = 0; … … 151 163 // We don't want to preserve data in these arrays 152 164 153 delete[] mag; 154 delete[] phase; 155 delete[] prevPhase; 156 delete[] unwrappedPhase; 165 mag = allocDouble(mag, realSize); 166 phase = allocDouble(phase, realSize); 167 prevPhase = allocDouble(prevPhase, realSize); 168 prevError = allocDouble(prevError, realSize); 169 unwrappedPhase = allocDouble(unwrappedPhase, realSize); 170 envelope = allocDouble(envelope, realSize); 171 157 172 delete[] freqPeak; 158 159 mag = new double[realSize];160 phase = new double[realSize];161 prevPhase = new double[realSize];162 unwrappedPhase = new double[realSize];163 173 freqPeak = new size_t[realSize]; 164 174 165 delete[] fltbuf; 166 fltbuf = new float[windowSize]; 175 fltbuf = allocFloat(fltbuf, windowSize); 167 176 168 177 // But we do want to preserve data in these 169 178 170 float *newAcc = new float[windowSize]; 179 float *newAcc = allocFloat(windowSize); 180 171 181 for (size_t i = 0; i < oldSize; ++i) newAcc[i] = accumulator[i]; 172 delete[] accumulator; 182 183 freeFloat(accumulator); 173 184 accumulator = newAcc; 174 185 175 newAcc = new float[windowSize]; 186 newAcc = allocFloat(windowSize); 187 176 188 for (size_t i = 0; i < oldSize; ++i) newAcc[i] = windowAccumulator[i]; 177 delete[] windowAccumulator; 189 190 freeFloat(windowAccumulator); 178 191 windowAccumulator = newAcc; 179 192 … … 181 194 182 195 for (size_t i = 0; i < realSize; ++i) { 183 mag[i] = 0.0;184 phase[i] = 0.0;185 prevPhase[i] = 0.0;186 unwrappedPhase[i] = 0.0;187 196 freqPeak[i] = 0; 188 197 } 189 198 190 199 for (size_t i = 0; i < windowSize; ++i) { 191 fltbuf[i] = 0.0; 192 } 193 194 for (size_t i = oldSize; i < windowSize; ++i) { 195 accumulator[i] = 0.f; 196 windowAccumulator[i] = 0.f; 200 fltbuf[i] = 0.f; 197 201 } 198 202 199 203 if (ffts.find(windowSize) == ffts.end()) { 200 ffts[windowSize] = new FFT(windowSize );204 ffts[windowSize] = new FFT(windowSize * oversample); 201 205 ffts[windowSize]->initDouble(); 202 206 } … … 206 210 dblbuf = fft->getDoubleTimeBuffer(); 207 211 208 for (size_t i = 0; i < windowSize ; ++i) {212 for (size_t i = 0; i < windowSize * oversample; ++i) { 209 213 dblbuf[i] = 0.0; 210 214 } … … 229 233 } 230 234 235 void 236 RubberBandStretcher::Impl::ChannelData::setResampleBufSize(size_t sz) 237 { 238 resamplebuf = allocFloat(resamplebuf, sz); 239 resamplebufSize = sz; 240 } 241 231 242 RubberBandStretcher::Impl::ChannelData::~ChannelData() 232 243 { 233 244 delete resampler; 234 delete[] resamplebuf; 245 246 freeFloat(resamplebuf); 235 247 236 248 delete inbuf; 237 249 delete outbuf; 238 delete[] mag; 239 delete[] phase; 240 delete[] prevPhase; 241 delete[] unwrappedPhase; 250 251 freeDouble(mag); 252 freeDouble(phase); 253 freeDouble(prevPhase); 254 freeDouble(prevError); 255 freeDouble(unwrappedPhase); 256 freeDouble(envelope); 242 257 delete[] freqPeak; 243 delete[] accumulator;244 delete[] windowAccumulator;245 delete[] fltbuf;258 freeFloat(accumulator); 259 freeFloat(windowAccumulator); 260 freeFloat(fltbuf); 246 261 247 262 for (std::map<size_t, FFT *>::iterator i = ffts.begin(); … … 265 280 inputSize = -1; 266 281 outCount = 0; 282 unchanged = true; 267 283 draining = false; 268 284 outputComplete = false; -
trunk/rubberband/src/StretcherChannelData.h
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 19 19 20 20 #include <set> 21 22 //#define EXPERIMENT 1 21 23 22 24 namespace RubberBand … … 40 42 * size specified by the user of the code. 41 43 */ 42 ChannelData(size_t windowSize, size_t outbufSize);44 ChannelData(size_t windowSize, int overSample, size_t outbufSize); 43 45 44 46 /** … … 55 57 */ 56 58 ChannelData(const std::set<size_t> &windowSizes, 57 size_t initialWindowSize, size_t outbufSize);59 int overSample, size_t initialWindowSize, size_t outbufSize); 58 60 ~ChannelData(); 59 61 … … 77 79 void setOutbufSize(size_t outbufSize); 78 80 81 /** 82 * Set the resampler buffer size. Default if not called is no 83 * buffer allocated at all. 84 */ 85 void setResampleBufSize(size_t resamplebufSize); 86 79 87 RingBuffer<float> *inbuf; 80 88 RingBuffer<float> *outbuf; … … 84 92 85 93 double *prevPhase; 94 double *prevError; 86 95 double *unwrappedPhase; 96 87 97 88 98 size_t *freqPeak; … … 94 104 float *fltbuf; 95 105 double *dblbuf; // owned by FFT object, only used for time domain FFT i/o 106 double *envelope; // for cepstral formant shift 107 bool unchanged; 96 108 97 109 size_t prevIncrement; // only used in RT mode … … 112 124 size_t resamplebufSize; 113 125 126 int oversample; 127 114 128 private: 115 129 void construct(const std::set<size_t> &windowSizes, -
trunk/rubberband/src/StretcherImpl.cpp
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 17 17 #include "HighFrequencyAudioCurve.h" 18 18 #include "SpectralDifferenceAudioCurve.h" 19 #include "SilentAudioCurve.h" 19 20 #include "ConstantAudioCurve.h" 20 21 #include "StretchCalculator.h" 21 22 #include "StretcherChannelData.h" 22 23 #include "Resampler.h" 24 #include "Profiler.h" 23 25 24 26 #include <cassert> … … 35 37 using std::min; 36 38 39 37 40 namespace RubberBand { 38 41 … … 47 50 48 51 49 RubberBandStretcher::Impl::Impl(RubberBandStretcher *stretcher, 50 size_t sampleRate,52 53 RubberBandStretcher::Impl::Impl(size_t sampleRate, 51 54 size_t channels, 52 55 Options options, 53 56 double initialTimeRatio, 54 57 double initialPitchScale) : 55 m_s tretcher(stretcher),58 m_sampleRate(sampleRate), 56 59 m_channels(channels), 57 60 m_timeRatio(initialTimeRatio), … … 71 74 m_spaceAvailable("space"), 72 75 m_inputDuration(0), 76 m_silentHistory(0), 73 77 m_lastProcessOutputIncrements(16), 74 78 m_lastProcessPhaseResetDf(16), 75 79 m_phaseResetAudioCurve(0), 76 80 m_stretchAudioCurve(0), 81 m_silentAudioCurve(0), 77 82 m_stretchCalculator(0), 78 83 m_freq0(600), … … 81 86 m_baseWindowSize(m_defaultWindowSize) 82 87 { 88 83 89 if (m_debugLevel > 0) { 84 cerr << "RubberBandStretcher::Impl::Impl: rate = " << m_s tretcher->m_sampleRate << ", options = " << options << endl;90 cerr << "RubberBandStretcher::Impl::Impl: rate = " << m_sampleRate << ", options = " << options << endl; 85 91 } 86 92 87 93 // Window size will vary according to the audio sample rate, but 88 94 // we don't let it drop below the 48k default 89 m_rateMultiple = float(m_s tretcher->m_sampleRate) / 48000.f;95 m_rateMultiple = float(m_sampleRate) / 48000.f; 90 96 if (m_rateMultiple < 1.f) m_rateMultiple = 1.f; 91 97 m_baseWindowSize = roundUp(int(m_defaultWindowSize * m_rateMultiple)); … … 161 167 delete m_phaseResetAudioCurve; 162 168 delete m_stretchAudioCurve; 169 delete m_silentAudioCurve; 163 170 delete m_stretchCalculator; 164 171 delete m_studyFFT; … … 194 201 if (m_phaseResetAudioCurve) m_phaseResetAudioCurve->reset(); 195 202 if (m_stretchAudioCurve) m_stretchAudioCurve->reset(); 203 if (m_silentAudioCurve) m_silentAudioCurve->reset(); 196 204 m_inputDuration = 0; 205 m_silentHistory = 0; 197 206 198 207 if (m_threaded) m_threadSetMutex.unlock(); … … 228 237 229 238 if (fs == m_pitchScale) return; 239 240 bool was1 = (m_pitchScale == 1.f); 241 bool rbs = resampleBeforeStretching(); 242 230 243 m_pitchScale = fs; 231 244 232 245 reconfigure(); 246 247 if (!(m_options & OptionPitchHighConsistency) && 248 (was1 || resampleBeforeStretching() != rbs) && 249 m_pitchScale != 1.f) { 250 251 // resampling mode has changed 252 for (int c = 0; c < int(m_channels); ++c) { 253 if (m_channelData[c]->resampler) { 254 m_channelData[c]->resampler->reset(); 255 } 256 } 257 } 233 258 } 234 259 … … 322 347 if (m_realtime) { 323 348 324 // use a fixed input increment325 326 inputIncrement = roundUp(int(m_defaultIncrement * m_rateMultiple));327 328 349 if (r < 1) { 350 351 bool rsb = (m_pitchScale < 1.0 && !resampleBeforeStretching()); 352 float windowIncrRatio = 4.5; 353 if (r == 1.0) windowIncrRatio = 4; 354 else if (rsb) windowIncrRatio = 4.5; 355 else windowIncrRatio = 6; 356 357 inputIncrement = int(windowSize / windowIncrRatio); 329 358 outputIncrement = int(floor(inputIncrement * r)); 330 if (outputIncrement < 1) { 331 outputIncrement = 1; 332 inputIncrement = roundUp(lrint(ceil(outputIncrement / r))); 333 windowSize = inputIncrement * 4; 334 } 359 360 // Very long stretch or very low pitch shift 361 if (outputIncrement < m_defaultIncrement / 4) { 362 if (outputIncrement < 1) outputIncrement = 1; 363 while (outputIncrement < m_defaultIncrement / 4 && 364 windowSize < m_baseWindowSize * 4) { 365 outputIncrement *= 2; 366 inputIncrement = lrint(ceil(outputIncrement / r)); 367 windowSize = roundUp(lrint(ceil(inputIncrement * windowIncrRatio))); 368 } 369 } 370 335 371 } else { 336 outputIncrement = int(ceil(inputIncrement * r)); 337 while (outputIncrement > 1024 && inputIncrement > 1) { 338 inputIncrement /= 2; 339 outputIncrement = lrint(ceil(inputIncrement * r)); 340 } 341 windowSize = std::max(windowSize, roundUp(outputIncrement * 6)); 342 if (r > 5) while (windowSize < 8192) windowSize *= 2; 372 373 bool rsb = (m_pitchScale > 1.0 && resampleBeforeStretching()); 374 float windowIncrRatio = 4.5; 375 if (r == 1.0) windowIncrRatio = 4; 376 else if (rsb) windowIncrRatio = 4.5; 377 else windowIncrRatio = 6; 378 379 outputIncrement = int(windowSize / windowIncrRatio); 380 inputIncrement = int(outputIncrement / r); 381 while (outputIncrement > 1024 * m_rateMultiple && 382 inputIncrement > 1) { 383 outputIncrement /= 2; 384 inputIncrement = int(outputIncrement / r); 385 } 386 size_t minwin = roundUp(lrint(outputIncrement * windowIncrRatio)); 387 if (windowSize < minwin) windowSize = minwin; 388 389 if (rsb) { 390 // cerr << "adjusting window size from " << windowSize; 391 size_t newWindowSize = roundUp(lrint(windowSize / m_pitchScale)); 392 if (newWindowSize < 512) newWindowSize = 512; 393 size_t div = windowSize / newWindowSize; 394 if (inputIncrement > div && outputIncrement > div) { 395 inputIncrement /= div; 396 outputIncrement /= div; 397 windowSize /= div; 398 } 399 // cerr << " to " << windowSize << " (inputIncrement = " << inputIncrement << ", outputIncrement = " << outputIncrement << ")" << endl; 400 } 343 401 } 344 402 345 403 } else { 346 347 // use a variable increment348 404 349 405 if (r < 1) { … … 366 422 if (r > 5) while (windowSize < 8192) windowSize *= 2; 367 423 } 368 } 424 } 369 425 370 426 if (m_expectedInputDuration > 0) { … … 451 507 if (m_realtime) { 452 508 windowSizes.insert(m_baseWindowSize); 509 windowSizes.insert(m_baseWindowSize / 2); 453 510 windowSizes.insert(m_baseWindowSize * 2); 454 windowSizes.insert(m_baseWindowSize * 4);511 // windowSizes.insert(m_baseWindowSize * 4); 455 512 } 456 513 windowSizes.insert(m_windowSize); … … 480 537 for (size_t c = 0; c < m_channels; ++c) { 481 538 m_channelData.push_back 482 (new ChannelData(windowSizes, m_windowSize, m_outbufSize));539 (new ChannelData(windowSizes, 1, m_windowSize, m_outbufSize)); 483 540 } 484 541 } … … 486 543 if (!m_realtime && windowSizeChanged) { 487 544 delete m_studyFFT; 488 m_studyFFT = new FFT(m_windowSize );545 m_studyFFT = new FFT(m_windowSize, m_debugLevel); 489 546 m_studyFFT->initFloat(); 490 547 } 491 548 492 if (m_pitchScale != 1.0 || m_realtime) { 549 if (m_pitchScale != 1.0 || 550 (m_options & OptionPitchHighConsistency) || 551 m_realtime) { 493 552 494 553 for (size_t c = 0; c < m_channels; ++c) { … … 497 556 498 557 m_channelData[c]->resampler = 499 new Resampler(Resampler::FastestTolerable, 1, 4096 * 16); 558 new Resampler(Resampler::FastestTolerable, 1, 4096 * 16, 559 m_debugLevel); 500 560 501 561 // rbs is the amount of buffer space we think we'll need … … 505 565 lrintf(ceil((m_increment * m_timeRatio * 2) / m_pitchScale)); 506 566 if (rbs < m_increment * 16) rbs = m_increment * 16; 507 m_channelData[c]->resamplebufSize = rbs; 508 m_channelData[c]->resamplebuf = new float[rbs]; 567 m_channelData[c]->setResampleBufSize(rbs); 509 568 } 510 569 } 511 570 571 // stretchAudioCurve is unused in RT mode; phaseResetAudioCurve, 572 // silentAudioCurve and stretchCalculator however are used in all 573 // modes 574 512 575 delete m_phaseResetAudioCurve; 513 m_phaseResetAudioCurve = new PercussiveAudioCurve(m_stretcher->m_sampleRate, 514 m_windowSize); 515 516 // stretchAudioCurve unused in RT mode; phaseResetAudioCurve and 517 // stretchCalculator however are used in all modes 576 m_phaseResetAudioCurve = new PercussiveAudioCurve 577 (m_sampleRate, m_windowSize); 578 579 delete m_silentAudioCurve; 580 m_silentAudioCurve = new SilentAudioCurve 581 (m_sampleRate, m_windowSize); 518 582 519 583 if (!m_realtime) { … … 521 585 if (!(m_options & OptionStretchPrecise)) { 522 586 m_stretchAudioCurve = new SpectralDifferenceAudioCurve 523 (m_s tretcher->m_sampleRate, m_windowSize);587 (m_sampleRate, m_windowSize); 524 588 } else { 525 589 m_stretchAudioCurve = new ConstantAudioCurve 526 (m_s tretcher->m_sampleRate, m_windowSize);590 (m_sampleRate, m_windowSize); 527 591 } 528 592 } … … 530 594 delete m_stretchCalculator; 531 595 m_stretchCalculator = new StretchCalculator 532 (m_s tretcher->m_sampleRate, m_increment,596 (m_sampleRate, m_increment, 533 597 !(m_options & OptionTransientsSmooth)); 534 598 … … 566 630 m_phaseResetDf.clear(); 567 631 m_stretchDf.clear(); 632 m_silence.clear(); 568 633 m_inputDuration = 0; 569 634 } … … 610 675 611 676 m_channelData[c]->resampler = 612 new Resampler(Resampler::FastestTolerable, 1, m_windowSize); 613 614 m_channelData[c]->resamplebufSize = 615 lrintf(ceil((m_increment * m_timeRatio * 2) / m_pitchScale)); 616 m_channelData[c]->resamplebuf = 617 new float[m_channelData[c]->resamplebufSize]; 677 new Resampler(Resampler::FastestTolerable, 1, m_windowSize, 678 m_debugLevel); 679 680 m_channelData[c]->setResampleBufSize 681 (lrintf(ceil((m_increment * m_timeRatio * 2) / m_pitchScale))); 618 682 } 619 683 } … … 638 702 return; 639 703 } 640 m_options &= ~(OptionTransientsMixed |641 OptionTransientsSmooth |642 OptionTransientsCrisp);704 int mask = (OptionTransientsMixed | OptionTransientsSmooth | OptionTransientsCrisp); 705 m_options &= ~mask; 706 options &= mask; 643 707 m_options |= options; 644 708 … … 650 714 RubberBandStretcher::Impl::setPhaseOption(Options options) 651 715 { 652 m_options &= ~(OptionPhaseAdaptive |653 OptionPhasePeakLocked |654 OptionPhaseIndependent);716 int mask = (OptionPhaseLaminar | OptionPhaseIndependent); 717 m_options &= ~mask; 718 options &= mask; 655 719 m_options |= options; 656 720 } 657 721 658 722 void 723 RubberBandStretcher::Impl::setFormantOption(Options options) 724 { 725 int mask = (OptionFormantShifted | OptionFormantPreserved); 726 m_options &= ~mask; 727 options &= mask; 728 m_options |= options; 729 } 730 731 void 732 RubberBandStretcher::Impl::setPitchOption(Options options) 733 { 734 if (!m_realtime) { 735 cerr << "RubberBandStretcher::Impl::setPitchOption: Pitch option is not used in non-RT mode" << endl; 736 return; 737 } 738 739 Options prior = m_options; 740 741 int mask = (OptionPitchHighQuality | 742 OptionPitchHighSpeed | 743 OptionPitchHighConsistency); 744 m_options &= ~mask; 745 options &= mask; 746 m_options |= options; 747 748 if (prior != m_options) reconfigure(); 749 } 750 751 void 659 752 RubberBandStretcher::Impl::study(const float *const *input, size_t samples, bool final) 660 753 { 754 Profiler profiler("RubberBandStretcher::Impl::study"); 755 661 756 if (m_realtime) { 662 757 if (m_debugLevel > 1) { … … 716 811 } 717 812 718 while ((inbuf.getReadSpace() >= m_windowSize) ||719 (final && (inbuf.getReadSpace() >= m_windowSize/2))) {813 while ((inbuf.getReadSpace() >= int(m_windowSize)) || 814 (final && (inbuf.getReadSpace() >= int(m_windowSize/2)))) { 720 815 721 816 // We know we have at least m_windowSize samples available … … 744 839 df = m_stretchAudioCurve->process(cd.fltbuf, m_increment); 745 840 m_stretchDf.push_back(df); 841 842 df = m_silentAudioCurve->process(cd.fltbuf, m_increment); 843 bool silent = (df > 0.f); 844 if (silent && m_debugLevel > 1) { 845 cerr << "silence found at " << m_inputDuration << endl; 846 } 847 m_silence.push_back(silent); 746 848 747 849 // cout << df << endl; … … 818 920 RubberBandStretcher::Impl::calculateStretch() 819 921 { 922 Profiler profiler("RubberBandStretcher::Impl::calculateStretch"); 923 820 924 std::vector<int> increments = m_stretchCalculator->calculate 821 925 (getEffectiveRatio(), … … 824 928 m_stretchDf); 825 929 930 int history = 0; 931 for (size_t i = 0; i < increments.size(); ++i) { 932 if (i >= m_silence.size()) break; 933 if (m_silence[i]) ++history; 934 else history = 0; 935 if (history >= int(m_windowSize / m_increment) && increments[i] >= 0) { 936 increments[i] = -increments[i]; 937 if (m_debugLevel > 1) { 938 std::cerr << "phase reset on silence (silent history == " 939 << history << ")" << std::endl; 940 } 941 } 942 } 943 826 944 if (m_outputIncrements.empty()) m_outputIncrements = increments; 827 945 else { … … 844 962 RubberBandStretcher::Impl::getSamplesRequired() const 845 963 { 964 Profiler profiler("RubberBandStretcher::Impl::getSamplesRequired"); 965 846 966 size_t reqd = 0; 847 967 … … 879 999 RubberBandStretcher::Impl::process(const float *const *input, size_t samples, bool final) 880 1000 { 1001 Profiler profiler("RubberBandStretcher::Impl::process"); 1002 881 1003 if (m_mode == Finished) { 882 1004 cerr << "RubberBandStretcher::Impl::process: Cannot process again after final chunk" << endl; … … 914 1036 bool allConsumed = false; 915 1037 916 map<size_t, size_t> consumed;1038 size_t *consumed = (size_t *)alloca(m_channels * sizeof(size_t)); 917 1039 for (size_t c = 0; c < m_channels; ++c) { 918 1040 consumed[c] = 0; … … 920 1042 921 1043 while (!allConsumed) { 922 923 // cerr << "process looping" << endl;924 1044 925 1045 //#ifndef NO_THREADING … … 936 1056 937 1057 allConsumed = true; 1058 938 1059 for (size_t c = 0; c < m_channels; ++c) { 939 1060 consumed[c] += consumeChannel(c, 940 1061 input[c] + consumed[c], 941 samples - consumed[c]); 1062 samples - consumed[c], 1063 final); 942 1064 if (consumed[c] < samples) { 943 1065 allConsumed = false; … … 982 1104 */ 983 1105 } 1106 1107 // if (!allConsumed) cerr << "process looping" << endl; 1108 984 1109 } 985 1110 … … 989 1114 } 990 1115 991 size_t 992 RubberBandStretcher::Impl::consumeChannel(size_t c, const float *input, size_t samples) 993 { 994 size_t consumed = 0; 995 996 ChannelData &cd = *m_channelData[c]; 997 RingBuffer<float> &inbuf = *cd.inbuf; 998 999 while (consumed < samples) { 1000 1001 size_t writable = inbuf.getWriteSpace(); 1002 1003 // cerr << "channel " << c << ": samples remaining = " << samples - consumed << ", writable space = " << writable << endl; 1004 1005 writable = min(writable, samples - consumed); 1006 1007 if (writable == 0) { 1008 // warn 1009 // cerr << "WARNING: writable == 0 for ch " << c << " (consumed = " << consumed << ", samples = " << samples << ")" << endl; 1010 return consumed; 1011 } else { 1012 inbuf.write(input + consumed, writable); 1013 consumed += writable; 1014 cd.inCount += writable; 1015 } 1016 } 1017 1018 return samples; 1019 } 1020 1021 1022 } 1023 1116 1117 } 1118 -
trunk/rubberband/src/StretcherImpl.h
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 35 35 { 36 36 public: 37 Impl(RubberBandStretcher *stretcher, 38 size_t sampleRate, size_t channels, Options options, 37 Impl(size_t sampleRate, size_t channels, Options options, 39 38 double initialTimeRatio, double initialPitchScale); 40 39 ~Impl(); … … 51 50 void setTransientsOption(Options); 52 51 void setPhaseOption(Options); 52 void setFormantOption(Options); 53 void setPitchOption(Options); 53 54 54 55 void setExpectedInputDuration(size_t samples); … … 84 85 85 86 protected: 86 RubberBandStretcher *m_stretcher;87 size_t m_sampleRate; 87 88 size_t m_channels; 88 89 89 size_t consumeChannel(size_t channel, const float *input, size_t samples); 90 size_t consumeChannel(size_t channel, const float *input, 91 size_t samples, bool final); 90 92 void processChunks(size_t channel, bool &any, bool &last); 91 93 bool processOneChunk(); // across all channels, for real time use … … 99 101 void analyseChunk(size_t channel); 100 102 void modifyChunk(size_t channel, size_t outputIncrement, bool phaseReset); 103 void formantShiftChunk(size_t channel); 101 104 void synthesiseChunk(size_t channel); 102 105 void writeChunk(size_t channel, size_t shiftIncrement, bool last); … … 110 113 size_t roundUp(size_t value); // to next power of two 111 114 115 bool resampleBeforeStretching() const; 116 112 117 double m_timeRatio; 113 118 double m_pitchScale; … … 162 167 std::vector<float> m_phaseResetDf; 163 168 std::vector<float> m_stretchDf; 169 std::vector<bool> m_silence; 170 int m_silentHistory; 164 171 165 172 class ChannelData; … … 173 180 AudioCurve *m_phaseResetAudioCurve; 174 181 AudioCurve *m_stretchAudioCurve; 182 AudioCurve *m_silentAudioCurve; 175 183 StretchCalculator *m_stretchCalculator; 176 184 -
trunk/rubberband/src/StretcherProcess.cpp
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 20 20 #include "StretcherChannelData.h" 21 21 #include "Resampler.h" 22 #include "Profiler.h" 22 23 23 24 #include <cassert> … … 25 26 #include <set> 26 27 #include <map> 28 #include <deque> 29 27 30 28 31 using std::cerr; … … 98 101 } 99 102 103 bool 104 RubberBandStretcher::Impl::resampleBeforeStretching() const 105 { 106 // We can't resample before stretching in offline mode, because 107 // the stretch calculation is based on doing it the other way 108 // around. It would take more work (and testing) to enable this. 109 if (!m_realtime) return false; 110 111 if (m_options & OptionPitchHighQuality) { 112 return (m_pitchScale < 1.0); // better sound 113 } else if (m_options & OptionPitchHighConsistency) { 114 return false; 115 } else { 116 return (m_pitchScale > 1.0); // better performance 117 } 118 } 119 120 size_t 121 RubberBandStretcher::Impl::consumeChannel(size_t c, const float *input, 122 size_t samples, bool final) 123 { 124 Profiler profiler("RubberBandStretcher::Impl::consumeChannel"); 125 126 ChannelData &cd = *m_channelData[c]; 127 RingBuffer<float> &inbuf = *cd.inbuf; 128 129 size_t toWrite = samples; 130 size_t writable = inbuf.getWriteSpace(); 131 132 bool resampling = resampleBeforeStretching(); 133 134 if (resampling) { 135 136 toWrite = int(ceil(samples / m_pitchScale)); 137 if (writable < toWrite) { 138 samples = int(floor(writable * m_pitchScale)); 139 if (samples == 0) return 0; 140 } 141 142 size_t reqSize = int(ceil(samples / m_pitchScale)); 143 if (reqSize > cd.resamplebufSize) { 144 cerr << "WARNING: RubberBandStretcher::Impl::consumeChannel: resizing resampler buffer from " 145 << cd.resamplebufSize << " to " << reqSize << endl; 146 cd.setResampleBufSize(reqSize); 147 } 148 149 150 toWrite = cd.resampler->resample(&input, 151 &cd.resamplebuf, 152 samples, 153 1.0 / m_pitchScale, 154 final); 155 156 } 157 158 if (writable < toWrite) { 159 if (resampling) { 160 return 0; 161 } 162 toWrite = writable; 163 } 164 165 if (resampling) { 166 inbuf.write(cd.resamplebuf, toWrite); 167 cd.inCount += samples; 168 return samples; 169 } else { 170 inbuf.write(input, toWrite); 171 cd.inCount += toWrite; 172 return toWrite; 173 } 174 } 175 100 176 void 101 177 RubberBandStretcher::Impl::processChunks(size_t c, bool &any, bool &last) 102 178 { 179 Profiler profiler("RubberBandStretcher::Impl::processChunks"); 180 103 181 // Process as many chunks as there are available on the input 104 182 // buffer for channel c. This requires that the increments have … … 141 219 RubberBandStretcher::Impl::processOneChunk() 142 220 { 221 Profiler profiler("RubberBandStretcher::Impl::processOneChunk"); 222 143 223 // Process a single chunk for all channels, provided there is 144 224 // enough data on each channel for at least one chunk. This is … … 174 254 RubberBandStretcher::Impl::testInbufReadSpace(size_t c) 175 255 { 256 Profiler profiler("RubberBandStretcher::Impl::testInbufReadSpace"); 257 176 258 ChannelData &cd = *m_channelData[c]; 177 259 RingBuffer<float> &inbuf = *cd.inbuf; … … 224 306 bool phaseReset) 225 307 { 308 Profiler profiler("RubberBandStretcher::Impl::processChunkForChannel"); 309 226 310 // Process a single chunk on a single channel. This assumes 227 311 // enough input data is available; caller must have tested this … … 250 334 // We need to peek m_windowSize samples for processing, and 251 335 // then skip m_increment to advance the read pointer. 252 336 253 337 modifyChunk(c, phaseIncrement, phaseReset); 254 338 synthesiseChunk(c); // reads from cd.mag, cd.phase … … 285 369 286 370 if (m_threaded) { 287 size_t required = shiftIncrement; 371 372 int required = shiftIncrement; 373 288 374 if (m_pitchScale != 1.0) { 289 375 required = int(required / m_pitchScale) + 1; … … 314 400 bool &phaseReset) 315 401 { 402 Profiler profiler("RubberBandStretcher::Impl::calculateIncrements"); 403 316 404 // cerr << "calculateIncrements" << endl; 317 405 … … 342 430 } 343 431 } 432 433 const int hs = m_windowSize/2 + 1; 344 434 345 435 // Normally we would mix down the time-domain signal and apply a … … 353 443 // be apparent. 354 444 355 for (size_t i = 0; i <= m_windowSize/2; ++i) { 356 cd.fltbuf[i] = 0.0; 357 } 358 359 for (size_t c = 0; c < m_channels; ++c) { 360 for (size_t i = 0; i <= m_windowSize/2; ++i) { 361 cd.fltbuf[i] += m_channelData[c]->mag[i]; 362 } 363 } 364 365 float df = m_phaseResetAudioCurve->process(cd.fltbuf, m_increment); 445 float df = 0.f; 446 bool silent = false; 447 448 if (m_channels == 1) { 449 450 df = m_phaseResetAudioCurve->process(cd.mag, m_increment); 451 silent = (m_silentAudioCurve->process(cd.mag, m_increment) > 0.f); 452 453 } else { 454 455 double *tmp = (double *)alloca(hs * sizeof(double)); 456 457 for (int i = 0; i < hs; ++i) { 458 tmp[i] = 0.0; 459 } 460 for (size_t c = 0; c < m_channels; ++c) { 461 for (int i = 0; i < hs; ++i) { 462 tmp[i] += m_channelData[c]->mag[i]; 463 } 464 } 465 466 df = m_phaseResetAudioCurve->process(tmp, m_increment); 467 silent = (m_silentAudioCurve->process(tmp, m_increment) > 0.f); 468 } 366 469 367 470 int incr = m_stretchCalculator->calculateSingle 368 (getEffectiveRatio(), 369 m_inputDuration, //!!! no, totally wrong... fortunately it doesn't matter atm 370 df); 471 (getEffectiveRatio(), df, m_increment); 371 472 372 473 m_lastProcessPhaseResetDf.write(&df, 1); … … 400 501 401 502 cd.prevIncrement = shiftIncrementRtn; 503 504 if (silent) ++m_silentHistory; 505 else m_silentHistory = 0; 506 507 if (m_silentHistory >= int(m_windowSize / m_increment) && !phaseReset) { 508 phaseReset = true; 509 if (m_debugLevel > 1) { 510 cerr << "calculateIncrements: phase reset on silence (silent history == " 511 << m_silentHistory << ")" << endl; 512 } 513 } 402 514 } 403 515 … … 408 520 bool &phaseReset) 409 521 { 522 Profiler profiler("RubberBandStretcher::Impl::getIncrements"); 523 410 524 if (channel >= m_channels) { 411 525 phaseIncrementRtn = m_increment; … … 479 593 RubberBandStretcher::Impl::analyseChunk(size_t channel) 480 594 { 481 size_t i; 595 Profiler profiler("RubberBandStretcher::Impl::analyseChunk"); 596 597 int i; 482 598 483 599 ChannelData &cd = *m_channelData[channel]; 484 600 601 double *const R__ dblbuf = cd.dblbuf; 602 float *const R__ fltbuf = cd.fltbuf; 603 604 int sz = m_windowSize; 605 int hs = m_windowSize/2; 606 485 607 // cd.fltbuf is known to contain m_windowSize samples 486 608 487 m_window->cut(cd.fltbuf); 488 489 for (i = 0; i < m_windowSize/2; ++i) { 490 cd.dblbuf[i] = cd.fltbuf[i + m_windowSize/2]; 491 cd.dblbuf[i + m_windowSize/2] = cd.fltbuf[i]; 492 } 493 494 cd.fft->forwardPolar(cd.dblbuf, cd.mag, cd.phase); 495 } 496 497 double mod(double x, double y) { return x - (y * floor(x / y)); } 498 double princarg(double a) { return mod(a + M_PI, -2 * M_PI) + M_PI; } 609 m_window->cut(fltbuf); 610 611 if (cd.oversample > 1) { 612 613 int bufsiz = sz * cd.oversample; 614 int offset = (bufsiz - sz) / 2; 615 616 // eek 617 618 for (i = 0; i < offset; ++i) { 619 dblbuf[i] = 0.0; 620 } 621 for (i = 0; i < offset; ++i) { 622 dblbuf[bufsiz - i - 1] = 0.0; 623 } 624 for (i = 0; i < sz; ++i) { 625 dblbuf[offset + i] = fltbuf[i]; 626 } 627 for (i = 0; i < bufsiz / 2; ++i) { 628 double tmp = dblbuf[i]; 629 dblbuf[i] = dblbuf[i + bufsiz/2]; 630 dblbuf[i + bufsiz/2] = tmp; 631 } 632 } else { 633 for (i = 0; i < hs; ++i) { 634 dblbuf[i] = fltbuf[i + hs]; 635 dblbuf[i + hs] = fltbuf[i]; 636 } 637 } 638 639 cd.fft->forwardPolar(dblbuf, cd.mag, cd.phase); 640 } 641 642 static inline double mod(double x, double y) { return x - (y * floor(x / y)); } 643 static inline double princarg(double a) { return mod(a + M_PI, -2.0 * M_PI) + M_PI; } 499 644 500 645 void 501 RubberBandStretcher::Impl::modifyChunk(size_t channel, size_t outputIncrement, 646 RubberBandStretcher::Impl::modifyChunk(size_t channel, 647 size_t outputIncrement, 502 648 bool phaseReset) 503 649 { 650 Profiler profiler("RubberBandStretcher::Impl::modifyChunk"); 651 504 652 ChannelData &cd = *m_channelData[channel]; 505 653 … … 508 656 } 509 657 510 size_t count = m_windowSize/2; 511 size_t pfp = 0; 512 double rate = m_stretcher->m_sampleRate; 513 514 if (!(m_options & OptionPhaseIndependent)) { 515 516 cd.freqPeak[0] = 0; 517 518 float freq0 = m_freq0; 519 float freq1 = m_freq1; 520 float freq2 = m_freq2; 521 522 // As the stretch ratio increases, so the frequency thresholds 523 // for phase lamination should increase. Beyond a ratio of 524 // about 1.5, the threshold should be about 1200Hz; beyond a 525 // ratio of 2, we probably want no lamination to happen at all 526 // by default. This calculation aims for more or less that. 527 // We only do this if the phase option is OptionPhaseAdaptive 528 // (the default), i.e. not Independent or PeakLocked. 529 530 if (!(m_options & OptionPhasePeakLocked)) { 531 float r = getEffectiveRatio(); 532 if (r > 1) { 533 float rf0 = 600 + (600 * ((r-1)*(r-1)*(r-1)*2)); 534 float f1ratio = freq1 / freq0; 535 float f2ratio = freq2 / freq0; 536 freq0 = std::max(freq0, rf0); 537 freq1 = freq0 * f1ratio; 538 freq2 = freq0 * f2ratio; 539 } 540 } 541 542 size_t limit0 = lrint((freq0 * m_windowSize) / rate); 543 size_t limit1 = lrint((freq1 * m_windowSize) / rate); 544 size_t limit2 = lrint((freq2 * m_windowSize) / rate); 545 546 size_t range = 0; 547 548 if (limit1 < limit0) limit1 = limit0; 549 if (limit2 < limit1) limit2 = limit1; 550 551 // cerr << "limit0 = " << limit0 << " limit1 = " << limit1 << " limit2 = " << limit2 << endl; 552 553 int peakCount = 0; 554 555 for (size_t i = 0; i <= count; ++i) { 556 557 double mag = cd.mag[i]; 558 bool isPeak = true; 559 560 for (size_t j = 1; j <= range; ++j) { 561 562 if (mag < cd.mag[i-j]) { 563 isPeak = false; 564 break; 565 } 566 567 if (mag < cd.mag[i+j]) { 568 isPeak = false; 569 break; 570 } 571 } 572 573 if (isPeak) { 574 575 // i is a peak bin. 576 577 // The previous peak bin was at pfp; make freqPeak entries 578 // from pfp to half-way between pfp and i point at pfp, and 579 // those from the half-way mark to i point at i. 580 581 size_t halfway = (pfp + i) / 2; 582 if (halfway == pfp) halfway = pfp + 1; 583 584 for (size_t j = pfp + 1; j < halfway; ++j) { 585 cd.freqPeak[j] = pfp; 586 } 587 for (size_t j = halfway; j <= i; ++j) { 588 cd.freqPeak[j] = i; 589 } 590 591 pfp = i; 592 593 ++peakCount; 594 } 595 596 if (i == limit0) range = 1; 597 if (i == limit1) range = 2; 598 if (i >= limit2) { 599 range = 3; 600 if (i + range + 1 > count) range = count - i; 601 } 602 } 603 604 // cerr << "peakCount = " << peakCount << endl; 605 606 cd.freqPeak[count-1] = count-1; 607 cd.freqPeak[count] = count; 608 } 609 610 double peakInPhase = 0.0; 611 double peakOutPhase = 0.0; 612 size_t p, pp; 613 614 for (size_t i = 0; i <= count; ++i) { 615 616 if (m_options & OptionPhaseIndependent) { 617 p = i; 618 pp = i-1; 619 } else { 620 p = cd.freqPeak[i]; 621 pp = cd.freqPeak[i-1]; 622 } 658 const double rate = m_sampleRate; 659 const int sz = m_windowSize; 660 const int count = (sz * cd.oversample) / 2; 661 662 bool unchanged = cd.unchanged && (outputIncrement == m_increment); 663 bool fullReset = phaseReset; 664 bool laminar = !(m_options & OptionPhaseIndependent); 665 bool bandlimited = (m_options & OptionTransientsMixed); 666 int bandlow = lrint((150 * sz * cd.oversample) / rate); 667 int bandhigh = lrint((1000 * sz * cd.oversample) / rate); 668 669 float freq0 = m_freq0; 670 float freq1 = m_freq1; 671 float freq2 = m_freq2; 672 673 if (laminar) { 674 float r = getEffectiveRatio(); 675 if (r > 1) { 676 float rf0 = 600 + (600 * ((r-1)*(r-1)*(r-1)*2)); 677 float f1ratio = freq1 / freq0; 678 float f2ratio = freq2 / freq0; 679 freq0 = std::max(freq0, rf0); 680 freq1 = freq0 * f1ratio; 681 freq2 = freq0 * f2ratio; 682 } 683 } 684 685 int limit0 = lrint((freq0 * sz * cd.oversample) / rate); 686 int limit1 = lrint((freq1 * sz * cd.oversample) / rate); 687 int limit2 = lrint((freq2 * sz * cd.oversample) / rate); 688 689 if (limit1 < limit0) limit1 = limit0; 690 if (limit2 < limit1) limit2 = limit1; 691 692 double prevInstability = 0.0; 693 bool prevDirection = false; 694 695 double distance = 0.0; 696 const double maxdist = 8.0; 697 698 const int lookback = 1; 699 700 double distacc = 0.0; 701 702 for (int i = count; i >= 0; i -= lookback) { 623 703 624 704 bool resetThis = phaseReset; 625 705 626 if (m_options & OptionTransientsMixed) { 627 size_t low = lrint((150 * m_windowSize) / rate); 628 size_t high = lrint((1000 * m_windowSize) / rate); 706 if (bandlimited) { 629 707 if (resetThis) { 630 if (i > low && i < high) resetThis = false; 631 } 632 } 708 if (i > bandlow && i < bandhigh) { 709 resetThis = false; 710 fullReset = false; 711 } 712 } 713 } 714 715 double p = cd.phase[i]; 716 double perr = 0.0; 717 double outphase = p; 718 719 double mi = maxdist; 720 if (i <= limit0) mi = 0.0; 721 else if (i <= limit1) mi = 1.0; 722 else if (i <= limit2) mi = 3.0; 633 723 634 724 if (!resetThis) { 635 725 636 if (i == 0 || p != pp) { 637 638 double omega = (2 * M_PI * m_increment * p) / m_windowSize; 639 double expectedPhase = cd.prevPhase[p] + omega; 640 double phaseError = princarg(cd.phase[p] - expectedPhase); 641 double phaseIncrement = (omega + phaseError) / m_increment; 642 643 double unwrappedPhase = cd.unwrappedPhase[p] + 644 outputIncrement * phaseIncrement; 645 646 cd.prevPhase[p] = cd.phase[p]; 647 cd.phase[p] = unwrappedPhase; 648 cd.unwrappedPhase[p] = unwrappedPhase; 649 650 peakInPhase = cd.prevPhase[p]; 651 peakOutPhase = unwrappedPhase; 652 } 653 654 if (i != p) { 655 656 double diffToPeak = peakInPhase - cd.phase[i]; 657 double unwrappedPhase = peakOutPhase - diffToPeak; 658 659 cd.prevPhase[i] = cd.phase[i]; 660 cd.phase[i] = unwrappedPhase; 661 cd.unwrappedPhase[i] = unwrappedPhase; 662 } 726 double omega = (2 * M_PI * m_increment * i) / (sz * cd.oversample); 727 728 double pp = cd.prevPhase[i]; 729 double ep = pp + omega; 730 perr = princarg(p - ep); 731 732 double instability = fabs(perr - cd.prevError[i]); 733 bool direction = (perr > cd.prevError[i]); 734 735 bool inherit = false; 736 737 if (laminar) { 738 if (distance >= mi) { 739 inherit = false; 740 } else if (bandlimited && (i == bandhigh || i == bandlow)) { 741 inherit = false; 742 } else if (instability > prevInstability && 743 direction == prevDirection) { 744 inherit = true; 745 } 746 } 747 748 double advance = outputIncrement * ((omega + perr) / m_increment); 749 750 if (inherit) { 751 double inherited = 752 cd.unwrappedPhase[i + lookback] - cd.prevPhase[i + lookback]; 753 advance = ((advance * distance) + 754 (inherited * (maxdist - distance))) 755 / maxdist; 756 outphase = p + advance; 757 distacc += distance; 758 distance += 1.0; 759 } else { 760 outphase = cd.unwrappedPhase[i] + advance; 761 distance = 0.0; 762 } 763 764 prevInstability = instability; 765 prevDirection = direction; 663 766 664 767 } else { 665 cd.prevPhase[i] = cd.phase[i]; 666 cd.unwrappedPhase[i] = cd.phase[i]; 667 } 668 } 768 distance = 0.0; 769 } 770 771 cd.prevError[i] = perr; 772 cd.prevPhase[i] = p; 773 cd.phase[i] = outphase; 774 cd.unwrappedPhase[i] = outphase; 775 } 776 777 if (m_debugLevel > 1) { 778 cerr << "mean inheritance distance = " << distacc / count << endl; 779 } 780 781 if (fullReset) unchanged = true; 782 cd.unchanged = unchanged; 783 784 if (unchanged && m_debugLevel > 1) { 785 cerr << "frame unchanged on channel " << channel << endl; 786 } 787 } 788 789 790 void 791 RubberBandStretcher::Impl::formantShiftChunk(size_t channel) 792 { 793 Profiler profiler("RubberBandStretcher::Impl::formantShiftChunk"); 794 795 ChannelData &cd = *m_channelData[channel]; 796 797 double *const R__ mag = cd.mag; 798 double *const R__ envelope = cd.envelope; 799 double *const R__ dblbuf = cd.dblbuf; 800 801 const int sz = m_windowSize; 802 const int hs = m_windowSize/2; 803 const double denom = sz; 804 805 806 cd.fft->inverseCepstral(mag, dblbuf); 807 808 for (int i = 0; i < sz; ++i) { 809 dblbuf[i] /= denom; 810 } 811 812 const int cutoff = m_sampleRate / 700; 813 814 // cerr <<"cutoff = "<< cutoff << ", m_sampleRate/cutoff = " << m_sampleRate/cutoff << endl; 815 816 dblbuf[0] /= 2; 817 dblbuf[cutoff-1] /= 2; 818 819 for (int i = cutoff; i < sz; ++i) { 820 dblbuf[i] = 0.0; 821 } 822 823 cd.fft->forward(dblbuf, envelope, 0); 824 825 826 for (int i = 0; i <= hs; ++i) { 827 envelope[i] = exp(envelope[i]); 828 } 829 for (int i = 0; i <= hs; ++i) { 830 mag[i] /= envelope[i]; 831 } 832 833 if (m_pitchScale > 1.0) { 834 // scaling up, we want a new envelope that is lower by the pitch factor 835 for (int target = 0; target <= hs; ++target) { 836 int source = lrint(target * m_pitchScale); 837 if (source > int(m_windowSize)) { 838 envelope[target] = 0.0; 839 } else { 840 envelope[target] = envelope[source]; 841 } 842 } 843 } else { 844 // scaling down, we want a new envelope that is higher by the pitch factor 845 for (int target = hs; target > 0; ) { 846 --target; 847 int source = lrint(target * m_pitchScale); 848 envelope[target] = envelope[source]; 849 } 850 } 851 852 for (int i = 0; i <= hs; ++i) { 853 mag[i] *= envelope[i]; 854 } 855 856 cd.unchanged = false; 669 857 } 670 858 … … 672 860 RubberBandStretcher::Impl::synthesiseChunk(size_t channel) 673 861 { 862 Profiler profiler("RubberBandStretcher::Impl::synthesiseChunk"); 863 864 865 if ((m_options & OptionFormantPreserved) && 866 (m_pitchScale != 1.0)) { 867 formantShiftChunk(channel); 868 } 869 674 870 ChannelData &cd = *m_channelData[channel]; 675 871 676 cd.fft->inversePolar(cd.mag, cd.phase, cd.dblbuf); 677 678 for (size_t i = 0; i < m_windowSize/2; ++i) { 679 cd.fltbuf[i] = cd.dblbuf[i + m_windowSize/2]; 680 cd.fltbuf[i + m_windowSize/2] = cd.dblbuf[i]; 681 } 682 683 // our ffts produced unscaled results 684 for (size_t i = 0; i < m_windowSize; ++i) { 685 cd.fltbuf[i] = cd.fltbuf[i] / m_windowSize; 686 } 687 688 m_window->cut(cd.fltbuf); 689 690 for (size_t i = 0; i < m_windowSize; ++i) { 691 cd.accumulator[i] += cd.fltbuf[i]; 872 double *const R__ dblbuf = cd.dblbuf; 873 float *const R__ fltbuf = cd.fltbuf; 874 float *const R__ accumulator = cd.accumulator; 875 float *const R__ windowAccumulator = cd.windowAccumulator; 876 877 int sz = m_windowSize; 878 int hs = m_windowSize/2; 879 int i; 880 881 882 if (!cd.unchanged) { 883 884 cd.fft->inversePolar(cd.mag, cd.phase, cd.dblbuf); 885 886 if (cd.oversample > 1) { 887 888 int bufsiz = sz * cd.oversample; 889 int hbs = hs * cd.oversample; 890 int offset = (bufsiz - sz) / 2; 891 892 for (i = 0; i < hbs; ++i) { 893 double tmp = dblbuf[i]; 894 dblbuf[i] = dblbuf[i + hbs]; 895 dblbuf[i + hbs] = tmp; 896 } 897 for (i = 0; i < sz; ++i) { 898 fltbuf[i] = float(dblbuf[i + offset]); 899 } 900 } else { 901 for (i = 0; i < hs; ++i) { 902 fltbuf[i] = float(dblbuf[i + hs]); 903 } 904 for (i = 0; i < hs; ++i) { 905 fltbuf[i + hs] = float(dblbuf[i]); 906 } 907 } 908 909 float denom = float(sz * cd.oversample); 910 911 // our ffts produced unscaled results 912 for (i = 0; i < sz; ++i) { 913 fltbuf[i] = fltbuf[i] / denom; 914 } 915 } 916 917 m_window->cut(fltbuf); 918 919 for (i = 0; i < sz; ++i) { 920 accumulator[i] += fltbuf[i]; 692 921 } 693 922 694 923 cd.accumulatorFill = m_windowSize; 695 924 696 float fixed = m_window->getArea() * 1.5 ;697 698 for ( size_t i = 0; i < m_windowSize; ++i) {925 float fixed = m_window->getArea() * 1.5f; 926 927 for (i = 0; i < sz; ++i) { 699 928 float val = m_window->getValue(i); 700 cd.windowAccumulator[i] += val * fixed;929 windowAccumulator[i] += val * fixed; 701 930 } 702 931 } … … 705 934 RubberBandStretcher::Impl::writeChunk(size_t channel, size_t shiftIncrement, bool last) 706 935 { 936 Profiler profiler("RubberBandStretcher::Impl::writeChunk"); 937 707 938 ChannelData &cd = *m_channelData[channel]; 708 939 940 float *const R__ accumulator = cd.accumulator; 941 float *const R__ windowAccumulator = cd.windowAccumulator; 942 943 const int sz = m_windowSize; 944 const int si = shiftIncrement; 945 946 int i; 947 709 948 if (m_debugLevel > 2) { 710 949 cerr << "writeChunk(" << channel << ", " << shiftIncrement << ", " << last << ")" << endl; 711 950 } 712 951 713 for ( size_t i = 0; i < shiftIncrement; ++i) {714 if ( cd.windowAccumulator[i] > 0.f) {715 cd.accumulator[i] /= cd.windowAccumulator[i];952 for (i = 0; i < si; ++i) { 953 if (windowAccumulator[i] > 0.f) { 954 accumulator[i] /= windowAccumulator[i]; 716 955 } 717 956 } … … 724 963 } 725 964 726 if (m_pitchScale != 1.0 && cd.resampler) { 727 728 size_t reqSize = int(ceil(shiftIncrement / m_pitchScale)); 965 bool resampledAlready = resampleBeforeStretching(); 966 967 if (!resampledAlready && 968 (m_pitchScale != 1.0 || m_options & OptionPitchHighConsistency) && 969 cd.resampler) { 970 971 size_t reqSize = int(ceil(si / m_pitchScale)); 729 972 if (reqSize > cd.resamplebufSize) { 730 973 // This shouldn't normally happen -- the buffer is … … 735 978 cerr << "WARNING: RubberBandStretcher::Impl::writeChunk: resizing resampler buffer from " 736 979 << cd.resamplebufSize << " to " << reqSize << endl; 737 cd.resamplebufSize = reqSize; 738 if (cd.resamplebuf) delete[] cd.resamplebuf; 739 cd.resamplebuf = new float[cd.resamplebufSize]; 980 cd.setResampleBufSize(reqSize); 740 981 } 741 982 … … 743 984 size_t outframes = cd.resampler->resample(&cd.accumulator, 744 985 &cd.resamplebuf, 745 s hiftIncrement,986 si, 746 987 1.0 / m_pitchScale, 747 988 last); … … 752 993 753 994 } else { 754 writeOutput(*cd.outbuf, cd.accumulator,755 s hiftIncrement, cd.outCount, theoreticalOut);756 } 757 758 for ( size_t i = 0; i < m_windowSize - shiftIncrement; ++i) {759 cd.accumulator[i] = cd.accumulator[i + shiftIncrement];760 } 761 762 for ( size_t i = m_windowSize - shiftIncrement; i < m_windowSize; ++i) {763 cd.accumulator[i] = 0.0f;764 } 765 766 for ( size_t i = 0; i < m_windowSize - shiftIncrement; ++i) {767 cd.windowAccumulator[i] = cd.windowAccumulator[i + shiftIncrement];768 } 769 770 for ( size_t i = m_windowSize - shiftIncrement; i < m_windowSize; ++i) {771 cd.windowAccumulator[i] = 0.0f;772 } 773 774 if ( cd.accumulatorFill > shiftIncrement) {775 cd.accumulatorFill -= s hiftIncrement;995 writeOutput(*cd.outbuf, accumulator, 996 si, cd.outCount, theoreticalOut); 997 } 998 999 for (i = 0; i < sz - si; ++i) { 1000 accumulator[i] = accumulator[i + si]; 1001 } 1002 1003 for (i = sz - si; i < sz; ++i) { 1004 accumulator[i] = 0.0f; 1005 } 1006 1007 for (i = 0; i < sz - si; ++i) { 1008 windowAccumulator[i] = windowAccumulator[i + si]; 1009 } 1010 1011 for (i = sz - si; i < sz; ++i) { 1012 windowAccumulator[i] = 0.0f; 1013 } 1014 1015 if (int(cd.accumulatorFill) > si) { 1016 cd.accumulatorFill -= si; 776 1017 } else { 777 1018 cd.accumulatorFill = 0; … … 788 1029 RubberBandStretcher::Impl::writeOutput(RingBuffer<float> &to, float *from, size_t qty, size_t &outCount, size_t theoreticalOut) 789 1030 { 1031 Profiler profiler("RubberBandStretcher::Impl::writeOutput"); 1032 790 1033 // In non-RT mode, we don't want to write the first startSkip 791 1034 // samples, because the first chunk is centred on the start of the … … 860 1103 RubberBandStretcher::Impl::available() const 861 1104 { 1105 Profiler profiler("RubberBandStretcher::Impl::available"); 1106 862 1107 if (m_threaded) { 863 1108 MutexLocker locker(&m_threadSetMutex); … … 907 1152 RubberBandStretcher::Impl::retrieve(float *const *output, size_t samples) const 908 1153 { 1154 Profiler profiler("RubberBandStretcher::Impl::retrieve"); 1155 909 1156 size_t got = samples; 910 1157 -
trunk/rubberband/src/Thread.cpp
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 16 16 17 17 #include <iostream> 18 #include <cstdlib> 18 19 19 20 #include <sys/time.h> 20 21 #include <time.h> 21 22 //#define DEBUG_THREAD 123 //#define DEBUG_MUTEX 124 //#define DEBUG_CONDITION 125 22 26 23 using std::cerr; … … 108 105 } 109 106 110 Mutex::Mutex() : 111 m_locked(false) 107 Mutex::Mutex() 108 #ifndef NO_THREAD_CHECKS 109 : 110 m_lockedBy(-1) 111 #endif 112 112 { 113 113 m_mutex = CreateMutex(NULL, FALSE, NULL); … … 128 128 Mutex::lock() 129 129 { 130 if (m_locked) { 130 #ifndef NO_THREAD_CHECKS 131 DWORD tid = GetCurrentThreadId(); 132 if (m_lockedBy == tid) { 131 133 cerr << "ERROR: Deadlock on mutex " << &m_mutex << endl; 132 134 } 133 #ifdef DEBUG_MUTEX 134 cerr << "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Want to lock mutex " << &m_mutex << endl; 135 #endif 136 #ifdef DEBUG_MUTEX 137 cerr << "MUTEX DEBUG: " << (void *)tid << ": Want to lock mutex " << &m_mutex << endl; 135 138 #endif 136 139 WaitForSingleObject(m_mutex, INFINITE); 137 m_locked = true; 138 #ifdef DEBUG_MUTEX 139 cerr << "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Locked mutex " << &m_mutex << endl; 140 #ifndef NO_THREAD_CHECKS 141 m_lockedBy = tid; 142 #endif 143 #ifdef DEBUG_MUTEX 144 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << endl; 140 145 #endif 141 146 } … … 144 149 Mutex::unlock() 145 150 { 146 #ifdef DEBUG_MUTEX 147 cerr << "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Unlocking mutex " << &m_mutex << endl; 148 #endif 149 m_locked = false; 151 #ifndef NO_THREAD_CHECKS 152 DWORD tid = GetCurrentThreadId(); 153 if (m_lockedBy != tid) { 154 cerr << "ERROR: Mutex " << &m_mutex << " not owned by unlocking thread" << endl; 155 return; 156 } 157 #endif 158 #ifdef DEBUG_MUTEX 159 cerr << "MUTEX DEBUG: " << (void *)tid << ": Unlocking mutex " << &m_mutex << endl; 160 #endif 161 #ifndef NO_THREAD_CHECKS 162 m_lockedBy = -1; 163 #endif 150 164 ReleaseMutex(m_mutex); 151 165 } … … 154 168 Mutex::trylock() 155 169 { 170 #ifndef NO_THREAD_CHECKS 171 DWORD tid = GetCurrentThreadId(); 172 #endif 156 173 DWORD result = WaitForSingleObject(m_mutex, 0); 157 174 if (result == WAIT_TIMEOUT || result == WAIT_FAILED) { 158 175 #ifdef DEBUG_MUTEX 159 cerr << "MUTEX DEBUG: " << (void *) GetCurrentThreadId()<< ": Mutex " << &m_mutex << " unavailable" << endl;176 cerr << "MUTEX DEBUG: " << (void *)tid << ": Mutex " << &m_mutex << " unavailable" << endl; 160 177 #endif 161 178 return false; 162 179 } else { 163 m_locked = true; 164 #ifdef DEBUG_MUTEX 165 cerr << "MUTEX DEBUG: " << (void *)GetCurrentThreadId() << ": Locked mutex " << &m_mutex << " (from trylock)" << endl; 180 #ifndef NO_THREAD_CHECKS 181 m_lockedBy = tid; 182 #endif 183 #ifdef DEBUG_MUTEX 184 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << " (from trylock)" << endl; 166 185 #endif 167 186 return true; … … 170 189 171 190 Condition::Condition(string name) : 172 m_name(name),173 191 m_locked(false) 192 #ifdef DEBUG_CONDITION 193 , m_name(name) 194 #endif 174 195 { 175 196 m_mutex = CreateMutex(NULL, FALSE, NULL); … … 344 365 } 345 366 346 Mutex::Mutex() : 367 Mutex::Mutex() 368 #ifndef NO_THREAD_CHECKS 369 : 370 m_lockedBy(0), 347 371 m_locked(false) 372 #endif 348 373 { 349 374 pthread_mutex_init(&m_mutex, 0); … … 364 389 Mutex::lock() 365 390 { 366 if (m_locked) { 391 #ifndef NO_THREAD_CHECKS 392 pthread_t tid = pthread_self(); 393 if (m_locked && m_lockedBy == tid) { 367 394 cerr << "ERROR: Deadlock on mutex " << &m_mutex << endl; 368 395 } 369 #ifdef DEBUG_MUTEX 370 cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Want to lock mutex " << &m_mutex << endl; 396 #endif 397 #ifdef DEBUG_MUTEX 398 cerr << "MUTEX DEBUG: " << (void *)tid << ": Want to lock mutex " << &m_mutex << endl; 371 399 #endif 372 400 pthread_mutex_lock(&m_mutex); 401 #ifndef NO_THREAD_CHECKS 402 m_lockedBy = tid; 373 403 m_locked = true; 374 #ifdef DEBUG_MUTEX 375 cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Locked mutex " << &m_mutex << endl; 404 #endif 405 #ifdef DEBUG_MUTEX 406 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << endl; 376 407 #endif 377 408 } … … 380 411 Mutex::unlock() 381 412 { 382 #ifdef DEBUG_MUTEX 383 cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Unlocking mutex " << &m_mutex << endl; 384 #endif 413 #ifndef NO_THREAD_CHECKS 414 pthread_t tid = pthread_self(); 415 if (!m_locked) { 416 cerr << "ERROR: Mutex " << &m_mutex << " not locked in unlock" << endl; 417 return; 418 } else if (m_lockedBy != tid) { 419 cerr << "ERROR: Mutex " << &m_mutex << " not owned by unlocking thread" << endl; 420 return; 421 } 422 #endif 423 #ifdef DEBUG_MUTEX 424 cerr << "MUTEX DEBUG: " << (void *)tid << ": Unlocking mutex " << &m_mutex << endl; 425 #endif 426 #ifndef NO_THREAD_CHECKS 385 427 m_locked = false; 428 #endif 386 429 pthread_mutex_unlock(&m_mutex); 387 430 } … … 390 433 Mutex::trylock() 391 434 { 435 #ifndef NO_THREAD_CHECKS 436 pthread_t tid = pthread_self(); 437 #endif 392 438 if (pthread_mutex_trylock(&m_mutex)) { 393 439 #ifdef DEBUG_MUTEX 394 cerr << "MUTEX DEBUG: " << (void *) pthread_self()<< ": Mutex " << &m_mutex << " unavailable" << endl;440 cerr << "MUTEX DEBUG: " << (void *)tid << ": Mutex " << &m_mutex << " unavailable" << endl; 395 441 #endif 396 442 return false; 397 443 } else { 444 #ifndef NO_THREAD_CHECKS 445 m_lockedBy = tid; 398 446 m_locked = true; 399 #ifdef DEBUG_MUTEX 400 cerr << "MUTEX DEBUG: " << (void *)pthread_self() << ": Locked mutex " << &m_mutex << " (from trylock)" << endl; 447 #endif 448 #ifdef DEBUG_MUTEX 449 cerr << "MUTEX DEBUG: " << (void *)tid << ": Locked mutex " << &m_mutex << " (from trylock)" << endl; 401 450 #endif 402 451 return true; … … 405 454 406 455 Condition::Condition(string name) : 407 m_locked(false), 408 m_name(name) 456 m_locked(false) 457 #ifdef DEBUG_CONDITION 458 , m_name(name) 459 #endif 409 460 { 410 461 pthread_mutex_init(&m_mutex, 0); -
trunk/rubberband/src/Thread.h
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 23 23 24 24 #include <string> 25 26 //#define DEBUG_THREAD 1 27 //#define DEBUG_MUTEX 1 28 //#define DEBUG_CONDITION 1 25 29 26 30 namespace RubberBand … … 74 78 #ifdef _WIN32 75 79 HANDLE m_mutex; 76 bool m_locked; 80 #ifndef NO_THREAD_CHECKS 81 DWORD m_lockedBy; 82 #endif 77 83 #else 78 84 pthread_mutex_t m_mutex; 85 #ifndef NO_THREAD_CHECKS 86 pthread_t m_lockedBy; 79 87 bool m_locked; 88 #endif 80 89 #endif 81 90 }; … … 114 123 115 124 private: 125 116 126 #ifdef _WIN32 117 127 HANDLE m_mutex; 128 HANDLE m_condition; 118 129 bool m_locked; 119 HANDLE m_condition;120 std::string m_name;121 130 #else 122 131 pthread_mutex_t m_mutex; 132 pthread_cond_t m_condition; 123 133 bool m_locked; 124 pthread_cond_t m_condition; 134 #endif 135 #ifdef DEBUG_CONDITION 125 136 std::string m_name; 126 137 #endif -
trunk/rubberband/src/Window.cpp
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 13 13 */ 14 14 15 #include "AudioCurve.h" 16 17 namespace RubberBand 18 { 19 20 AudioCurve::AudioCurve(size_t sampleRate, size_t windowSize) : 21 m_sampleRate(sampleRate), 22 m_windowSize(windowSize) 23 { 24 } 25 26 AudioCurve::~AudioCurve() 27 { 28 } 15 #include "Window.h" 29 16 30 17 31 } -
trunk/rubberband/src/Window.h
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 18 18 #include <cmath> 19 19 #include <iostream> 20 #include <cstdlib> 20 21 #include <map> 22 23 #include "sysutils.h" 21 24 22 25 namespace RubberBand { … … 41 44 * Construct a windower of the given type. 42 45 */ 43 Window(WindowType type, size_t size) : m_type(type), m_size(size) { encache(); }46 Window(WindowType type, int size) : m_type(type), m_size(size) { encache(); } 44 47 Window(const Window &w) : m_type(w.m_type), m_size(w.m_size) { encache(); } 45 48 Window &operator=(const Window &w) { … … 52 55 virtual ~Window() { delete[] m_cache; } 53 56 54 void cut(T *src) const { cut(src, src); } 55 void cut(T *src, T *dst) const { 56 for (size_t i = 0; i < m_size; ++i) dst[i] = src[i] * m_cache[i]; 57 void cut(T *R__ src) const 58 { 59 const int sz = m_size; 60 for (int i = 0; i < sz; ++i) { 61 src[i] *= m_cache[i]; 62 } 63 } 64 65 void cut(T *R__ src, T *dst) const { 66 const int sz = m_size; 67 for (int i = 0; i < sz; ++i) { 68 dst[i] = src[i]; 69 } 70 for (int i = 0; i < sz; ++i) { 71 dst[i] *= m_cache[i]; 72 } 57 73 } 58 74 59 75 T getArea() { return m_area; } 60 T getValue( size_t i) { return m_cache[i]; }76 T getValue(int i) { return m_cache[i]; } 61 77 62 78 WindowType getType() const { return m_type; } 63 size_t getSize() const { return m_size; }79 int getSize() const { return m_size; } 64 80 65 81 protected: 66 82 WindowType m_type; 67 size_t m_size;68 T * m_cache;83 int m_size; 84 T *R__ m_cache; 69 85 T m_area; 70 86 -
trunk/rubberband/src/sysutils.cpp
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 27 27 28 28 #include <iostream> 29 29 30 30 31 namespace RubberBand { … … 82 83 #ifdef _WIN32 83 84 84 voidgettimeofday(struct timeval *tv, void *tz)85 int gettimeofday(struct timeval *tv, void *tz) 85 86 { 86 87 union { … … 92 93 tv->tv_usec = (long)((now.ns100 / 10LL) % 1000000LL); 93 94 tv->tv_sec = (long)((now.ns100 - 116444736000000000LL) / 10000000LL); 95 return 0; 94 96 } 95 97 … … 101 103 #endif 102 104 105 106 float *allocFloat(float *ptr, int count) 107 { 108 if (ptr) free((void *)ptr); 109 void *allocated; 110 #ifndef _WIN32 111 if (!posix_memalign(&allocated, 16, count * sizeof(float))) 112 #endif 113 allocated = malloc(count * sizeof(float)); 114 for (int i = 0; i < count; ++i) ((float *)allocated)[i] = 0.f; 115 return (float *)allocated; 116 } 117 118 float *allocFloat(int count) 119 { 120 return allocFloat(0, count); 121 } 122 123 void freeFloat(float *ptr) 124 { 125 if (ptr) free(ptr); 126 } 127 128 double *allocDouble(double *ptr, int count) 129 { 130 if (ptr) free((void *)ptr); 131 void *allocated; 132 #ifndef _WIN32 133 if (!posix_memalign(&allocated, 16, count * sizeof(double))) 134 #endif 135 allocated = malloc(count * sizeof(double)); 136 for (int i = 0; i < count; ++i) ((double *)allocated)[i] = 0.f; 137 return (double *)allocated; 138 } 139 140 double *allocDouble(int count) 141 { 142 return allocDouble(0, count); 143 } 144 145 void freeDouble(double *ptr) 146 { 147 if (ptr) free(ptr); 148 } 149 150 103 151 } 104 152 -
trunk/rubberband/src/sysutils.h
r234 r267 4 4 Rubber Band 5 5 An audio time-stretching and pitch-shifting library. 6 Copyright 2007 Chris Cannam.6 Copyright 2007-2008 Chris Cannam. 7 7 8 8 This program is free software; you can redistribute it and/or … … 16 16 #define _RUBBERBAND_SYSINFO_H_ 17 17 18 #ifdef __MSVC__ 19 #include "bsd-3rdparty/float_cast/float_cast.h" 20 #define R__ __restrict 21 #endif 22 23 #ifdef __GNUC__ 24 #define R__ __restrict__ 25 #endif 26 27 #ifndef R__ 28 #define R__ 29 #endif 30 31 #ifdef __MINGW32__ 32 #include <malloc.h> 33 #endif 34 35 #ifdef __MSVC__ 36 #define alloca _alloca 37 #endif 38 18 39 namespace RubberBand { 19 40 … … 21 42 22 43 #ifdef _WIN32 44 23 45 struct timeval { long tv_sec; long tv_usec; }; 24 void gettimeofday(struct timeval *p, void *tz); 46 int gettimeofday(struct timeval *p, void *tz); 47 25 48 void usleep(unsigned long); 49 26 50 #endif 51 52 extern float *allocFloat(int); 53 extern float *allocFloat(float *, int); 54 extern void freeFloat(float *); 55 56 extern double *allocDouble(int); 57 extern double *allocDouble(double *, int); 58 extern void freeDouble(double *); 27 59 28 60 }
