Git Product home page Git Product logo

undertone's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

undertone's Issues

Create a sample piece of ambient music: Conjunctio Iovis et Saturni

Tasks:

  • Come up with chord progression
  • Determine voices / parts
  • Come up with synth sounds for each voice
  • Create tracks in DAW for each voice
  • Link DAW tracks with MIDI channels
  • Connect mplay in undertone with each channel
  • Decide upon tempo and loop length
  • Decide upon chord / arpeggio progressions
  • Write each voice
  • Publish excerpt on SoundCloud
  • Record full piece and complete production
  • Publish full track on bandcamp
  • Use in teaser video for Lambda Days 2021

Convert the extempore REPL to a gen_server

This is intended mostly as an experiment in feasibility and usefulness. If it works out, then offering an option to start the REPL by default (e.g., #52) may be easier to enable/configure.

Tasks:

  • Add configuration data for the REPL
  • Re-org code for better re-use
  • Add placeholder, stubbed-out gen_server
  • Examine the parts of the current undertone.repl.extempore that may be reused
  • Examine which parts will relinquish their responsibilities to the gen_server
  • Figure out how to best support both REPL types (keeping the existing, simple REPL loop will be good as a pedagogical example)

Create a hybrid LFE/Extempore undertone REPL

With the learnings from Extempore-only REPL (see #33), we might now be in a position to support arbitrary Extempore forms in native-LFE land. This would basically be an LFE REPL, but would have the capability of intercepting user input to check for special, undertone-specific forms, e.g., (xt:define ...). Those could use the functionality developed in the undertone.repl.extempore module.

Tasks:

  • Create a new module in the REPL pseudo-package, namely undertone.repl
  • Add functions for a custom REPL
  • Add support for an xt REPL command
  • In the parser, scan for the presence of (xt ...) and dispatch to the Extempore REPL functions
  • Everything else, treat as LFE
  • Include one or more LFE macros that generate (and send) Extempore code (see #48; a big step toward solving #22)
  • Support entering the extempore REPL from the undertone REPL (and exiting back out to the undertone one)

Note that the approach above doesn't support evaluating LFE expressions inside (xt ...) forms. That would come later (again, see #22).

Create a new supervisor for the Extempore server

Tasks:

  1. Refresh on best way to integrate a binary / OS process into OTP supervision tree
  2. Add a new set of modules for managing this
  3. Add code for converting config options into command line parameters for extempore
  4. Integrate into the main undertone supervision tree
  5. Add health checks:
    • for port existance
    • for OS process existance
    • for Extempore TCP connectivity
  6. Test restarts with #44

Update logo watermark

There seems to be a mushroom thing going on for the project ;-) (see ceba794) Let's go all-in and add it to the logo, too ...

Tasks:

  • Find or create a good outline for Lactarius indigo
  • Convert that to paths then SVG
  • Import paths / SVG into logo vector file
  • Colour appropriately
  • Generate logo v2

Add support for a pure-Extempore REPL

This would allow for Extempore syntax in an LFE session (but in a new REPL).

Tasks:

  • Create a new psuedo-package for repls: undertone.repl
  • Create a new module: undertone.repl.pure-xt
  • Create REPL functions for starting a new REPL
  • Start with single-line support: send all input, as-is, to Extempore
  • Expand to multi-line support
  • Support loading code from the file system and running that in Extempore

Cut the 0.2.0 release

Tasks:

  • Checkout local release/0.2.x branch and rebase from remote for latest
  • Check README / docs for any remaining changes necessary
  • Update versions:
    • apps/undertone/src/undertone.app.src
    • src/undertone-lib.app.src
    • relx entry in rebar.config
  • PR release/0.2.x or merge/push to main
  • Checkout local main and rebase from remote main
  • Tag and push
  • Close out milestone
  • Create a new release branch for the next dev cycle
  • Bump all three version sources for the next dev cycle and push
  • Set the default branch to the next release cycle at https://github.com/lfex/undertone/settings/branches

Figure out how to best support complex/arbitrary Extempore functions & vars

Considerations:

  • LFE's Lisp-2+ syntax is not compatible with Extempore's Lisp-1 syntax
  • Not all symbols used in Extempore are legal in LFE
  • Simply having the user type Extempore Scheme code as a bitstring isn't good DevEx
  • Selectively converting LFE symbols to their Extempore counterparts is either messy (lots of special-casing) or complex (writing an undertone LFE dialect parser + "bitstring transpiler" 🙄)

Questions:

  • Do we want to have a custom REPL that intercepts code before LFE gets to it? Syntax becomes 100% open at that point ...
    • Yes, we do :-)
    • Extempore-only REPL (see #33)
    • Hybrid LFE/Extempore REPL (see #36)

First thoughts on what needs to happed:

  • Starting with a simple macro, just explore converting a regular LFE expression to a bitstring (first part of #48)
  • Explore a custom REPL (#33)
  • Explore scenarios of evaluating LFE code for Extempore Scheme bitstrings (#36)

Add logging

Let's use the new Erlang logger module; this will mean only Erlang 21 and newer will be supported ...

Convert to OTP release-based project

Things to consider:

  • release startup needs to:
    • connect to any enabled OSC servers
    • connect to Extempore, if enabled
  • if Extempore is enabled, a check needs to be performed:
    • is undertone in charge of starting Extempore? (actual support for this will be added later; see #25)
    • or will it assume Extempore to be already started?
  • if undertone will be in charge of starting Extempore
    • that will need to happen before the TCP client manager starts up
    • very likely, this means the use of OTP application start phases

Tasks:

  • Define boundaries between undertone services and libraries
  • Create app/undertone/src and all the basic supervision tree essentials
  • Move only the necessary service code there, leaving the rest for use as the undertone library
  • Deeply evaluate service/application configuration needs
  • Determine good mechanism for enabling / disabling services based upon config
  • Draft config data
  • Develop config data accessors and update sys.config as needed
  • Do refresher on OTP start phases
  • Implement start phases as needed for just the work in this ticket (adding placeholders where appropriate)

Explore supporting writing to MIDI devices

Tasks:

  • What sorts of MIDI libraries exist in the Erlang ecosystem?
    • nothing much; it's a pretty crappy scene
  • How might MIDI file parsers be adapted to send MIDI in real-time?
    • they pretty much can't be; there's a ton of effort that has gone into various APIs to make their critical bits as real-time as possible; naïvely parsing and sending data isn't going to cut it
  • How does one write to MIDI-ready VST plugins?
  • How can one send MIDI signals (namely,. from an external service like an Erlang app) to a track / strip in a DAW?
    • one way to do this is use a software MIDI controller that accepts incoming MIDI messages and offers a pass-through option
  • What about writing a MIDI controller that the OS recognizes?

After all this exploration, what are the options for the goal "I want to control a MIDI-capable VST plugin from LFE"?

  1. ❌ Send MIDI from LFE
    1. ❌ write RAW MIDI data directly to a device
    2. ⚠️ use a cross-platform MIDI library like PortMIDI (I actually don't care about cross-platform compat)
      1. ❌ compile a C NIF for use in Erlang
      2. ⚠️ use Erlang ports to communicate with a PortMIDI daemon to avoid NIF VM crashes (maybe when I care about cross-platform?)
    3. 🤔 use an Apple-specific MIDI library
      1. use Erlang ports to communicate with a CoreMIDI daemon (would require a bunch of new work)
  2. 🤔 Send OSC data from LFE, i.e., find a MIDI controller with OSC support (just have to implement functions for appropriate OSC addresses)
  3. ✅ Use Extempore!

Add support for session management

This would be for temporary, single-session REPL command management. For history management (persistent storage between sessions), see #55.

Tasks:

  • With every completed REPL entry (successful parse), do the following:
    • Store ephemeral session in ETS table
    • Complete drop the ETS data when quitting
  • Add related Extempore REPL commands:
    • Show all recent history
    • Show last n lines of history
    • Show last n lines of session
    • Execute a particular history line again
    • Export history to file
    • Support re-running commands
    • Support re-running ranges of commands
  • Review naming of functions to keep concepts of "Session" vs. "History" clear and separate

Create Lambda Days 2021 video teaser

  • Create script
  • Create first draft of videography
  • Record intro video
  • Screen-capture some IDE time
  • Record final fade
  • Create mini-score using undertone - #37
  • Get NASA image(s)
  • Create image scenes / transitions
  • Create text overlays / transitions
  • Produce final mix

OSC Client: Add Ardour DAW support

Tasks:

  • Create a psuedo-package for Ardour OSC support
  • Re-examine code re-use for all OSC clients and improve as applicable
  • Examine the Ardour OSC docs for a good set of initial OSC addresses to support
  • Implement select addresses:
    • /strip/list
    • /strip/plugin/list ssid
    • /strip/plugin/descriptor ssid
    • /strip/select ssid y/n
    • /goto_start
    • /monitor/mute

Branch:

Resources:

Create a first set of LFE macros for executing Extempore code

This wouldn't necessarily be very useful, but would represent an essential first step in addressing #22 and would be a useful feature in #36 and subsequent features for that REPL.

Tasks:

  • Create (defxtmsg ...) which simply generates a full message (including terminator string) and can be assigned to a variable
  • Create (definext ...) which mimics Extempore's (define ...)
  • Create (lambdaxt ...) which mimics Extempore's (lambda ...)
  • Create (bind*xt ...) which mimics Extempore's (bind* ...)

Add banner

Tasks:

  • Create / design ASCII art+figlet banner
  • Create banner-rendering function
  • Add special case for receiving the "Welcome to Extempore" message
  • Add banner-tracking (maybe displayed-banner?) to undertone session manager
  • Display banner upon receiving welcome message and only if displayed-banner? is not true

Ponder music structures not defined by Extempore

Extempore is designed for use in live coding and improvisation; units of composition don't go too far beyond collections of notes. Things to ponder, in order to use undertone as a tool in composition while being backed by Extempore:

  • Is a representation of a measure useful?
  • A score?
  • Voices / instruments in a score?
  • What about the metaphor of a mixer / console / DAW? Is that useful?
  • Can these different metaphors be mixed usefully?
  • What about mechanics?
    • For example, setting up devices for playback / recording at a combination of OS / DAW level can be cumbersome.
    • What is the best way to do that for access / use in Extempore + DAW + undertone?
    • e.g., when playing multiple instruments at the same time

Add support for history management

This would be persistent storage for commands over the course of multiple sessions, as opposed to the temporary storage of REPL commands in one session (see #40).

Tasks:

  • With every completed REPL entry (successful parse), do the following:
    • Store history to Mnesia table (DETS doesn't support ordered sets)
    • Support backups to disk
    • When starting a new session, automatically load data from history backups on disk

Improve listing MIDI devices

Right now, there doesn't seem to be a way of capturing the list of MIDI devices seen by Extempore -- the function appears to bd stdout-only.

Tasks:

  • Full explore the Extempore codebase to verify or invalidate this initial discovery
  • Discuss on Extempore mail ilst
  • If necessary, experiment with local build of Extempore that adds a return value (even if just bytes / a string)
  • If successful, submit PR to Extempore project
  • Add parsing of MIDI device list to undertone

This may need to be done for both PortMIDI and rtmidi in Extempore ...

Set up LFE code for supporting Extempore

  • Populate sub pseudo-packages with Extempore-component support
  • Create an xt.lang module for functions that generate Extempore's Scheme forms
    • this will allow for calling such functions/macros as (xtl:define ...) without conflict in any of LFE's forms
  • Properly integrate this with the client functionality for sending to the extempore TCP server
    • any functions that needs to perform an actual send to the server should do everything to make that happen under the hood
    • all calls to the Extempore server should go through a single point that converts stringified forms to binary
    • and adds the message terminator \r\n
  • We should feel free to introduce Lisp-2-isms/LFE-isms here and not just duplicate the exact syntax of xtlang (this is LFE, after all!)

Update parens-balancer to short-cut on negative counts

Right now the Extempore parentheses balancer function only considers an expression balanced when the parens count reaches zero. An essentially error state may be created when negative parens counts occur (via typos, too many closing parens, etc.). This may be avoided by executing zero-parens logic for any negative parens counts, too.

Add support for Extempore

Tasks:

Phase 1 - Basic Support

  • Experiment with a modern extempore - #19
  • Experiment with simple LFE/OTP TCP client - #20
  • Ponder Extempore's compiler server and the best way to represent code to be sent to the server
  • Create a pseudo-package at src/xt - #21
  • Populate a top-level xt module with all the functions necessary to get started using Extempore
  • For support of every major Extempore component added, also provide an include file for easy use

Phase 2 - Extempore Management / OTP Integration

  • Create a primary supervision tree
  • Add start options record / include for extempore binary flags
  • Create a child that starts the extempore binary / executable (see #51 and #44)
  • Create a child that maintains a TCP connection / client with the extempore TCP server
    • this should depend upon the binary child
    • if that restarts, this one will need to a well
  • Create a child that maintains a coding session (see #40)
    • so that even if the executable and/or the TCP client are restarted, the work is preserved
    • as such, it should not depend upon (or be restarted by) either of the other children
    • it should probably use ETS

Phase 3 - Extended Support

  • Allow for the defining of complex vars and functions
    • Explore the problem space #22
    • Add a custom REPL with native support for Extempore - #33
    • Add a dedicated undertone REPL - #36
  • Add LFE-native DSP support - #23
  • Add LFE-native MIDI support - #24
  • Add more simple examples for this capability
  • Make sure the 2014 OSCON theme song can be built and played from LFE (add as an example)

Phase 4 - Compositional DSL

  • Ponder Extempore's use in composition (see #41, #37)
  • Add song macro
  • Add measure macro
  • Integrate these with Extempore's language patterns (for playing notes)

Resources

Create a health check for the Extempore TCP server

A positive is fairly easy to do: send a blocking message to the server and if a result comes back, you're good. Simply sending a bool like #"#t\r\n" would do it. However, if the server is not okay, you can be in a bad state. A timeout will help with that (see lfex/tcp-client#7). Until then, an async message that writes a warning to a log should be fine.

This could be done with sending a specific bit of data, e.g., #(health ok) which will then be resent by Extempore back to undertone. When that specific packet comes back, it can be intercepted and a lot message can be generated.

Tasks:

  • Create a (check-xt) REPL function, which will async send #(health ok)
  • Create a new pattern check in the TCP message handler for #(health ok), logging that at notice-level

Investigate starting the undertone REPLs automatically

What will it take to automatically start the extempore or undertone REPLs? (once we have the undertone REPL in place, see #36). The goal being that when the system comes up with a rebar3 command such as rebar3 as extempore repl or rebar3 as undertone repl, start with that REPL instead of the LFE REPL.

Tasks:

  • Try starting the existing, extempore REPL automatically
  • Create a rebar3 plugin for undertone
  • If useful/desired, update / convert one of the custom REPLs to be a gen_server (see #54)
  • Re-examine the code underlying rebar3 lfe repl and setting a custom tty
  • Identify a good way to do this for the new REPL
  • Create an alias in rebar.config that passes the appropriate flags or uses the appropriate profile
  • Test it!

Explore Extempore internal state data

General health / connection status is probably the single most important factor (see #47), but it would be nice to have access to other info, too:

  • totally memory use
  • current CPU util (5/10/15 min averages would be good)
  • latency of responses (this would be 100% on the undertone side and could be done as an enhancement to the health / connectivity / status check)

As a starter, Andrew Sorensen pointed me to the top of this file:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.