solidsnake745 / midi_device_controller Goto Github PK
View Code? Open in Web Editor NEWAn Arduino based library for controlling various devices via the MIDI interface
License: GNU General Public License v3.0
An Arduino based library for controlling various devices via the MIDI interface
License: GNU General Public License v3.0
Don't want users to control ID assignment as the library now relies on index positions as the unique "ID". Refactor ID concept so that it's not publicly available and is set when adding a device to MIDIDevice_Controller.
Currently all of the device chain classes exist in a single file. Want to separate into one file per class.
Want to encapsulate functionality around parsing serial data from Hairless MIDI into MIDI messages for consumption through this framework.
Create a singleton instance for hairless MIDI data similar to usbMIDI for Teensy.
Create similar methods to:
Low on priority, but including the MIDI_Collection_Controller header file automatically creates and instantiates its singleton instance; even if the consumer isn't really using it.
To reduce memory footprint and allow consumers to knowingly opt into it's functionality, I want to refactor the instantiation into an initialize method.
Ran into a couple issues after using MIDI_Shift_Register in real time - Wasn't properly stopping notes.
Also noticing some improvements that need to be made:
In order to better group, understand, and maintain where settings from Settings.h are being consumed, want to move those sets into their relevant constructors. May later on make them constructor arguments, but for not entirely sure that's necessary.
Classes currently consuming settings:
Updating name scheme around note assignment to better convey what it represents to consumers.
Will make it easier for them to understand what this does in the domain.
Current | New |
---|---|
assignNote | playNote |
clearNote | stopNote |
While working on the latest PCB prototype, ran into an issue while trying to use device chains.
Had forgotten that while passing arrays to methods they are passed by pointer and therefore using sizeof on it results in just the size of the pointer; not the total size of the array. Using a parameter pack is actually easier for consumers too as they can simply concatenate as many desired IDs as they like. The method is already setup to handle bad inputs and continue you on so it should work fine.
Creating a class to represent a device for drums. Encapsulates a chain of solenoids and utilizes the SPI bus.
Add a method specifically for creating a piezo device for simplicity/clarity. Have been using createHDD to achieve this as they are functionality identical.
Updating naming scheme around note processing to better convey what it represents to consumers.
Will make it easier for them to understand what this does in the domain.
Current | New |
---|---|
_isProcessing | _isPlayingNotes |
_autoProcessing | _autoPlayNotes |
setAutoProcess | setAutoPlay |
startProcessing | startPlaying |
stopProcessing | stopPlaying |
resetProcessing | *process |
isProcessing | isPlayingNotes |
*Changing to encompass all running all relevant processes rather than just handling stopping the interrupt process. Also better follows other Arduino library implementations of this concept.
Having used it couple times, would be simpler to just be able to add devices to the collection instances with an assignment strategy; rather than making the user create the objects, assign them to the MIDI_Device_Controller, and THEN configure the different chains,
Want something along the lines of creating collections by passing in device references (straight from factory creation) and then assignment strategy. Can probably reuse recursive decay from MIDI_Collection_Controller to do this.
I'm really fond of Doxygen documentation and want to use it to document my library. Documentation is important to give users a clean overview of available functionality.
Want to rename MIDI chains to collections as it is easier to understand.
Current naming scheme:
MIDI_ | {1} | *_{2} |
---|---|---|
Standard prefix | Class or subclass name/desc | Final class name/desc (*optional) |
Current | New |
---|---|
MIDI_Chain_Controller | MIDI_Collection_Controller |
MIDI_Chain_Factory | MIDI_Collection_Factory |
MIDI_Device_Chain | Base_MIDI_Device_Collection |
Direct_Chain | *Direct_Collection |
FirstAvailable_Chain | *FirstAvailable_Collection |
RoundRobin_Chain | *RoundRobin_Collection |
*Temporary naming, doesn't entirely fit well, come back and review
Was broken in the shift from using primitive arrays to class objects to represent devices. Need to update so it works with the new device object class approach.
In the past, found the Arduino Uno/Duemilanove was not fast enough to bend entire channels (OK for single device bends). This test function is mainly for confirming if the controller is fast enough to do pitch bending for an entire channel.
This will probably end up getting refactored into device chains.
Want to simplify use of this library by including classes that encapsulate configuration and processing of MIDI events from different frameworks.
Thinking they will share two common methods, but with different parameters depending on case:
Use cases in mind currently:
This check prevents compilation for the Arduino boards (Uno and Nano tested). Removing in order restore functionality.
This will be handled by device chains later.
Forgot to wrap numerous string objects in the F() macro to reduce memory usage. Need to go back and fix this.
After #7, want to add a functional and some sort of load test to allow testing of pitch bending capability. First test confirms pitch bending is working normally while the load test confirms efficiency.
Continuation of #8 - Create a controller meant to manage device chains. Will allow for easily grouping devices to allow for pooling/distributing notes per some configured strategy. Current strategies are direct, stacking, and round robin. Very similarly structured to MIDI_DeviceController (singleton instance, allows for adding/removing device chains).
There's no need for devices to have unique IDs. There isn't really an advantage over just associating devices to their position in the MIDI device controller collection (array). Refactor out to reduce complexity and optimize device referencing.
It's bothering me. A lot. Every day. Every second. Make it stop.
Deciding to separate out device chain functionality. It's able to stand by itself for now so want to reduce dependencies by refactoring into it's own library. Most likely to be called DeviceChainController.
This issue just covers removing it from this repo/library.
Checked in a very simple description of the library as the readme for now.
Want to update it with more details about the library, it's use, and key concepts.
Created the keywords file a long time ago before a lot of the final code was written. Need to go back and update keywords and decide what type of keyword they are. This causes key terms to be highlighted in the Arduino IDE.
Want to restructure the shift register implementation so it's more decoupled from note assignment. Also want to be able to re-use some of its mechanisms in other implementations such as MCP23017 and MCP23S17. Will create another controller to manage note to interface + output mappings: MIDI_Pulse_Controller.
As a means to ensure the original requirements are still functioning, I have a test sketch that configures a (Teensy) microcontroller as a MIDI FDD Controller. Once updated with the latest changes from adding in DeviceChain_Controller, this stopped working properly. Need to update and add logging to trace where the issue is occurring. Could be a simple logic oversight, but currently there is no way to confirm as logging in DeviceChain_Controller is broken.
First version of logging using compiler macros still in use. Update to use SerialDebug instead.
Had previously made two classes around parsing MIDI messages into an object and then executing callbacks based on those messages, Want to update and include those classes to address the use cases outlined in #9.
Majority of the implementation is written, tested, and done. Want to move it into the Arduino library system so it's ready to be made available to consumers.
Follow specification outlined: https://arduino.github.io/arduino-cli/library-specification/
Now that consumers only need to include a single header, want to place more of the files within sub-folders. At the same time, want to create an MDC_Extras file for controlling which add ons are included.
Recently discovered pitch bending was broken while working on intro course.
Issue occurring was all pitch bend commands would sound wrong - resulting note after bending was far too high. For the notes tested with, the bend values should have resulted in lower tones - not higher; suggesting the bend value used was larger than expected.
After researching further, looks like there were two separate paths of failure that can be fixed with one change.
To summarize:
For now, addressing only the need to shift the new values into the expected range to fix existing functionality for my own instruments. Need to address the issue with Hairless MIDI in #30.
Same concept as #22 but for device chains essentially.
Current device chain types:
Looking over the naming scheme again, would be more straight forward to correlate device names to output types. With that in mind, want to update the following:
Current | Desired |
---|---|
MIDI_Device | MIDI_Pitch |
(TODO: Create this device) | MIDI_Pulse |
MIDI_Shift_Register | MIDI_Shift_Register |
Need to apply change to multiple files/places:
Current | New |
---|---|
MIDI_Device | MIDI_Pitch |
Base_MIDI_Device_Collection | Base_MIDI_Pitch_Device_Collection |
-addDevice | addPitchDevice |
-addDevices | addPitchDevices |
-removeDevice | removePitchDevice |
MIDI_Device_Node | MIDI_Pitch_Node |
MIDI_Device_Controller | MIDI_Device_Controller (NO NAME CHANGE) |
-_devices | _pitchDevices |
-_enabledDevices | _enabledPitchDevices |
-reloadEnabledDevices | reloadEnabledPitchDevices |
-addDevice | addPitchDevice |
-addDevices | addPitchDevices |
-getDevice | getPitchDevice |
-deleteDevice | deletePitchDevice |
-resetPositions | resetPitchDevicePositions |
-calibratePositions | calibratePitchDevicePositions |
-playNote | playPitchNote |
-pitchBend | bendPitchNote |
-stopNote | stopPitchNote |
-getMaxDevices | getMaxPitchDevices |
-testDeviceInterrupt | testPitchDeviceInterrupt |
MIDI_Collection_Controller | MIDI_Pitch_Collection_Controller |
MIDI_Device_Factory | MIDI_Device_Factory (NO NAME CHANGE) |
MAX_DEVICES | MAX_PITCH_DEVICES |
Having the ability to configure a collection (array) of devices will simplify making configurations for various use cases/scenarios and is fairly simple to do before further designing #9.
Need to separate and centralize MIDI_Device instantiation methods for creating various devices.
Will help organize the various types of current and future devices and provide consumers with a clean list of possible devices.
Current types of MIDI_Devices:
Need to separate debugging per class being logged. Best change seems to make SerialDebug an instantiable object with it's own setting member(s). It's already a pretty minimal class so no need to enforce a single instance. Logging functionality will be driven from those settings then; allowing customization per class.
Like any good Arduino library, I should have example sketches of how to use the library.
Need to know the most common use cases people are running into and create examples for those.
Current thoughts:
Currently there are various settings/constants defined in various header files. Want to combine them into a single header to allow control across the entire library from a single place. Also want to add flags/settings for controlling logging here.
After #9 is resolved, should refactor out Defaults.h as it's a bit unnecessary and not flexible. After config classes or the like are implemented, those can contain specific pin configurations and other related information and will only be included if consumers specifically choose to.
I've just been arbitrarily throwing in log statements all across the library at level 5. Just wanted logging to be available to troubleshoot specific issues or see related information.
Need to go back across the entire library and ensure logging is consistent, appropriately given a level, and accurate (copied log statements that don't apply).
Will probably get to this much later, just creating an issue to remind myself of the need.
Want to be able to leverage WiFi capabilities for this project. Need to change a few things in order to compile and test on a development board.
Currently, pitch bending calculates the factor to bend by during every call. The range of values is predictable and can be cached in memory to speed up operation. Build a static class to house this functionality like MIDI_Periods and include a setting to toggle on and off.
After implementing MIDI_Shift_Register, realized it's a lot more straight forward to encapsulate operation logic into the device itself. Want to go back and change the existing code to better accommodate future additions to the interrupt process.
While testing DeviceChain_Controller during #15, realized the issue I was running into could easily trip up others. To avoid this, add/create methods in DeviceChain_Controller to handle creating derived instances of chains and populating them with device from MIDI_DeviceController.
Thinking a single method that has two three parameters is the cleanest implementation.
Method takes in the index to add the chain to, an enum of device chain type (direct, stacking FA, RR) and an array of uint8_t correlating to the devices to add.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.