Giter Site home page Giter Site logo

varese's Introduction

Varèse-inspired pitch space tools Build status Coverage Status

What?

The gist of it is that if you throw away your contemporary notions of harmony—in particular, the notion that equivalence classes of pitches are determined by modding out octaves—then you get some interesting stuff.

The tree

One of the core concepts at hand is the notion of infoldings and outfoldings of a chord—say a trichord (three notes) for simplicity. If you have a trichord, you can outfold it by “pivoting” the middle note about the top note (an upward outfolding) or the bottom note (a downward outfolding), preserving the interval. So C–E–G would upfold to C–G–B♭, preserving the minor third, or downfold to A♭–C–G, preserving the major third.

The inverse operation is an infolding: pivot one of the outer notes about the middle note. So C–E–G could infold to C–C♯–E or E–G–G♯. But note only the first of those outfolds back to the original, because only the first one puts the folded pitch in the middle. So we see that it's more useful to infold the pitch that makes a smaller interval, and there's a canonical infolding.

Thus, the trichords form a (complete, infinite) binary tree: left children are downward outfoldings, and right children are upward outfoldings; parents are canonical infoldings.

This is what the tree explorer (/#/tree) allows you to explore.

This is closely related to Varèse's work.

The roots

There's also the concept of finding the acoustic root of an interval, or, by extension, of a chord.

Suppose we have an interval of two pitches. We want to find some fundamental frequency of which each of the pitches in the interval is an integer multiple. For example, if the pitches are at 500 Hz and 300 Hz, then the fundamental is 100 Hz; if the first pitch were instead 600 Hz, the fundamental would be 200 Hz.

We can extend that to chords recursively: most concisely, if intervalRoot : Pitch → Pitch → Pitch, then define

pairwiseRoots :: [Pitch]  [Pitch]
pairwiseRoots ps = zipWith intervalRoot ps (tail ps)

chordRoot :: [Pitch]  Pitch
chordRoot = head  last  takeWhile (not  null)  iterate pairwiseRoots

and chordRoot gives the root of a chord.

For example, consider the chord C4–E♭4–F♯4. The root of (C4, E♭4) is A♭1, and the root of (E♭4, F♯4) is B1. The root of (A♭1, B1) is E−1. The next iteration would yield the empty list, so we stop here; E−1 is the root of the chord. (Note that the roots get really low really fast: a normal trichord and we're already more than a full octave below the piano!)

If you're paying close attention, you may be wondering how we work with pitches when we really want to be dealing with frequencies—after all, they don't always coincide! So how do we convert something like C4–E4–G4 to frequency? Simple: we get the user to do it! Specifically, if the user gives us specific acoustic ratios for each of the simple intervals—e.g., “we'll call a minor sixth the ratio of the fifth to the eighth overtones”—we can extrapolate everything we need from there. (We only need ratios because the actual frequencies don't matter.) Going in the other direction is easy because we can get exact values logarithmically, and they should be mostly consistent with the user-specified rationalizations.

This is what the pitch calculator (/#/calculator) calculates.

This is mostly a new area of study.

Technical overview

The core operations (i.e., the actual calculations and the interesting stuff) are in a thoroughly tested functional core. The UI is as light as possible a React wrapper around this, which makes it really easy to reason about the data flow. We're also starting to write some tests for the React components themselves—both in terms of the DOM output they produce and with simulated user interactions.

The whole React app is webpacked into a bundle.js file, which is included by the HTML page. The HTML page is tiny, and just provides a <div id="app"></div> into which React will render the application.

The UI entry point is index.jsx, but you really probably want to start looking at either PitchCalculator or TreeExplorer.

Confused? Looking for API links? Here's the stack: React and React Router for the UI and routing, Bootstrap (not React-Bootstrap) for the CSS (not JS), Mocha and Chai for the unit testing. The global state (configuration and settings) is managed through the wonderful Redux and bound to the UI with React Redux. We use VexFlow for engraving chords.

The tool stack includes webpack for the module bundling and babel for the ES2015-and-up desugarings.

Building

$ cd varese
$ npm install
$ npm test
$ npm start
$ open http://localhost:8080/

This will start a development server with hot reloading enabled: just change the JSX files and you shouldn't even have to refresh the page to see your changes. If your changes aren't going through, try touching the file you changed.

Deploying

$ git commit -m "do a thing"
$ ./deploy.sh

You should also probably push to master.

You may have to restart your development server after deploying to get your hot loading working again. Just hit ^C and run npm start again.

varese's People

Contributors

wchargin avatar

Watchers

 avatar

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.