UNPKG

reaper-osc

Version:
278 lines 10 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 Handlers_1 = require("./Handlers"); const Messages_1 = require("./Messages"); /** The Reaper transport */ let Transport = class Transport { /** * @param sendOscMessage A callback used to send OSC messages to Reaper */ constructor(sendOscMessage) { this._beat = '1.1.00'; this._frames = '00:00:00:00'; this._isFastForwarding = false; this._isPlaying = false; this._isRecording = false; this._isRepeatEnabled = false; this._isRewinding = false; this._isStopped = false; this._loopEnd = 0; this._loopStart = 0; this._time = 0; this._handlers = [ new Handlers_1.BooleanMessageHandler('/repeat', value => (this._isRepeatEnabled = value)), new Handlers_1.BooleanMessageHandler('/record', value => (this._isRecording = value)), new Handlers_1.BooleanMessageHandler('/stop', value => (this._isStopped = value)), new Handlers_1.BooleanMessageHandler('/play', value => (this._isPlaying = value)), new Handlers_1.BooleanMessageHandler('/rewind', value => (this._isRewinding = value)), new Handlers_1.BooleanMessageHandler('/forward', value => (this._isFastForwarding = value)), new Handlers_1.FloatMessageHandler('/time', value => (this._time = value)), new Handlers_1.StringMessageHandler('/beat/str', value => (this._beat = value)), new Handlers_1.StringMessageHandler('/frames/str', value => (this._frames = value)), new Handlers_1.FloatMessageHandler('/loop/start/time', value => (this._loopStart = value)), new Handlers_1.FloatMessageHandler('/loop/end/time', value => (this._loopEnd = value)) ]; this._sendOscMessage = sendOscMessage; } /** 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 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 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; } /** Jumps to the specified beat (absolute) * @param beat The beat to jump to */ jumpToBeat(beat) { this._sendOscMessage(new Messages_1.StringMessage('/beat/str', 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._sendOscMessage(new Messages_1.StringMessage('/frames/str', 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._sendOscMessage(new Messages_1.FloatMessage('/time', 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) { const newTime = Math.max(this._time + time, 0); this._sendOscMessage(new Messages_1.FloatMessage('/time', newTime)); } // eslint-disable-next-line @typescript-eslint/no-unused-vars onPropertyChanged(property, callback) { throw new Error('not implemented'); } /** Toggle pause */ pause() { this._sendOscMessage(new Messages_1.OscMessage('/pause')); } /** Toggle play */ play() { this._sendOscMessage(new Messages_1.OscMessage('/play')); } /** * Receive and handle an OSC message * @param message The message to be handled */ receive(message) { for (const handler of this._handlers) { if (handler.handle(message)) { return true; } } return false; } /** Toggle recording */ record() { this._sendOscMessage(new Messages_1.OscMessage('/record')); } /** * Sets the loop end time * @param time End time for the loop (in seconds) */ setLoopEnd(time) { this._sendOscMessage(new Messages_1.FloatMessage('/loop/end/time', time)); } /** * Sets the loop start time * @param time Start time for the loop (in seconds) */ setLoopStart(time) { this._sendOscMessage(new Messages_1.FloatMessage('/loop/start/time', time)); } /** Start fast fowarding. Will continue until stopped */ startFastForwarding() { this._sendOscMessage(new Messages_1.BooleanMessage('/forward', true)); } /** Start rewinding. Will continue until stopped */ startRewinding() { this._sendOscMessage(new Messages_1.BooleanMessage('/rewind', true)); } /** Stop playback or recording */ stop() { this._sendOscMessage(new Messages_1.OscMessage('/stop')); } /** Stop fast forwarding */ stopFastForwarding() { this._sendOscMessage(new Messages_1.BooleanMessage('/forward', false)); } /** Stop rewinding */ stopRewinding() { this._sendOscMessage(new Messages_1.BooleanMessage('/rewind', false)); } /** Toggle repeat on or off */ toggleRepeat() { this._sendOscMessage(new Messages_1.OscMessage('/repeat')); } }; __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('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('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