reaper-osc
Version:
Controls Cockos Reaper using OSC
300 lines • 12.3 kB
JavaScript
"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.RecordMonitoringMode = exports.Track = void 0;
/** Contains classes for controlling tracks in Reaper
* @module
*/
const Fx_1 = require("./Fx");
const Notify_1 = require("./Notify");
const Handlers_1 = require("./Handlers");
const Messages_1 = require("./Messages");
/** 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 sendOscMessage A callback used to send OSC messages to Reaper
*/
constructor(trackNumber, numberOfFx, sendOscMessage) {
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 = RecordMonitoringMode.OFF;
this._volumeDb = 0;
this._volumeFaderPosition = 0;
this._vu = 0;
this._vuLeft = 0;
this._vuRight = 0;
this._fx = [];
this._handlers = [];
this._sendOscMessage = sendOscMessage;
for (let i = 0; i < numberOfFx; i++) {
this._fx[i] = new Fx_1.TrackFx(trackNumber, i + 1, sendOscMessage);
}
this.initHandlers();
}
/** Deselect the track */
deselect() {
this._sendOscMessage(new Messages_1.BooleanMessage(this.oscAddress + '/select', false));
}
/** The track's current FX back */
get fx() {
return this._fx;
}
/** 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*/
get isSelected() {
return this._isSelected;
}
/** Indicates whether the track is soloed */
get isSoloed() {
return this._isSoloed;
}
/** Mute the track */
mute() {
this._sendOscMessage(new Messages_1.BooleanMessage(this.oscAddress + '/mute', 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;
}
/**
* 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;
}
/** Arm the track for recording */
recordArm() {
this._sendOscMessage(new Messages_1.BooleanMessage(this.oscAddress + '/recarm', true));
}
/** Indicates the record monitoring mode */
get recordMonitoring() {
return this._recordMonitoring;
}
/** Disarm track recording */
recordDisarm() {
this._sendOscMessage(new Messages_1.BooleanMessage(this.oscAddress + '/recarm', 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._sendOscMessage(new Messages_1.StringMessage(this.oscAddress + '/name', name));
// Reaper will not send a name message in response
this._name = name;
}
/** Select the track */
select() {
this._sendOscMessage(new Messages_1.BooleanMessage(this.oscAddress + '/select', true));
}
/**
* Set the record monitoring mode
* @param {RecordMonitorMode} value
* */
setMonitoringMode(value) {
this._sendOscMessage(new Messages_1.IntegerMessage(this.oscAddress + '/monitor', 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._sendOscMessage(new Messages_1.FloatMessage(this.oscAddress + '/pan', 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._sendOscMessage(new Messages_1.FloatMessage(this.oscAddress + '/pan2', 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._sendOscMessage(new Messages_1.FloatMessage(this.oscAddress + '/volume/db', 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._sendOscMessage(new Messages_1.FloatMessage(this.oscAddress + '/volume', position));
// Reaper does not send OSC message to update this, but does send other volume messages
this._volumeFaderPosition = position;
}
/** Solo the track */
solo() {
this._sendOscMessage(new Messages_1.BooleanMessage(this.oscAddress + '/solo', true));
}
/** Toggle mute on/off */
toggleMute() {
this._sendOscMessage(new Messages_1.ToggleMessage(this.oscAddress + '/mute'));
}
/** Toggle record arm on/off */
toggleRecordArm() {
this._sendOscMessage(new Messages_1.ToggleMessage(this.oscAddress + '/recarm'));
}
/** Toggle solo on/off */
toggleSolo() {
this._sendOscMessage(new Messages_1.ToggleMessage(this.oscAddress + '/solo'));
}
/** Unmute the track */
unmute() {
this._sendOscMessage(new Messages_1.BooleanMessage(this.oscAddress + '/mute', false));
}
/** Unsolo the track */
unsolo() {
this._sendOscMessage(new Messages_1.BooleanMessage(this.oscAddress + '/solo', 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;
}
initHandlers() {
this._handlers.push(new Handlers_1.StringMessageHandler(this.oscAddress + '/name', value => (this._name = value)), new Handlers_1.BooleanMessageHandler(this.oscAddress + '/mute', value => (this._isMuted = value)), new Handlers_1.BooleanMessageHandler(this.oscAddress + '/solo', value => (this._isSoloed = value)), new Handlers_1.BooleanMessageHandler(this.oscAddress + '/recarm', value => (this._isRecordArmed = value)), new Handlers_1.IntegerMessageHandler(this.oscAddress + '/monitor', value => (this._recordMonitoring = value)), new Handlers_1.BooleanMessageHandler(this.oscAddress + '/select', value => (this._isSelected = value)), new Handlers_1.TrackFxMessageHandler(fxNumber => (this._fx[fxNumber - 1] !== undefined ? this._fx[fxNumber - 1] : null)), new Handlers_1.FloatMessageHandler(this.oscAddress + '/pan', value => (this._pan = value)), new Handlers_1.FloatMessageHandler(this.oscAddress + '/pan2', value => (this._pan2 = value)), new Handlers_1.StringMessageHandler(this.oscAddress + '/panmode', value => (this._panMode = value)), new Handlers_1.FloatMessageHandler(this.oscAddress + '/volume', value => (this._volumeFaderPosition = value)), new Handlers_1.FloatMessageHandler(this.oscAddress + '/volume/db', value => (this._volumeDb = value)), new Handlers_1.FloatMessageHandler(this.oscAddress + '/vu', value => (this._vu = value)), new Handlers_1.FloatMessageHandler(this.oscAddress + '/vu/L', value => (this._vuLeft = value)), new Handlers_1.FloatMessageHandler(this.oscAddress + '/vu/R', value => (this._vuRight = value)));
}
/** The OSC address of the track */
get oscAddress() {
return `/track/${this.trackNumber}`;
}
};
__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;
var RecordMonitoringMode;
(function (RecordMonitoringMode) {
/** Record monitoring disabled */
RecordMonitoringMode[RecordMonitoringMode["OFF"] = 0] = "OFF";
/** Record monitoring enabled */
RecordMonitoringMode[RecordMonitoringMode["ON"] = 1] = "ON";
/** Tape auto style */
RecordMonitoringMode[RecordMonitoringMode["AUTO"] = 2] = "AUTO";
})(RecordMonitoringMode = exports.RecordMonitoringMode || (exports.RecordMonitoringMode = {}));
//# sourceMappingURL=Tracks.js.map