setPitch method

  1. @override
Future<void> setPitch(
  1. double pitch, {
  2. bool synchronized = true,
})
override

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();
  }
}