UNPKG

reaper-osc

Version:
238 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.Reaper = exports.ConsoleLogger = exports.ReaperConfiguration = void 0; const Tracks_1 = require("./Tracks"); const Transport_1 = require("./Transport"); const ViewPort_1 = require("./ViewPort"); const Device_1 = require("./Device"); const SelectedTrack_1 = require("./SelectedTrack"); const Marker_1 = require("./Marker"); const Region_1 = require("./Region"); const Client_1 = require("./Client/Client"); const Commands_1 = require("./Client/Commands"); const Config_1 = require("./Config"); const Notify_1 = require("./Notify"); // Re-export for backwards compatibility var Config_2 = require("./Config"); Object.defineProperty(exports, "ReaperConfiguration", { enumerable: true, get: function () { return Config_2.ReaperConfiguration; } }); Object.defineProperty(exports, "ConsoleLogger", { enumerable: true, get: function () { return Config_2.ConsoleLogger; } }); /** * Allows control of an instance of Reaper via OSC. * * @example * ```typescript * // Create an instance of Reaper using default settings * const reaper = new Reaper(); * // Start OSC * reaper.startOsc(); * // Give the port a chance to open, then tell Reaper to start playback * setTimeout(() => {reaper.transport.play();}, 100); *``` */ let Reaper = class Reaper { constructor(clientOrConfig, config) { this._isAutoRecordArmEnabled = false; this._isAnySoloed = false; this._isMetronomeEnabled = false; this._markers = []; this._regions = []; this._tracks = []; let resolvedConfig; if (clientOrConfig instanceof Client_1.ReaperOscClient) { this._client = clientOrConfig; resolvedConfig = config !== null && config !== void 0 ? config : new Config_1.ReaperConfiguration(); } else { resolvedConfig = clientOrConfig !== null && clientOrConfig !== void 0 ? clientOrConfig : new Config_1.ReaperConfiguration(); this._client = new Client_1.ReaperOscClient(resolvedConfig); } this._afterMessageReceived = resolvedConfig.afterMessageReceived; const send = (command) => this._client.send(command); this._device = new Device_1.DeviceState(send); this._transport = new Transport_1.Transport(send); this._viewport = new ViewPort_1.ViewPort(send); this._selectedTrack = new SelectedTrack_1.SelectedTrack(resolvedConfig.numberOfFx, resolvedConfig.numberOfSends, resolvedConfig.numberOfReceives, send); this._masterTrack = new Tracks_1.Track(0, resolvedConfig.numberOfFx, resolvedConfig.numberOfSends, resolvedConfig.numberOfReceives, send); for (let i = 0; i < resolvedConfig.numberOfTracks; i++) { this._tracks[i] = new Tracks_1.Track(i + 1, resolvedConfig.numberOfFx, resolvedConfig.numberOfSends, resolvedConfig.numberOfReceives, send); } for (let i = 0; i < resolvedConfig.numberOfMarkers; i++) { this._markers[i] = new Marker_1.Marker(i + 1, send); } for (let i = 0; i < resolvedConfig.numberOfRegions; i++) { this._regions[i] = new Region_1.Region(i + 1, send); } // Track whether the last parsed event was known (for afterMessageReceived) let lastEventWasKnown = false; this._client.on('message', event => { var _a, _b, _c; lastEventWasKnown = event.type !== 'unknown'; switch (event.type) { case 'metronome': this._isMetronomeEnabled = event.enabled; break; case 'autoRecordArm': this._isAutoRecordArmEnabled = event.enabled; break; case 'anySolo': this._isAnySoloed = event.active; break; } this._transport.handleEvent(event); this._selectedTrack.handleEvent(event); if ('trackNumber' in event) { const trackNumber = event.trackNumber; if (trackNumber === 0) { this._masterTrack.handleEvent(event); } else { (_a = this._tracks[trackNumber - 1]) === null || _a === void 0 ? void 0 : _a.handleEvent(event); } } if (event.type === 'marker:name' || event.type === 'marker:number' || event.type === 'marker:time') { (_b = this._markers[event.slotIndex - 1]) === null || _b === void 0 ? void 0 : _b.handleEvent(event); } if (event.type === 'region:name' || event.type === 'region:number' || event.type === 'region:time' || event.type === 'region:length') { (_c = this._regions[event.slotIndex - 1]) === null || _c === void 0 ? void 0 : _c.handleEvent(event); } }); this._client.on('rawMessage', message => { if (this._afterMessageReceived !== null) { this._afterMessageReceived(message, lastEventWasKnown); } }); } /** The underlying stateless OSC client */ get client() { return this._client; } /** Controls the OSC device's navigation state (track/bank/FX selection) */ get device() { return this._device; } /** Indicates whether auto-record-arm is enabled */ get isAutoRecordArmEnabled() { return this._isAutoRecordArmEnabled; } /** Indicates whether any track is soloed */ get isAnySoloed() { return this._isAnySoloed; } /** Indicates whether the metronome is enabled */ get isMetronomeEnabled() { return this._isMetronomeEnabled; } /** Indicates whether OSC is ready to send and receive messages */ get isReady() { return this._client.isReady; } /** The master track */ get master() { return this._masterTrack; } /** The current bank of markers */ get markers() { return this._markers; } /** The current bank of regions */ get regions() { return this._regions; } // eslint-disable-next-line @typescript-eslint/no-unused-vars onPropertyChanged(property, callback) { throw new Error('not implemented'); } /** * Triggers the action `Control surface: Refresh all surfaces` (Command ID: 41743) */ refreshControlSurfaces() { this.triggerAction(41743); } /** * Send a message to Reaper via OSC. Messages may not be sent while {@link Reaper.isReady} is false. * @param message The OSC message to be sent */ sendOscMessage(message) { this._client.sendRaw(message); } /** Open the OSC port and start listening for messages */ async start() { return this._client.start(); } /** Stop listening for OSC messages */ async stop() { return this._client.stop(); } /** Toggle auto-record-arm on or off */ toggleAutoRecordArm() { this._client.send(Commands_1.ToggleAutoRecordArm()); } /** Toggle the metronome on or off */ toggleMetronome() { this._client.send(Commands_1.ToggleMetronome()); } /** Reset all solos */ soloReset() { this._client.send(Commands_1.ResetSolos()); } /** * The OSC device's currently focused track. * State is populated by the sync burst Reaper sends when the focused track changes. * @see {@link DeviceState.selectTrack} */ get selectedTrack() { return this._selectedTrack; } /** The current bank of tracks */ get tracks() { return this._tracks; } /** Transport controls */ get transport() { return this._transport; } /** Arrange-view scroll and zoom controls */ get viewport() { return this._viewport; } /** * Trigger a Reaper action * @param commandId The Command ID of the action to be triggered. * @param value The value to send for the action. Note that some actions expect the CC value (0-127) while others expect a decimal value between 0 and 1. * @example * ```typescript * // Trigger action 'Track: Toggle mute for master track' * reaper.triggerAction(14); * // Trigger SWS Extension action 'SWS/S&M: Live Config #1 - Apply config (MIDI/OSC only)' with a CC value of 3, selects config #3 * reaper.triggerAction('_S&M_LIVECFG_APPLY1', 3); * // Trigger action 'Track: Set volume for track 01 (MIDI CC/OSC only)' with a value of 0.75, sets volume of track 1 to +0.0dB * reaper.triggerAction(20, 0.7156) * ``` */ triggerAction(commandId, value = null) { if (value !== null && (value < 0 || value > 127)) { throw new RangeError('Values must be between 0 and 127 inclusive'); } this._client.send(Commands_1.TriggerAction(commandId, value !== null && value !== void 0 ? value : undefined)); } }; __decorate([ Notify_1.notify('isAutoRecordArmEnabled') ], Reaper.prototype, "_isAutoRecordArmEnabled", void 0); __decorate([ Notify_1.notify('isAnySoloed') ], Reaper.prototype, "_isAnySoloed", void 0); __decorate([ Notify_1.notify('isMetronomeEnabled') ], Reaper.prototype, "_isMetronomeEnabled", void 0); Reaper = __decorate([ Notify_1.notifyOnPropertyChanged ], Reaper); exports.Reaper = Reaper; //# sourceMappingURL=Reaper.js.map