<commit_before>import * as audioContext from 'audio-context';
import * as timestamp from 'unix-timestamp';
import * as getUserMedia from 'getusermedia';
import * as EventEmitter from 'wolfy87-eventemitter';

export const PULSE_EVENT = 'pulse';

export default class extends EventEmitter {
	construct({
		bufferSize = 512,
		numberOfInputChannels = 1,
		numberOfOutputChannels = 1
	}) {
		this.initAudioScriptProcessor( bufferSize, numberOfInputChannels, numberOfOutputChannels );
	}

	getUserMedia() {
		return new Promise((resolve, reject) => {
			getUserMedia({
				audio: true,
				video: false
			}, (err, stream) => {
				if (err) {
					reject("Can't get user media (getUserMedia)");
				}

				resolve(stream);
			});
		})
	}

	start({
		pulseThresholdRms = 0.1,
		minSecondsBetweenPulses = 0.2
	}) {
		this.pulseThresholdRms = pulseThresholdRms;
		this.minSecondsBetweenPulses = minSecondsBetweenPulses;

		this.isFirstPulse = true;
		this.lastPulseTimestamp = 0;

		return new Promise((resolve, reject) => {
			getUserMedia().then((stream) => {
				const microphone = this.audioContext.createMediaStreamSource(stream);

				microphone.connect(this.audioScriptProcessor);

				this.audioScriptProcessor.connect(this.audioContext.destination);

				resolve(() => {
					microphone.disconnect();

					this.audioScriptProcessor.disconnect();
				});

			}).catch((reason) => reject(reason));
		});
	}

	initAudioScriptProcessor(bufferSize, numberOfInputChannels, numberOfOutputChannels) {
		this.audioContext = audioContext;

		this.audioScriptProcessor = this.audioContext.createScriptProcessor(
			bufferSize,
			numberOfInputChannels,
			numberOfOutputChannels
		);

		this.audioScriptProcessor.onaudioprocess = this.handleAudioProcess;
	}

	handleAudioProcess(event) {
		const input = event.inputBuffer.getChannelData( 0 );

		let rms = this.getRms( input );

		if ( ! this.isPulse( rms ) ) {
			return;
		}

		if ( this.isFirstPulse ) {
			this.isFirstPulse = false;

			return;
		}

		let currentPulseTimestamp = timestamp.now();

		let secondsBetweenPulses = currentPulseTimestamp - this.lastPulseTimestamp;
		let rpm = this.calcRPM( secondsBetweenPulses );

		this.lastPulseTimestamp = currentPulseTimestamp;

		this.emitEvent(PULSE_EVENT, {
			'timestamp': currentPulseTimestamp,
			'secondsBetweenPulses': secondsBetweenPulses,
			'rpm': rpm
		});
	}

	calcRPM(secondsBetweenPulses) {
		return Math.floor( 60 / secondsBetweenPulses )
	}

	getRms(inputBuffer) {
		let sum = 0.0;

		inputBuffer.forEach( (data) => {
			sum += data * data;
		} );

		return Math.sqrt( sum / inputBuffer.length );
	}

	isPulse(rms) {
		if ( rms < this.pulseThresholdRms ) {
			return false;
		}

		return timestamp.now() - this.lastPulseTimestamp < this.minSecondsBetweenPulses;
	}

}<commit_msg>Format code, remove newlines and add semicolon<commit_after>import * as audioContext from 'audio-context';
import * as timestamp from 'unix-timestamp';
import * as getUserMedia from 'getusermedia';
import * as EventEmitter from 'wolfy87-eventemitter';

export const PULSE_EVENT = 'pulse';

export default class extends EventEmitter {
	construct({
		bufferSize = 512,
		numberOfInputChannels = 1,
		numberOfOutputChannels = 1
	}) {
		this.initAudioScriptProcessor( bufferSize, numberOfInputChannels, numberOfOutputChannels );
	}

	getUserMedia() {
		return new Promise((resolve, reject) => {
			getUserMedia({
				audio: true,
				video: false
			}, (err, stream) => {
				if (err) {
					reject("Can't get user media (getUserMedia)");
				}

				resolve(stream);
			});
		});
	}

	start({
		pulseThresholdRms = 0.1,
		minSecondsBetweenPulses = 0.2
	}) {
		this.pulseThresholdRms = pulseThresholdRms;
		this.minSecondsBetweenPulses = minSecondsBetweenPulses;

		this.isFirstPulse = true;
		this.lastPulseTimestamp = 0;

		return new Promise((resolve, reject) => {
			getUserMedia().then((stream) => {
				const microphone = this.audioContext.createMediaStreamSource(stream);

				microphone.connect(this.audioScriptProcessor);

				this.audioScriptProcessor.connect(this.audioContext.destination);

				resolve(() => {
					microphone.disconnect();

					this.audioScriptProcessor.disconnect();
				});

			}).catch((reason) => reject(reason));
		});
	}

	initAudioScriptProcessor(bufferSize, numberOfInputChannels, numberOfOutputChannels) {
		this.audioContext = audioContext;

		this.audioScriptProcessor = this.audioContext.createScriptProcessor(
			bufferSize,
			numberOfInputChannels,
			numberOfOutputChannels
		);

		this.audioScriptProcessor.onaudioprocess = this.handleAudioProcess;
	}

	handleAudioProcess(event) {
		const input = event.inputBuffer.getChannelData( 0 );

		let rms = this.getRms( input );

		if ( ! this.isPulse( rms ) ) {
			return;
		}

		if ( this.isFirstPulse ) {
			this.isFirstPulse = false;

			return;
		}

		let currentPulseTimestamp = timestamp.now();

		let secondsBetweenPulses = currentPulseTimestamp - this.lastPulseTimestamp;
		let rpm = this.calcRPM( secondsBetweenPulses );

		this.lastPulseTimestamp = currentPulseTimestamp;

		this.emitEvent(PULSE_EVENT, {
			'timestamp': currentPulseTimestamp,
			'secondsBetweenPulses': secondsBetweenPulses,
			'rpm': rpm
		});
	}

	calcRPM(secondsBetweenPulses) {
		return Math.floor( 60 / secondsBetweenPulses )
	}

	getRms(inputBuffer) {
		let sum = 0.0;

		inputBuffer.forEach( (data) => {
			sum += data * data;
		} );

		return Math.sqrt( sum / inputBuffer.length );
	}

	isPulse(rms) {
		if ( rms < this.pulseThresholdRms ) {
			return false;
		}

		return timestamp.now() - this.lastPulseTimestamp < this.minSecondsBetweenPulses;
	}
}
{'fraction_non_alphanumeric': 0.1157613535173642, 'fraction_numerical': 0.006055209260908282, 'mean_word_length': 4.114754098360656, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 17, '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': '50921', 'n_tokens_mistral': 2136, 'n_tokens_neox': 1772, 'n_words': 338}