000d5dda4f36 — Chris Cannam 24 days ago
Merge from default branch
5 files changed, 79 insertions(+), 39 deletions(-)

M README.md
M cross/macos-universal.txt
M cross/macos-x86_64.txt
M meson.build
M rubberband/RubberBandStretcher.h
M README.md +7 -13
@@ 258,17 258,11 @@ this:
 $ meson build --cross-file cross/macos-universal.txt && ninja -C build
 ```
 
-However, the resulting binary will be marked as loadable on macOS 11+
-only, even for Intel, which is probably not what you want (ideally the
-Intel slice would support older versions of the OS). A Makefile that
-handles this explicitly is also provided:
-
-```
-$ make -f otherbuilds/Makefile.macos-universal
-```
-
-This produces only a static library, but it's a universal binary that
-is compatible with macOS 10.7 onwards on the Intel side.
+Note that the universal cross file also sets the minimum OS version to
+the earliest supported macOS versions for both architectures. (Note
+that actual compatibility will also depend on how any dependent
+libraries have been compiled.)  You can edit this in the
+`cross/macos-universal.txt` file if you want a specific target.
 
 See "FFT and resampler selection" below for further build options.
 

          
@@ 284,7 278,7 @@ commercial terms.
 Ensure the Xcode command-line tools are installed, and
 
 ```
-$ meson build_ios --cross-file cross/ios.txt && ninja -C build
+$ meson build_ios --cross-file cross/ios.txt && ninja -C build_ios
 ```
 
 The output files will be found in the `build_ios` directory.

          
@@ 292,7 286,7 @@ The output files will be found in the `b
 To build for the simulator,
 
 ```
-$ meson build_sim --cross-file cross/ios-simulator.txt && ninja -C build
+$ meson build_sim --cross-file cross/ios-simulator.txt && ninja -C build_sim
 ```
 
 The output files will be found in the `build_sim` directory.

          
M cross/macos-universal.txt +3 -3
@@ 14,8 14,8 @@ strip = 'strip'
 pkgconfig = 'pkg-config'
 
 [built-in options]
-c_args = ['-arch', 'arm64', '-arch', 'x86_64']
-cpp_args = ['-arch', 'arm64', '-arch', 'x86_64']
-cpp_link_args = ['-arch', 'arm64', '-arch', 'x86_64']
+c_args = ['-arch', 'arm64', '-arch', 'x86_64', '-mmacosx-version-min=10.7']
+cpp_args = ['-arch', 'arm64', '-arch', 'x86_64', '-stdlib=libc++', '-mmacosx-version-min=10.7']
+cpp_link_args = ['-arch', 'arm64', '-arch', 'x86_64', '-stdlib=libc++', '-mmacosx-version-min=10.7']
 
 

          
M cross/macos-x86_64.txt +2 -2
@@ 15,6 15,6 @@ pkgconfig = 'pkg-config'
 
 [built-in options]
 c_args = ['-arch', 'x86_64']
-cpp_args = ['-arch', 'x86_64']
-cpp_link_args = ['-arch', 'x86_64']
+cpp_args = ['-arch', 'x86_64', '-stdlib=libc++']
+cpp_link_args = ['-arch', 'x86_64', '-stdlib=libc++']
 

          
M meson.build +25 -13
@@ 333,31 333,43 @@ if system == 'darwin'
     '-exported_symbols_list', meson.source_root() / 'vamp/vamp-plugin.list'
   ]
 
-  have_version_min = false
-  foreach arg: get_option('cpp_args')
-    if arg.contains('version-min')
-      have_version_min = true
-    endif
-  endforeach
-
   if architecture == 'aarch64'
     arch_flags += [
       '-arch', 'arm64',
     ]
-    if not have_version_min
-      arch_flags += [ '-mmacosx-version-min=11' ]
-    endif
   elif architecture == 'x86_64'
     arch_flags += [
       '-arch', 'x86_64',
     ]
-    if not have_version_min
-      arch_flags += [ '-mmacosx-version-min=10.13' ]
-    endif
   else # begin architecture != 'aarch64' or 'x86_64'
     error('Build for architecture ' + architecture + ' is not supported on this platform')
   endif # end architecture
 
+  have_version_min = false
+  foreach arg: get_option('cpp_args')
+    if arg.contains('version-min')
+      have_version_min = true
+      bits = arg.split('=')
+      if bits.length() > 1
+	config_summary += { 'Target OS': bits[1] + '+' }
+      else
+	config_summary += { 'Target OS': '(unknown)' }
+      endif
+    endif
+  endforeach
+
+  if not have_version_min
+    message('Using default minimum target OS version')
+    message('(consider specifying this in cross-file if earlier target is desired)')
+    if architecture == 'aarch64'
+      arch_flags += [ '-mmacosx-version-min=11' ]
+      config_summary += { 'Target OS': '11+' }
+    else 
+      arch_flags += [ '-mmacosx-version-min=10.13' ]
+      config_summary += { 'Target OS': '10.13+' }
+    endif
+  endif
+
 elif system == 'windows'
   feature_defines += ['-D_WIN32', '-DNOMINMAX', '-D_USE_MATH_DEFINES', '-DGETOPT_API=']
   if cpp.get_id() == 'msvc'

          
M rubberband/RubberBandStretcher.h +42 -8
@@ 44,7 44,22 @@ 
  * 
  * The Rubber Band API is contained in the single class
  * RubberBand::RubberBandStretcher.
- * 
+ *
+ * The Rubber Band stretcher supports two processing modes, offline
+ * and real-time. The choice of mode is fixed on construction. In
+ * offline mode, you must provide the audio block-by-block in two
+ * passes: in the first pass calling study(), in the second pass
+ * calling process() and receiving the output via retrieve(). In
+ * real-time mode, there is no study pass, just a single streaming
+ * pass in which the audio is passed to process() and output received
+ * via retrieve().
+ *
+ * In real-time mode you can change the time and pitch ratios at any
+ * time, but in offline mode they are fixed and cannot be changed
+ * after the study pass has begun. (However, see setKeyFrameMap() for
+ * a way to do pre-planned variable time stretching in offline mode.)
+ * Offline mode typically produces slightly more precise results.
+ *
  * Threading notes for real-time applications:
  * 
  * Multiple instances of RubberBandStretcher may be created and used

          
@@ 332,11 347,28 @@ public:
 
     /**
      * Construct a time and pitch stretcher object to run at the given
-     * sample rate, with the given number of channels.  Processing
-     * options and the time and pitch scaling ratios may be provided.
-     * The time and pitch ratios may be changed after construction,
-     * but most of the options may not.  See the option documentation
-     * above for more details.
+     * sample rate, with the given number of channels.
+     *
+     * Initial time and pitch scaling ratios and other processing
+     * options may be provided. In particular, the behaviour of the
+     * stretcher depends strongly on whether offline or real-time mode
+     * is selected on construction (via OptionProcessOffline or
+     * OptionProcessRealTime option - offline is the default).
+     * 
+     * In offline mode, you must provide the audio block-by-block in
+     * two passes: in the first pass calling study(), in the second
+     * pass calling process() and receiving the output via
+     * retrieve(). In real-time mode, there is no study pass, just a
+     * single streaming pass in which the audio is passed to process()
+     * and output received via retrieve().
+     *
+     * In real-time mode you can change the time and pitch ratios at
+     * any time, but in offline mode they are fixed and cannot be
+     * changed after the study pass has begun. (However, see
+     * setKeyFrameMap() for a way to do pre-planned variable time
+     * stretching in offline mode.)
+     *
+     * See the option documentation above for more details.
      */
     RubberBandStretcher(size_t sampleRate,
                         size_t channels,

          
@@ 635,8 667,10 @@ public:
 
     /**
      * Obtain some processed output data from the stretcher.  Up to
-     * "samples" samples will be stored in the output arrays (one per
-     * channel for de-interleaved audio data) pointed to by "output".
+     * "samples" samples will be stored in each of the output arrays
+     * (one per channel for de-interleaved audio data) pointed to by
+     * "output".  The number of sample frames available to be
+     * retrieved can be queried beforehand with a call to available().
      * The return value is the actual number of sample frames
      * retrieved.
      *