Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MIDI message parsing and encoding to simplify usage #5

Open
GriffinSauce opened this issue Aug 12, 2022 · 0 comments
Open

Add MIDI message parsing and encoding to simplify usage #5

GriffinSauce opened this issue Aug 12, 2022 · 0 comments

Comments

@GriffinSauce
Copy link
Owner

The parsing and encoding should be optional so it's possible to interact with other tooling.

API options

1. Opt-out option per command

Adds a { raw: true } option to all commands to toggle input/output to raw mode.

Pros:

  • Explicit (both in API and data types)
  • Simple by default

Cons

  • Noisy API calls for raw applications
  • Multiple datatypes that are incompatible, potentially within the same application
// By default, MIDI messages are parsed
const globalSettings = await device.getGlobalSettings()
// {
//   type: 'programchange',
//   channel: 1,
//   number: 10,
//   outputs: {
//     midi0: true,
//     flexi1: true,
//     flexi2: true,
//     usb: true,
//   }
// }

// And encoded
device.setGlobalSettings({
  bankMessages: {
    numMessages: 1,
    messages: [{
      type: 'programchange',
      channel: 1,
      number: 10,
      outputs: {
        midi0: true,
        flexi1: true,
        flexi2: true,
        usb: true,
      },
    }],
  },
})

// Optionally, get the raw data
device.getGlobalSettings({ raw: true })
// {
//   statusByte: 'b0',
//   dataByte1: '0',
//   dataByte2: '0',
//   outputs: {
//     midi0: true,
//     flexi1: true,
//     flexi2: true,
//     usb: true,
//   }
// }

// And set raw data
device.setGlobalSettings({
  bankMessages: {
    numMessages: 1,
    messages: [{
      statusByte: 'b0',
      dataByte1: '0',
      dataByte2: '0',
      outputs: {
        midi0: true,
        flexi1: true,
        flexi2: true,
        usb: true,
      },
    }],
  },
}, {
  raw: true
})

2. Merged / automatic

Returns both for any get... commands and takes either format for set...

Pros

  • Easier to deal with

Cons

  • Extra properties in output could still cause incompatibility with other tooling (and the device itself)
  • Added complexity, adding checks, ambiguous types, input validation etc.
const globalSettings = await device.getGlobalSettings()
// {
//   statusByte: 'b0',
//   dataByte1: '0',
//   dataByte2: '0',
//   type: 'programchange',
//   channel: 1,
//   number: 10,
//   outputs: {
//     midi0: true,
//     flexi1: true,
//     flexi2: true,
//     usb: true,
//   }
// }

device.setGlobalSettings({
  bankMessages: {
    numMessages: 1,
    messages: [{
      type: 'programchange',
      channel: 1,
      number: 10,
      statusByte: 'b0',
      dataByte1: '0',
      dataByte2: '0',
      outputs: {
        midi0: true,
        flexi1: true,
        flexi2: true,
        usb: true,
      },
    }],
  },
})

3. External utility

Provide encodeMessages and decodeMessages utilities that process any data to and from the simplified representation.

Pros

  • Easy to integrate later
  • Doesn't complicate communication API

Cons

  • Could add a lot of noise in userland for deeply nested data or needs to be very generic and thus become complex

5. Additional ...Raw commands

The main command names handle simplified data, the ...Raw methods are available as needed.

Pros

  • Everything from 1.
  • Internally simple: the simplified commands compose raw commands with encoding/decoding
  • Somewhat simpler types because it is explicit at a method-level

Cons

  • Everything from 1.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant