M bqresample.sig +9 -3
@@ 8,10 8,16 @@ signature BQ_RESAMPLE = sig
type ratio
datatype quality = BEST | FASTEST_TOLERABLE | FASTEST
+ datatype dynamism = RATIO_OFTEN_CHANGING | RATIO_MOSTLY_FIXED
+ datatype ratio_change = SMOOTH_RATIO_CHANGE | SUDDEN_RATIO_CHANGE
- (** Create a new resampler supporting the given number of
- channels. *)
- val new : quality * int -> t
+ (** Create a new resampler with the given quality parameters,
+ supporting the given number of channels. *)
+ val new : { channels : int,
+ quality : quality,
+ dynamism : dynamism,
+ ratio_change : ratio_change
+ } -> t
(** Obtain the number of channels of the given resampler. *)
val channels : t -> int
M ffi/bqresample.sml +18 -8
@@ 13,18 13,28 @@ structure BqResample :>
type ratio = real
datatype quality = BEST | FASTEST_TOLERABLE | FASTEST
+ datatype dynamism = RATIO_OFTEN_CHANGING | RATIO_MOSTLY_FIXED
+ datatype ratio_change = SMOOTH_RATIO_CHANGE | SUDDEN_RATIO_CHANGE
fun new_arr n = RealArray.array (n, 0.0)
val to_vec = _prim "Array_toVector" : RealArray.array -> RealVector.vector;
-
- fun new (quality, channels) =
- let val ffiq = case quality of
- BEST => 2
- | FASTEST_TOLERABLE => 1
- | FASTEST => 0
+
+ fun new { channels, quality, dynamism, ratio_change } =
+ let val ffi_quality = case quality of
+ BEST => 0
+ | FASTEST_TOLERABLE => 1
+ | FASTEST => 2
+ val ffi_dynamism = case dynamism of
+ RATIO_OFTEN_CHANGING => 0
+ | RATIO_MOSTLY_FIXED => 1
+ val ffi_ratioChange = case ratio_change of
+ SMOOTH_RATIO_CHANGE => 0
+ | SUDDEN_RATIO_CHANGE => 1
val resampler = MLton.Finalizable.new
- (bq_resample_new (Int32.fromInt ffiq,
- Int32.fromInt channels))
+ (bq_resample_new (Int32.fromInt channels,
+ Int32.fromInt ffi_quality,
+ Int32.fromInt ffi_dynamism,
+ Int32.fromInt ffi_ratioChange))
val _ = MLton.Finalizable.addFinalizer
(resampler, bq_resample_delete)
in
M ffi/impl-bqresample.cpp +11 -3
@@ 37,15 37,23 @@ extern "C" {
delete rec;
}
- Pointer bq_resample_new(Int32 quality, Int32 channels) {
+ Pointer bq_resample_new(Int32 channels, Int32 quality,
+ Int32 dynamism, Int32 ratioChange) {
try {
resampler_rec *rec = new_resampler_rec();
size_t bufsiz = 10240;
breakfastquay::Resampler::Parameters params;
params.quality =
- (quality == 0 ? breakfastquay::Resampler::Fastest :
- quality == 2 ? breakfastquay::Resampler::Best :
+ (quality == 0 ? breakfastquay::Resampler::Best :
+ quality == 2 ? breakfastquay::Resampler::Fastest :
breakfastquay::Resampler::FastestTolerable);
+ params.dynamism =
+ (dynamism == 0 ? breakfastquay::Resampler::RatioOftenChanging :
+ breakfastquay::Resampler::RatioMostlyFixed);
+ params.ratioChange =
+ (ratioChange == 0 ? breakfastquay::Resampler::SmoothRatioChange :
+ breakfastquay::Resampler::SuddenRatioChange);
+
params.initialSampleRate = 44100; //!!!
params.maxBufferSize = bufsiz;
rec->resampler = new breakfastquay::Resampler(params, channels);
M ffi/import-bqresample.sml +1 -1
@@ 8,7 8,7 @@ structure ImportBqResample = struct
val bq_resample_new =
_import "bq_resample_new" private:
- Int32.int * Int32.int -> resamplehandle;
+ Int32.int * Int32.int * Int32.int * Int32.int -> resamplehandle;
val bq_resample_get_channel_count =
_import "bq_resample_get_channel_count" private:
M sml/bqaudiostream.sml +7 -3
@@ 73,9 73,13 @@ functor BqAudioReadStreamFn (S: READ_STR
stream = #stream t,
read_rate = rate,
ratio = Real.fromInt rate / Real.fromInt (#read_rate t),
- resampler = SOME (BqResample.new
- (BqResample.FASTEST_TOLERABLE,
- channels t))
+ resampler =
+ SOME (BqResample.new
+ { channels = channels t,
+ quality = BqResample.FASTEST_TOLERABLE,
+ dynamism = BqResample.RATIO_MOSTLY_FIXED,
+ ratio_change = BqResample.SUDDEN_RATIO_CHANGE
+ })
}
| err => err
M sml/bqresample.sml +9 -0
@@ 6,6 6,15 @@ structure BqResample
open Resampler
+ (*!!! todo: update bsq-resampler itself with these, after bqresample *)
+ datatype dynamism = RATIO_OFTEN_CHANGING | RATIO_MOSTLY_FIXED
+ datatype ratio_change = SMOOTH_RATIO_CHANGE | SUDDEN_RATIO_CHANGE
+ fun new { channels : int,
+ quality : quality,
+ dynamism : dynamism,
+ ratio_change : ratio_change } =
+ Resampler.new (quality, channels)
+
val set_verbosity = setVerbosity
fun resample_interleaved (t, inbuf, ratio, final) =
M test/test-bqresample.sml +6 -1
@@ 25,7 25,12 @@ structure TestBqResample : TESTS = struc
fn () =>
(* Interpolating a sinusoid should give us a sinusoid,
once we've dropped the first few samples *)
- let val resampler = BqResample.new (BqResample.FASTEST_TOLERABLE, 1)
+ let val resampler = BqResample.new
+ { channels = 1,
+ quality = BqResample.FASTEST_TOLERABLE,
+ dynamism = BqResample.RATIO_MOSTLY_FIXED,
+ ratio_change = BqResample.SUDDEN_RATIO_CHANGE
+ }
val ratio = 2.0
val test_sine = sinusoid (2000, 8.0,
{ frequency = 2.0,