diff --git a/readme.md b/readme.md index 3cd0c12..5e0fe3b 100644 --- a/readme.md +++ b/readme.md @@ -100,7 +100,10 @@ const sACNServer = new Sender({ async function main() { await sACNServer.send({ - payload: { // required. object with the percentages for each DMX channel + payload: { + // Required. An object with the percentages (0-100) for each DMX channel. + // You can use 0-255 instead of 0-100 by setting `useRawDmxValues: true` + // per packet, or in the `defaultPacketOptions`. 1: 100, 2: 50, 3: 0, @@ -113,7 +116,6 @@ async function main() { } main(); // wrapped in a main() function so that we can `await` the promise - ``` ### Table 3 - Options for Sender @@ -123,7 +125,7 @@ main(); // wrapped in a main() function so that we can `await` the promise | `universe` | `number` | Required. The universes to listen to. Must be within 1-63999 | `[]` | | `port` | `number` | Optional. The multicast port to use. All professional consoles broadcast to the default port. | `5568` | | `reuseAddr` | `boolean` | Optional. Allow multiple programs on your computer to send to the same sACN universe. | -| `defaultPacketOptions` | `object` | Optional. You can specify options like `sourceName`, `cid`, and `priority` here instead of on every packet | +| `defaultPacketOptions` | `object` | Optional. You can specify options like `sourceName`, `cid`, `priority` and `useRawDmxValues` here instead of on every packet | | `iface` | `string` | Optional. Specifies the IPv4 address of the network interface/card to use. | OS default interface (=active internet connection) | `useUnicastDestination`| `string` | Optional. Setting this attribute to an IPv4 address will cause data to be sent directly to that device, instead of broadcasting to the whole LAN. | @@ -147,6 +149,7 @@ The Architecture for Control Networks (ACN) and derived protocols are created by - RDMNet is defined in [ANSI E1.33](./docs/E1.33-2019.pdf) --- + 1­. Unicast is also supported by default, but this is not how sACN normally works. See [_Table 3_](#table-3---options-for-sender) for how to send data directly to a unicast address. [↩](#footnote-source1) diff --git a/src/packet.ts b/src/packet.ts index b95d745..93db168 100644 --- a/src/packet.ts +++ b/src/packet.ts @@ -19,6 +19,12 @@ export interface Options { sourceName?: Packet['sourceName']; priority?: Packet['priority']; cid?: Packet['cid']; + /** + * Whether to use 0-100 or 0-255 scale when creating the packet + * - `false` (default): 0-100 + * - `true`: 0-255 + */ + useRawDmxValues?: Packet['useRawDmxValues']; } /** @@ -58,6 +64,8 @@ export class Packet { /* eslint-enable lines-between-class-members */ + private readonly useRawDmxValues: boolean = false; + public constructor( input: Buffer | Options, public readonly sourceAddress?: string, @@ -121,6 +129,10 @@ export class Packet { this.propertyValueCount = 0x0201; // "Indicates 1+ the number of slots in packet" // We set the highest possible value (1+512) so that channels with zero values are // treated as deliberately 0 (cf. undefined) + + if (options.useRawDmxValues) { + this.useRawDmxValues = true; + } } } @@ -168,7 +180,11 @@ export class Packet { for (const ch in this.payload) { if (+ch >= 1 && +ch <= 512) { - n[125 + +ch] = inRange(this.payload[ch]! * 2.55); + if (this.useRawDmxValues) { + n[125 + +ch] = inRange(this.payload[ch]!); + } else { + n[125 + +ch] = inRange(this.payload[ch]! * 2.55); + } } } diff --git a/src/sender.ts b/src/sender.ts index 5136344..d9a652f 100644 --- a/src/sender.ts +++ b/src/sender.ts @@ -16,7 +16,10 @@ export interface SenderProps { minRefreshRate?: number; /** some options can be sepecified when you instantiate the sender, instead of sepecifying them on every packet */ - defaultPacketOptions?: Pick; + defaultPacketOptions?: Pick< + Options, + 'cid' | 'sourceName' | 'priority' | 'useRawDmxValues' + >; // IPv4 address of the network interface iface?: string; diff --git a/test/packet.test.ts b/test/packet.test.ts index 750cefa..5008342 100644 --- a/test/packet.test.ts +++ b/test/packet.test.ts @@ -59,4 +59,29 @@ describe('Simple Packet', () => { // double wrapped so that it converts to buffer and back assert.deepStrictEqual(new Packet(packet.buffer).payload, {}); }); + + it('correctly sets channel values from the [0-100] range', () => { + const packet = new Packet({ + universe: 1, + payload: { 1: 91.76, 2: 100, 4: 100 }, + sequence: 172, + }); + assert.deepStrictEqual( + packet.buffer.slice(126, 130), // first 4 channel values + Buffer.from([0xea, 0xff, 0, 0xff]), + ); + }); + + it('correctly sets channel values from the [0-255] range', () => { + const packet = new Packet({ + universe: 1, + payload: { 1: 234, 2: 255, 4: 255 }, + sequence: 172, + useRawDmxValues: true, + }); + assert.deepStrictEqual( + packet.buffer.slice(126, 130), // first 4 channel values + Buffer.from([0xea, 0xff, 0, 0xff]), + ); + }); });