<commit_before>function loadAudio(context, file) {
  return new Promise(async (resolve, reject) => {
    let content = await AsyncChrome.files.readBinary(file);
    context.decodeAudioData(content, buffer => resolve(buffer), error => reject(error));
  });
}

function roundUp(value, interval) {
  return interval * Math.ceil(value / interval);
}

class Metronome
{
  constructor(context, buffers, period) {
    this.buffers = buffers;
    this.period = period;
    this.context = context;
    this.interval = null;

    this.scheduledTime = 0;
    this.soundIndex = 0;
  }

  static async create(soundFiles, period) {
    let context = new AudioContext();
    context.suspend();

    let buffers = [];
    for (let file of soundFiles) {
      let buffer = await loadAudio(context, file);
      buffers.push(buffer);
    }

    return new Metronome(context, buffers, period);
  }

  async start() {
    if (!this.context || this.interval) {
      return;
    }

    const schedulePeriod = 1000;
    const scheduleSize = Math.max(2, 2 * (schedulePeriod / this.period));

    const schedule = () => {
      let frontierTime = roundUp(this.context.currentTime * 1000, this.period) + this.period * scheduleSize;
      while (this.scheduledTime < frontierTime) {
        this.scheduledTime += this.period;
        if (this.scheduledTime <= this.context.currentTime * 1000) {
          continue;
        }

        let source = this.context.createBufferSource();
        source.buffer = this.buffers[this.soundIndex];
        this.soundIndex = (this.soundIndex + 1) % this.buffers.length;

        source.connect(this.context.destination);
        source.start(this.scheduledTime / 1000);
      }
    };

    this.interval = setInterval(() => schedule(), schedulePeriod);
    schedule();

    await this.context.resume();
  }
<commit_msg>Only schedule metronome ticks once every 15 seconds.<commit_after>function loadAudio(context, file) {
  return new Promise(async (resolve, reject) => {
    let content = await AsyncChrome.files.readBinary(file);
    context.decodeAudioData(content, buffer => resolve(buffer), error => reject(error));
  });
}

function roundUp(value, interval) {
  return interval * Math.ceil(value / interval);
}

class Metronome
{
  constructor(context, buffers, period) {
    this.buffers = buffers;
    this.period = period;
    this.context = context;
    this.interval = null;

    this.scheduledTime = 0;
    this.soundIndex = 0;
  }

  static async create(soundFiles, period) {
    let context = new AudioContext();
    context.suspend();

    let buffers = [];
    for (let file of soundFiles) {
      let buffer = await loadAudio(context, file);
      buffers.push(buffer);
    }

    return new Metronome(context, buffers, period);
  }

  async start() {
    if (!this.context || this.interval) {
      return;
    }

    const schedulePeriod = 15 * 1000;
    const scheduleSize = Math.max(2, 2 * (schedulePeriod / this.period));

    const schedule = () => {
      let frontierTime = roundUp(this.context.currentTime * 1000, this.period) + this.period * scheduleSize;
      while (this.scheduledTime < frontierTime) {
        this.scheduledTime += this.period;
        if (this.scheduledTime <= this.context.currentTime * 1000) {
          continue;
        }

        let source = this.context.createBufferSource();
        source.buffer = this.buffers[this.soundIndex];
        this.soundIndex = (this.soundIndex + 1) % this.buffers.length;

        source.connect(this.context.destination);
        source.start(this.scheduledTime / 1000);
      }
    };

    this.interval = setInterval(() => schedule(), schedulePeriod);
    schedule();

    await this.context.resume();
  }

{'fraction_non_alphanumeric': 0.12628170534268754, 'fraction_numerical': 0.0124123043712898, 'mean_word_length': 2.9562433297758806, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4476897', 'n_tokens_mistral': 1129, 'n_tokens_neox': 1065, 'n_words': 250}