UNPKG

reaper-osc

Version:
361 lines 11.9 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Beat = exports.Transport = void 0; /** * Contains classes for controlling Reaper's transport * @module */ const Notify_1 = require("./Notify"); const Commands_1 = require("./Client/Commands"); const Marker_1 = require("./Marker"); const Region_1 = require("./Region"); /** The Reaper transport */ let Transport = class Transport { /** * @param send A callback used to send typed commands to Reaper */ constructor(send) { this._beat = '1.1.00'; this._frames = '00:00:00:00'; this._isFastForwarding = false; this._isPaused = false; this._isPlaying = false; this._isRecording = false; this._isRepeatEnabled = false; this._isRewinding = false; this._isStopped = false; this._isRewindByMarker = false; this._isSetLoop = false; this._loopEnd = 0; this._loopStart = 0; this._time = 0; this._lastMarker = new Marker_1.LastMarker(); this._lastRegion = new Region_1.LastRegion(); this._send = send; } /** Indicates the current transport beat in format mm.bb.xx */ get beat() { return this._beat; } /** Indicates the current transport from in format h:m:s:f */ get frames() { return this._frames; } /** Indicates whether playback is paused */ get isPaused() { return this._isPaused; } /** Indicates whether playback is active */ get isPlaying() { return this._isPlaying; } /** Indicates whether playback is stopped */ get isStopped() { return this._isStopped; } /** Indicates whether recording is active */ get isRecording() { return this._isRecording; } /** Indicates whether rewind is active */ get isRewinding() { return this._isRewinding; } /** Indicates whether fast-foward is active */ get isFastForwarding() { return this._isFastForwarding; } /** Indicates whether repeat is enabled */ get isRepeatEnabled() { return this._isRepeatEnabled; } /** Indicates whether rewind-to-previous-marker is enabled */ get isRewindByMarker() { return this._isRewindByMarker; } /** Indicates whether the set-loop-points mode is enabled */ get isSetLoop() { return this._isSetLoop; } /** The most recently passed marker */ get lastMarker() { return this._lastMarker; } /** The most recently entered region */ get lastRegion() { return this._lastRegion; } /** Indicates the end time of the loop (in seconds) */ get loopEnd() { return this._loopEnd; } /** Indicates the start time of the loop (in seconds) */ get loopStart() { return this._loopStart; } /** Indicates the current transport time in seconds */ get time() { return this._time; } /** * Handle a typed incoming event * @param event The event to handle */ handleEvent(event) { switch (event.type) { case 'transport:repeat': this._isRepeatEnabled = event.enabled; break; case 'transport:record': this._isRecording = event.recording; break; case 'transport:stop': this._isStopped = event.stopped; break; case 'transport:pause': this._isPaused = event.paused; break; case 'transport:play': this._isPlaying = event.playing; break; case 'transport:rewind': this._isRewinding = event.rewinding; break; case 'transport:fastForward': this._isFastForwarding = event.fastForwarding; break; case 'transport:time': this._time = event.time; break; case 'transport:beat': this._beat = event.beat; break; case 'transport:frames': this._frames = event.frames; break; case 'transport:loopStart': this._loopStart = event.time; break; case 'transport:loopEnd': this._loopEnd = event.time; break; case 'transport:rewindByMarker': this._isRewindByMarker = event.enabled; break; case 'transport:setLoop': this._isSetLoop = event.enabled; break; } this._lastMarker.handleEvent(event); this._lastRegion.handleEvent(event); } /** Jumps to the specified beat (absolute) * @param beat The beat to jump to */ jumpToBeat(beat) { this._send(Commands_1.SetBeat(beat.toString())); } /** Jumps to the specified frame (absolute) * @param frame Frame to jump to (in format h:m:s:f). Values in an invalid format will be ignored by Reaper */ jumpToFrame(frame) { this._send(Commands_1.SetFrames(frame)); } /** Jumps to the specified time in seconds (absolute) * @param time The time to jump to (in seconds). If this value is negative, Reaper will jump to 0 */ jumpToTime(time) { this._send(Commands_1.SetTime(time)); } /** * Jumps to a relative time in seconds. * Note that the absolute value to jump to is calculated by the library based on the currently known time, * as Reaper does not appear to support jumping to a relative time via OSC * @param time The relative time jump (in seconds) */ jumpToTimeRelative(time) { this._send(Commands_1.SetTime(Math.max(this._time + time, 0))); } // eslint-disable-next-line @typescript-eslint/no-unused-vars onPropertyChanged(property, callback) { throw new Error('not implemented'); } /** Toggle pause */ pause() { this._send(Commands_1.Pause()); } /** Toggle play */ play() { this._send(Commands_1.Play()); } /** Toggle recording */ record() { this._send(Commands_1.ToggleRecord()); } /** * Sets the loop end time * @param time End time for the loop (in seconds) */ setLoopEnd(time) { this._send(Commands_1.SetLoopEnd(time)); } /** * Sets the loop start time * @param time Start time for the loop (in seconds) */ setLoopStart(time) { this._send(Commands_1.SetLoopStart(time)); } /** Start fast fowarding. Will continue until stopped */ startFastForwarding() { this._send(Commands_1.SetFastForward(true)); } /** Start rewinding. Will continue until stopped */ startRewinding() { this._send(Commands_1.SetRewind(true)); } /** Stop playback or recording */ stop() { this._send(Commands_1.Stop()); } /** Stop fast forwarding */ stopFastForwarding() { this._send(Commands_1.SetFastForward(false)); } /** Stop rewinding */ stopRewinding() { this._send(Commands_1.SetRewind(false)); } /** Toggle repeat on or off */ toggleRepeat() { this._send(Commands_1.ToggleRepeat()); } /** Toggle rewind-to-previous-marker on or off */ toggleRewindByMarker() { this._send(Commands_1.ToggleRewindByMarker()); } /** Toggle the set-loop-points mode on or off */ toggleSetLoop() { this._send(Commands_1.ToggleSetLoop()); } /** * Jump to the marker with the given user-assigned number (as shown in Reaper's UI). * @param markerNumber The user-assigned marker number to jump to */ gotoMarker(markerNumber) { this._send(Commands_1.GotoMarker(markerNumber)); } /** * Jump to the region with the given user-assigned number (as shown in Reaper's UI). * @param regionNumber The user-assigned region number to jump to */ gotoRegion(regionNumber) { this._send(Commands_1.GotoRegion(regionNumber)); } }; __decorate([ Notify_1.notify('beat') ], Transport.prototype, "_beat", void 0); __decorate([ Notify_1.notify('frames') ], Transport.prototype, "_frames", void 0); __decorate([ Notify_1.notify('isFastForwarding') ], Transport.prototype, "_isFastForwarding", void 0); __decorate([ Notify_1.notify('isPaused') ], Transport.prototype, "_isPaused", void 0); __decorate([ Notify_1.notify('isPlaying') ], Transport.prototype, "_isPlaying", void 0); __decorate([ Notify_1.notify('isRecording') ], Transport.prototype, "_isRecording", void 0); __decorate([ Notify_1.notify('isRepeatEnabled') ], Transport.prototype, "_isRepeatEnabled", void 0); __decorate([ Notify_1.notify('isRewinding') ], Transport.prototype, "_isRewinding", void 0); __decorate([ Notify_1.notify('isStopped') ], Transport.prototype, "_isStopped", void 0); __decorate([ Notify_1.notify('isRewindByMarker') ], Transport.prototype, "_isRewindByMarker", void 0); __decorate([ Notify_1.notify('isSetLoop') ], Transport.prototype, "_isSetLoop", void 0); __decorate([ Notify_1.notify('loopEnd') ], Transport.prototype, "_loopEnd", void 0); __decorate([ Notify_1.notify('loopStart') ], Transport.prototype, "_loopStart", void 0); __decorate([ Notify_1.notify('time') ], Transport.prototype, "_time", void 0); Transport = __decorate([ Notify_1.notifyOnPropertyChanged ], Transport); exports.Transport = Transport; /** Represents a beat value in Reaper */ class Beat { /** * @param measure The measure of the beat * @param beat The beat in the measure * @param fraction The beat fraction (must be >= 0 and < 100) */ constructor(measure, beat, fraction) { if (fraction < 0 || fraction >= 100) { throw new Error(`Invalid fraction ${fraction}, must be >= 0 and < 100`); } this._beat = beat; this._fraction = fraction; this._measure = measure; } /** Indicates the beat portion of the beat (mm) */ get beat() { return this._beat; } /** Indicates the fraction portion of the beat (bb) */ get fraction() { return this._fraction; } /** Indicates the measure of the beat (xx) */ get measure() { return this._measure; } /** * Parses a string into a Beat * @param value String value in the format mm.bb.xx * @returns The parsed beat * @throws Throws an error when the format is invalid */ static parse(value) { const parts = value.split('.'); if (parts.length != 3) { throw new Error('Must be in the format mm.bb.xx'); } const numberParts = []; parts.forEach(element => { const intValue = parseInt(element); numberParts.push(intValue); }); return new Beat(numberParts[0], numberParts[1], numberParts[2]); } /** * Converts the beat into its string representation in the format mm.bb.xx */ toString() { return `${this.measure}.${this.beat}.${this.fraction}`; } } exports.Beat = Beat; //# sourceMappingURL=Transport.js.map