Git Product home page Git Product logo

aeolian's Introduction

Aeolian

CircleCI License

A (mostly) Clojure console application that processes Java source code through Checkstyle (producing source code quality metrics) and creates a musical representation of these metrics using ABC Notation and ultimately MIDI.

The name Aeolian (apart from being a Greek musical mode) refers to a leading company in the production of player pianos, which takes punched paper as input and drives a mechanical piano.

Aeolian was presented to the YOW West conference in May 2017. The slides can be found here.

Metrics

Currently, Aeolian maps the following source code metrics to aspects of the generated music:

Metric Affects... By...
Line length Note and octave selection Longer lines -> higher pitched notes
Cyclomatic Complexity Tempo Higher complexity -> faster tempo
Method Length Accompanying chord A chord based around first, third, fifth or seventh of key
Duplication Key (Major or Minor) Duplication >= 10% -> minor key
Git commit author MIDI instrument (from 7 available instruments) New instrument for each author change
Source file name Karaoke lyrics (if MIDI file is played through a player that supports the KAR format) New filename lyric for each source file change

Because there is one note played for each line of code processed, a larger source file will produce a longer song. Likewise, more complex code will result in faster passages in the song, whilst less complex code will result in slower passages.

All generated songs use a default tempo of 140bpm and all notes played are eighth notes.

Note: there are still lots of dimensions to code quality and song composition and structure which haven't been covered by Aeolian. I give this to you as a starting point to build out more complex audio representations of code quality for your own edification.

Usage

Assuming you have a Github repo you want to point Aeolian at, then start with this:

./go-gh.sh <github user name> <github repo name>

This script will perform a number of actions:

  1. Clone the repo locally.

    The repo will appear in a temporary directory underneath the Aeolian install dir (hereafter known as the $WORK_DIR). For example:

    $  ./go-gh.sh allegro grunt-maven-plugin
    Checking GitHub for repo 'grunt-maven-plugin' for user 'allegro'...
    Cloning repo to /home/amarks/Code/aeolian/tmp.YtpN0tR5yG...
    
  2. Find the commit history for all the source files.

    Sample terminal output:

    Find commit history for each Java file...
    

    The output from this stage is a file called blames.txt in the $WORK_DIR. The fields in this file are:

Field Position Prefix
Source file 1 None
Line number 2 #
Git commit author 3 AU=
Git commit timestamp 4 TS=
  1. Generate the metrics.

    Sample terminal output:

    Generating Checkstyle duplication metrics...
    Running metrics on all Java files...
    Processing ExecNpmOfflineMojo...
    Generating Checkstyle cyclomatic complexity metrics...
    Generating Checkstyle line length metrics...
    Generating Checkstyle method length metrics...
    Generating Checkstyle indentation metrics...
    Processing AbstractExecutableMojo...
    Generating Checkstyle cyclomatic complexity metrics...
    Generating Checkstyle line length metrics...
    Generating Checkstyle method length metrics...
    Generating Checkstyle indentation metrics...
    Processing ExecNpmMojo...
    ...
    Building uber metrics file...
    Joining metrics file with Git commit history...
    

    The Checkstyle configuration files to generate the complexity metrics can be found here and the script in charge of invoking Checkstyle for each source file can be found here.

    The output from this stage is a file called $WORK_DIR\duplication.txt which contains the summary of the duplication checking on the repo. Additional output is a number of temporary metrics files in $WORK_DIR for each source file processed. Each of these files is named to correspond to the source file and suffixed by a short pseudo-random UID to prevent clashes of source file names across packages.

    All metrics for each source file are eventually combined into a file with a .metrics.all extension. The fields in this file are:

    Field Position Prefix
    Source file 1 None
    Line number 2 #
    Line length N/A LL=
    Cyclomatic Complexity N/A CC=
    Method length N/A ML=

    The final step in this stage is to join the Git blame and Checkstyle metrics files, producing a file with a .history extension.

  2. Generate the ABC Notation.

    Sample terminal output:

    Generating ABC notation...
    Generated /home/amarks/Code/aeolian/tmp.YtpN0tR5yG/grunt-maven-plugin.metrics.history.abc
    

    The generated ABC notation file will appear in $WORK_DIR with the extension .metrics.history.abc.

  3. Generate a playable version of the ABC Notation.

    Aeolian was developed using abcmidi (available on OSX and Ubuntu). abcmidi takes an ABC Notation file as input (foo.abc) and generates a MIDI file from the input file (foo1.mid) for use in the next stage of the pipeline.

    Sample terminal output:

    Generating MIDI...
    3.90 September 25 2016 abc2midi
    writing MIDI file /home/amarks/Code/aeolian/tmp.YtpN0tR5yG/grunt-maven-plugin.metrics.mid
    

    The generated MIDI file will appear in $WORK_DIR with the extension .metrics.mid.

  4. Archive the generated ABC and MIDI files.

    Sample terminal output:

    Archiving generated files..
    

    Both the ABC and MIDI files will be copied to the archive directory.

  5. Play the music.

    Aeolian was developed using timidity (available on OSX and Ubuntu).

    Sample terminal output from Timidity.

    Playing MIDI...
    Requested buffer size 32768, fragment size 8192
    ALSA pcm 'default' set buffer size 32768, period size 8192 bytes
    Playing /home/amarks/Code/aeolian/tmp.YtpN0tR5yG/grunt-maven-plugin.metrics.mid
    MIDI file: /home/amarks/Code/aeolian/tmp.YtpN0tR5yG/grunt-maven-plugin.metrics.mid
    Format: 1  Tracks: 3  Divisions: 480
    Text: @KMIDI KARAOKE FILE
    Sequence: /home/amarks/Code/aeolian/tmp.YtpN0tR5yG/grunt-maven-plugin.metrics.history
    Text: @I/home/amarks/Code/aeolian/tmp.YtpN0tR5yG/grunt-maven-plugin.metrics.history
    Text: @IAEOLIAN
    ...
    Playing time: ~160 seconds
    Notes cut: 0
    Notes lost totally: 0
    

    Assuming all steps of the pipeline have been successful, you should now be listening to the quality of the specified code playing.

License

Copyright © 2015-2017 ThoughtWorks

Distributed under the Eclipse Public License, the same as Clojure.

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.