UNPKG

reaper-osc

Version:
400 lines 14.7 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.Track = exports.RecordMonitoringMode = void 0; /** Contains classes for controlling tracks in Reaper * @module */ const Fx_1 = require("./Fx"); const Send_1 = require("./Send"); const Receive_1 = require("./Receive"); const Notify_1 = require("./Notify"); const Events_1 = require("./Client/Events"); const Commands_1 = require("./Client/Commands"); var Events_2 = require("./Client/Events"); Object.defineProperty(exports, "RecordMonitoringMode", { enumerable: true, get: function () { return Events_2.RecordMonitoringMode; } }); /** A Reaper track */ let Track = class Track { /** * @param trackNumber The track's number in the current bank * @param numberOfFx The number of FX per FX bank * @param numberOfSends The number of sends per track * @param numberOfReceives The number of receives per track * @param send A callback used to send typed commands to Reaper */ constructor(trackNumber, numberOfFx, numberOfSends, numberOfReceives, send) { this.trackNumber = trackNumber; this._isMuted = false; this._isRecordArmed = false; this._isSelected = false; this._isSoloed = false; this._name = 'Track' + this.trackNumber; this._pan = 0; this._pan2 = 0; // TODO: Find out what the modes are - should this be an enum value? this._panMode = ''; this._recordMonitoring = Events_1.RecordMonitoringMode.OFF; this._volumeDb = 0; this._volumeFaderPosition = 0; this._vu = 0; this._vuLeft = 0; this._vuRight = 0; this._fx = []; this._sends = []; this._receives = []; this._send = send; for (let i = 0; i < numberOfFx; i++) { this._fx[i] = new Fx_1.TrackFx(trackNumber, i + 1, send); } for (let i = 0; i < numberOfSends; i++) { this._sends[i] = new Send_1.TrackSend(trackNumber, i + 1, send); } for (let i = 0; i < numberOfReceives; i++) { this._receives[i] = new Receive_1.TrackReceive(trackNumber, i + 1, send); } } /** * Deselect the track in the Reaper project. * Note: this affects Reaper's project-level track selection (visible in the UI). * To change which track the OSC device is focused on, use {@link DeviceState.selectTrack} instead. */ deselect() { this._send(Commands_1.SetTrackSelect(this.trackNumber, false)); } /** The track's current FX bank */ get fx() { return this._fx; } /** The track's sends */ get sends() { return this._sends; } /** The track's receives */ get receives() { return this._receives; } /** * Handle a typed incoming event * @param event The event to handle */ handleEvent(event) { switch (event.type) { case 'track:name': if (event.trackNumber === this.trackNumber) this._name = event.name; break; case 'track:mute': if (event.trackNumber === this.trackNumber) this._isMuted = event.muted; break; case 'track:solo': if (event.trackNumber === this.trackNumber) this._isSoloed = event.soloed; break; case 'track:recordArm': if (event.trackNumber === this.trackNumber) this._isRecordArmed = event.armed; break; case 'track:monitoringMode': if (event.trackNumber === this.trackNumber) this._recordMonitoring = event.mode; break; case 'track:select': if (event.trackNumber === this.trackNumber) this._isSelected = event.selected; break; case 'track:pan': if (event.trackNumber === this.trackNumber) this._pan = event.pan; break; case 'track:pan2': if (event.trackNumber === this.trackNumber) this._pan2 = event.pan2; break; case 'track:panMode': if (event.trackNumber === this.trackNumber) this._panMode = event.panMode; break; case 'track:volume': if (event.trackNumber === this.trackNumber) this._volumeFaderPosition = event.volume; break; case 'track:volumeDb': if (event.trackNumber === this.trackNumber) this._volumeDb = event.volumeDb; break; case 'track:vu': if (event.trackNumber === this.trackNumber) this._vu = event.vu; break; case 'track:vuLeft': if (event.trackNumber === this.trackNumber) this._vuLeft = event.vuLeft; break; case 'track:vuRight': if (event.trackNumber === this.trackNumber) this._vuRight = event.vuRight; break; case 'track:fx:name': case 'track:fx:bypass': case 'track:fx:openUi': case 'track:fx:preset': if (event.trackNumber === this.trackNumber) { const fx = this._fx[event.fxNumber - 1]; if (fx) fx.handleEvent(event); } break; case 'track:send:name': case 'track:send:volume': case 'track:send:volumeStr': case 'track:send:pan': case 'track:send:panStr': if (event.trackNumber === this.trackNumber) { const send = this._sends[event.sendNumber - 1]; if (send) send.handleEvent(event); } break; case 'track:recv:name': case 'track:recv:volume': case 'track:recv:volumeStr': case 'track:recv:pan': case 'track:recv:panStr': if (event.trackNumber === this.trackNumber) { const receive = this._receives[event.receiveNumber - 1]; if (receive) receive.handleEvent(event); } break; } } /** Indicates whether the track is muted */ get isMuted() { return this._isMuted; } /** Indicates whether the track is armed for recording */ get isRecordArmed() { return this._isRecordArmed; } /** * Indicates whether the track is selected in the Reaper project. * Note: this reflects Reaper's project-level selection, not the OSC device's focused track. * @see {@link DeviceState.selectTrack} and {@link Reaper.selectedTrack} */ get isSelected() { return this._isSelected; } /** Indicates whether the track is soloed */ get isSoloed() { return this._isSoloed; } /** Mute the track */ mute() { this._send(Commands_1.SetTrackMute(this.trackNumber, true)); } /** The track name */ get name() { return this._name; } // eslint-disable-next-line @typescript-eslint/no-unused-vars onPropertyChanged(property, callback) { throw new Error('not implemented'); } /** A floating-point value between -1 and 1 that indicates the pan position, with -1 being 100% left and 1 being 100% right */ get pan() { return this._pan; } /** A floating-point value between -1 and 1 that indicates the pan 2 position, with -1 being 100% left and 1 being 100% right */ get pan2() { return this._pan2; } /** The current pan mode */ get panMode() { return this._panMode; } /** Arm the track for recording */ recordArm() { this._send(Commands_1.SetTrackRecordArm(this.trackNumber, true)); } /** Indicates the record monitoring mode */ get recordMonitoring() { return this._recordMonitoring; } /** Disarm track recording */ recordDisarm() { this._send(Commands_1.SetTrackRecordArm(this.trackNumber, false)); } /** * Renames the track * @param name The new name of the track * @example * ```typescript * // Change the track name to 'Guitar' * track.rename('Guitar'); * ``` */ rename(name) { this._send(Commands_1.SetTrackName(this.trackNumber, name)); // Reaper will not send a name message in response this._name = name; } /** * Select the track in the Reaper project. * Note: this affects Reaper's project-level track selection (visible in the UI). * To change which track the OSC device is focused on, use {@link DeviceState.selectTrack} instead. */ select() { this._send(Commands_1.SetTrackSelect(this.trackNumber, true)); } /** * Set the record monitoring mode * @param {RecordMonitorMode} value * */ setMonitoringMode(value) { this._send(Commands_1.SetTrackMonitoringMode(this.trackNumber, value)); } /** * Sets the pan * @param value A floating-point value between -1 and 1, where -1 is 100% left and 1 is 100% right */ setPan(value) { if (value < -1 || value > 1) { throw new RangeError('Must be between -1 and 1'); } this._send(Commands_1.SetTrackPan(this.trackNumber, value)); // Reaper won't send a pan message, but will send pan2 when pan changes this._pan = value; } /** * Sets the pan 2 * @param value A floating-point value between -1 and 1, where -1 is 100% left and 1 is 100% right */ setPan2(value) { if (value < -1 || value > 1) { throw new RangeError('Must be between -1 and 1'); } this._send(Commands_1.SetTrackPan2(this.trackNumber, value)); // Reaper won't send a pan2 message, but will send pan when pan2 changes this._pan2 = value; } /** * Sets the volume to a specific dB value. * @param value Value (in dB) to set the volume to. Valid range is -100 to 12. */ setVolumeDb(value) { if (value < -100 || value > 12) { throw new RangeError('Must be between -100 and 12'); } this._send(Commands_1.SetTrackVolumeDb(this.trackNumber, value)); // Reaper does not send OSC message to update this, but does send other volume messages this._volumeDb = value; } /** Sets the volume by moving the fader to a specific position * @param position A value for the fader position between 0 and 1, where 0 is all the way down and 1 is all the way up */ setVolumeFaderPosition(position) { if (position < 0 || position > 1) { throw new RangeError('Must be between 0 and 1'); } this._send(Commands_1.SetTrackVolume(this.trackNumber, position)); // Reaper does not send OSC message to update this, but does send other volume messages this._volumeFaderPosition = position; } /** Solo the track */ solo() { this._send(Commands_1.SetTrackSolo(this.trackNumber, true)); } /** Toggle mute on/off */ toggleMute() { this._send(Commands_1.ToggleTrackMute(this.trackNumber)); } /** Toggle record arm on/off */ toggleRecordArm() { this._send(Commands_1.ToggleTrackRecordArm(this.trackNumber)); } /** Toggle solo on/off */ toggleSolo() { this._send(Commands_1.ToggleTrackSolo(this.trackNumber)); } /** Unmute the track */ unmute() { this._send(Commands_1.SetTrackMute(this.trackNumber, false)); } /** Unsolo the track */ unsolo() { this._send(Commands_1.SetTrackSolo(this.trackNumber, false)); } /** The track volume in dB */ get volumeDb() { return this._volumeDb; } /** A floating-point value between 0 and 1 that indicates the fader position, with 0 being all the way down and 1 being all the way up */ get volumeFaderPosition() { return this._volumeFaderPosition; } /** A floating-point value between 0 and 1 that indicates the VU level */ get vu() { return this._vu; } /** A floating-point value between 0 and 1 that indicates the Left VU level */ get vuLeft() { return this._vuLeft; } /** A floating-point value between 0 and 1 that indicates the Right VU level */ get vuRight() { return this._vuRight; } }; __decorate([ Notify_1.notify('isMuted') ], Track.prototype, "_isMuted", void 0); __decorate([ Notify_1.notify('isRecordArmed') ], Track.prototype, "_isRecordArmed", void 0); __decorate([ Notify_1.notify('isSelected') ], Track.prototype, "_isSelected", void 0); __decorate([ Notify_1.notify('isSoloed') ], Track.prototype, "_isSoloed", void 0); __decorate([ Notify_1.notify('name') ], Track.prototype, "_name", void 0); __decorate([ Notify_1.notify('pan') ], Track.prototype, "_pan", void 0); __decorate([ Notify_1.notify('pan2') ], Track.prototype, "_pan2", void 0); __decorate([ Notify_1.notify('panMode') ], Track.prototype, "_panMode", void 0); __decorate([ Notify_1.notify('recordMonitoring') ], Track.prototype, "_recordMonitoring", void 0); __decorate([ Notify_1.notify('volumeDb') ], Track.prototype, "_volumeDb", void 0); __decorate([ Notify_1.notify('volumeFaderPosition') ], Track.prototype, "_volumeFaderPosition", void 0); __decorate([ Notify_1.notify('vu') ], Track.prototype, "_vu", void 0); __decorate([ Notify_1.notify('vuLeft') ], Track.prototype, "_vuLeft", void 0); __decorate([ Notify_1.notify('vuRight') ], Track.prototype, "_vuRight", void 0); Track = __decorate([ Notify_1.notifyOnPropertyChanged ], Track); exports.Track = Track; //# sourceMappingURL=Tracks.js.map