Creating a script to randomly adjust "Note offset" parameter within a given range.

Hi.

I was wondering if any script guru’s could help me make a simple script please? My goal is to be able to select some notes and then have the script randomly adjust the “Note Offset” parameter under the timing and phonemes section positively or negatively within a given range for each note. This is to better simulate different takes for doubled vocals and harmonies. I attempted to do this myself by looking over the manual and using chatgpt but can’t seem to get past script check errors when rescanning the folder.

Any help would be appreciated.

Thank you.

Once I did this:

「いいね!」 4

Ah! That’s probably a helpful starting point.

If I find the parameters you’re adjusting and replace them with the Note Offset parameter I need it should essentially function in the same way yes, just I now have the benefit of a slider for the randomness?

Thanks.

I don’t remember, but isn’t onset and offset the same thing? Notes are connected.
Try it and you will see what it does.

The offset function under timing and phonemes doesn’t actually affect the note’s position, it keeps all notes locked to the grid as they were originally. It only affects the audio playback and the position of the waveforms under the notes when adjusting “Offset”. This is helpful as it’s non destructive to the actual midi notes.

But yes your script does what I’m trying to achieve however, in a manner that shifts the midi from the grid which for the most part is undesirable when going back to projects at a later date.

This is a script I started work on but never finished. It uses the sliders like you wanted, but has a very basic randomizer which may not produce very nice results (linear distribution rather than gaussian distribution like hataori’s).

Actual ADT would have a sort of “drifting” behavior, for example if the base offset were -20ms it might slowly drift between -12ms and -28ms, but it would never go directly from one end of that range to the other like a randomizer would (regardless of the distribution model used). This is the main part that I never got around to implementing (ignoring that actual ADT drift would happen gradually rather than note-by-note).

I’ll paste the in-progress version of the script here, perhaps you can use some combination of the two:

/** ADTOffset.js
 * Offsets the selected notes by a desired amount, ± a random variation.
 * This is a simplified version of ADT (artificial double tracking) using each note's offset setting.
 */
var SCRIPT_TITLE = "ADT Offset";

var DEFAULT_BASE_OFFSET = 0;

var DEFAULT_VARIATION = 0;

function getClientInfo() {
  return {
    "name": SV.T(SCRIPT_TITLE),
    "category": "Claire's Scripts - Automation",
    "author": "claire",
    "versionNumber": 1,
    "minEditorVersion": 65537
  }
}

var form = {
  title: SV.T(SCRIPT_TITLE),
  buttons: 'OkCancel',
  message: 'Notes will be offset by the first number ± a random number between zero and the second number.',
  widgets: [
    {
      name: 'baseOffset',
      type: 'Slider',
      label: SV.T('Base Offset'),
      format: '%1.0fms',
      default: DEFAULT_BASE_OFFSET,
      minValue: -100,
      maxValue: 100,
      interval: 1
    },
    {
      name: 'variation',
      type: 'Slider',
      label: SV.T('Variation'),
      format: '%1.0fms',
      default: DEFAULT_VARIATION,
      minValue: 0,
      maxValue: 100,
      interval: 1
    },
    {
      name: 'offsetPitch',
      type: 'CheckBox',
      text: 'Apply offset to pitch transition',
      default: true
    },
    {
      name: 'offsetPhonemes',
      type: 'CheckBox',
      text: 'Apply offset to phoneme timing',
      default: true
    },
    {
      name: 'keepCurrent',
      type: 'CheckBox',
      text: 'Add offset to existing value instead of zero',
      default: false
    }
  ]
};

function randomVariation(variation) {
  return Math.floor(Math.random() * (variation - (-variation) + 1)) + (-variation);
}

function applyOffset(args) {
  var baseOffset = args.baseOffset;
  var variation = args.variation;

  var selection = SV.getMainEditor().getSelection();
  var selectedNotes = selection.getSelectedNotes();
  if (selectedNotes.length == 0) {
    SV.showMessageBox(SV.T(SCRIPT_TITLE), SV.T('No notes selected.'));
    return;
  }

  for (var i = 0; i < selectedNotes.length; i++) {
    var note = selectedNotes[i];

    offset = (baseOffset + randomVariation(variation)) / 1000;

    if (args.offsetPitch) {
      var pitchOffset = offset;
      if (args.keepCurrent) {
        pitchOffset += note.getAttributes().tF0Offset || 0;
      }

      note.setAttributes({
        tF0Offset: pitchOffset
      });
    }

    if (args.offsetPhonemes) {
      var phonemeOffset = offset;

      if (args.keepCurrent) {
        phonemeOffset += note.getAttributes().tNoteOffset || 0;
      }

      note.setAttributes({
        tNoteOffset: phonemeOffset
      });
    }
  }
}

function main() {
  var result = SV.showCustomDialog(form);
  if (result.status) {
    applyOffset(result.answers);
  }

  SV.finish();
}
「いいね!」 1

Here’s one from a while ago that includes some note offset! I remember it being a work-in-progress, but hopefully it’s enough to get you started

「いいね!」 2