setPitch method
Sets the relative pitch of the Player. Defaults to 1.0
.
Implementation
@override
Future<void> setPitch(double pitch, {bool synchronized = true}) {
Future<void> function() async {
if (disposed) {
throw AssertionError('[Player] has been disposed');
}
await waitForPlayerInitialization;
await waitForVideoControllerInitializationIfAttached;
if (configuration.pitch) {
if (pitch <= 0.0) {
throw ArgumentError.value(
pitch,
'pitch',
'Must be greater than 0.0',
);
}
// Pitch shift control is enabled.
state = state.copyWith(
pitch: pitch,
);
if (!pitchController.isClosed) {
pitchController.add(state.pitch);
}
// Apparently, using scaletempo:scale actually controls the playback rate as intended after setting audio-pitch-correction as FALSE.
// speed on the other hand, changes the pitch when audio-pitch-correction is set to FALSE.
// Since, it also alters the actual [speed], the scaletempo:scale is divided by the same value of [pitch] to compensate the speed change.
var name = 'audio-pitch-correction'.toNativeUtf8();
final no = 'no'.toNativeUtf8();
mpv.mpv_set_property_string(
ctx,
name.cast(),
no.cast(),
);
calloc.free(name);
calloc.free(no);
name = 'speed'.toNativeUtf8();
final speed = calloc<Double>()..value = pitch;
mpv.mpv_set_property(
ctx,
name.cast(),
generated.mpv_format.MPV_FORMAT_DOUBLE,
speed.cast(),
);
calloc.free(name);
calloc.free(speed);
name = 'af'.toNativeUtf8();
// Divide by [state.pitch] to compensate the speed change caused by pitch shift.
final value =
'scaletempo:scale=${(state.rate / state.pitch).toStringAsFixed(8)}'
.toNativeUtf8();
mpv.mpv_set_property_string(
ctx,
name.cast(),
value.cast(),
);
calloc.free(name);
calloc.free(value);
} else {
// Pitch shift control is disabled.
throw ArgumentError('[PlayerConfiguration.pitch] is false');
}
}
if (synchronized) {
return lock.synchronized(function);
} else {
return function();
}
}