A C++11 library for representing musical scales and tunings.
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
examples
miles
tests
README.md
miles.h

README.md

Miles

Miles is a C++11 library for representing musical scales and tunings. It is simple, flexible and easily supports microtonal and non-western scales.

Using Miles

Miles is a header-only library. To use Miles:

  1. Include Miles by adding the following to your project:

    #include "miles.h"
  2. Add the directory which contains miles.h to your compiler's include path

If you need faster compilation times then you can only include the parts of Miles which you need to use, for example:

#include "miles/major_scale.h"

Examples

Using built-in scales

The most straightforward way to use Miles is to use one of its collection of built-in scales. In this example we print the C major scale between middle C and treble C.

#include <iostream>

#include "miles.h"

using namespace miles;

// Create a major scale
Scale scale = MajorScale();

// The frequency of low C, used as the base frequency of our scale
float lowC = 65.406f;

int main() {
    // Print the C major scale from middle C to treble C
    for (uint32_t i=0; i<8; i++) {
        std::cout << scale.getFrequency(i, lowC, 2) << std::endl;
    }
}

Changing the tuning

Miles' built-in scales use an appropriate tuning system by default, however this can be easily changed. In this example we create an A minor scale with just tuning, and use it to print the frequency of the F above middle C.

#include <iostream>

#include "miles.h"

using namespace miles;

// Create a minor scale with Just tuning
Scale scale = MinorScale(JustTuning());

// The frequency of the A below middle C, used as the base frequency of our
// scale
float baseA = 220.0f;

int main() {
    // Print the F above middle C (the 6th note in the A minor scale)
    std::cout << scale.getFrequency(5, baseA, 0) << std::endl;
}

Creating custom scales

If Miles doesn't contain the scales you need to use then it's simple to create a new one from a list of the scale's degrees. In this example we create the Phyrigian dominant scale, and print the C# scale.

#include <iostream>

#include "miles.h"

using namespace miles;

// A custom scale is a simple factory function returning a scale.
Scale CustomScale(Tuning tuning=EqualTemperamentTuning(12)) {
    return Scale({0u, 1u, 3u, 5u, 7u, 8u, 10u}, tuning);
}

// Create an instance of our custom scale
Scale scale = CustomScale();

// The frequency of low C#, used as the base frequency of our scale
float lowCSharp = 69.296f;

int main() {
    // Print our scale from low C# to bass C#
    for (uint32_t i=0; i<8; i++) {
        std::cout << scale.getFrequency(i, lowCSharp, 0) << std::endl;
    }
}

Creating custom tunings

Similarly, we can create custom tunings from a list of semitone values or note ratios. The following example prints the C major scale using a standard 12-tone equal temperament tuning, and a stretched version of the same tuning.

#include <iostream>
#include <iomanip>

#include "miles.h"

using namespace miles;

// A custom tuning is a simple factory function returning a tuning
Tuning CustomTuning() {
    return Tuning({0.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f, 9.f,
                   10.f, 11.f}, 2.05);
}

// Create two scale, one using the standard tuning and one using our custom
// tuning
Scale scaleA = MajorScale();
Scale scaleB = MajorScale(CustomTuning());

// The frequency of low C, used as the base frequency of our scale
float lowC = 65.406f;

int main() {
    // Print the two scales side by side for comparison
    std::cout << std::setw(8) << "ET";
    std::cout << std::setw(8) << "Custom" << std::endl;
    for (uint32_t i=0; i<8; i++) {
        std::cout << std::setw(8) << scaleA.getFrequency(i, lowC, 2);
        std::cout << std::setw(8) << scaleB.getFrequency(i, lowC, 2);
        std::cout << std::endl;  
    }
}

API Documentation

Scale

Scale(std::vector<float> degrees, Tuning tuning=EqualTemperamentTuning(12));

Construct a scale from a vector of degrees, and a tuning.

float Scale::getFrequency(uint32_t degree, float rootFrequency,
                          uint32_t octave);

Get the frequency of a note in the scale at a given degree and octave, with a root frequency for the scale.

Scale XScale(Tuning tuning=AnAppropriateTuning());

Return an instance of a built-in scale named X. Currently available scales are: MajorScale, MinorScale.

Tuning

Tuning(std::vector<float> semitones, float octaveRatio=2.0f);

Construct a tuning from a list of semitones and an octave ratio (allowing for stretched tunings).

static Tuning Tuning::fromRatios(std::vector<float> ratios,
                                 float octaveRatio=2.0);

Construct a tuning from a list of note ratios and an octave ratio.

Tuning XTuning();

Return an instance of a built-in tuning named X. Currently available tunings are: EqualTemperamentTuning, JustTuning.