/*
* Klang – a node+text-based synthesizer library
*
* This file is part of the *wellen* library (https://github.com/dennisppaul/wellen).
* Copyright (c) 2022 Dennis P Paul.
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// @TODO(move to strom)
#ifndef Scales_hpp
#define Scales_hpp
#include <vector>
#include "Klang.hpp"
namespace klang {
typedef uint8_t SCALE_TYPE;
class Scales {
public:
static const std::vector<SCALE_TYPE> CHROMATIC;
static const std::vector<SCALE_TYPE> FIFTH;
static const std::vector<SCALE_TYPE> MINOR;
static const std::vector<SCALE_TYPE> MAJOR;
static const std::vector<SCALE_TYPE> MINOR_CHORD;
static const std::vector<SCALE_TYPE> MAJOR_CHORD;
static const std::vector<SCALE_TYPE> MINOR_CHORD_7;
static const std::vector<SCALE_TYPE> MAJOR_CHORD_7;
static const std::vector<SCALE_TYPE> MINOR_PENTATONIC;
static const std::vector<SCALE_TYPE> MAJOR_PENTATONIC;
static const std::vector<SCALE_TYPE> OCTAVE;
static const std::vector<SCALE_TYPE> DIMINISHED;
static const std::vector<const std::vector<SCALE_TYPE>> SCALES;
static const uint8_t ID_CHROMATIC = 0;
static const uint8_t ID_FIFTH = 1;
static const uint8_t ID_MINOR = 2;
static const uint8_t ID_MAJOR = 3;
static const uint8_t ID_MINOR_CHORD = 4;
static const uint8_t ID_MAJOR_CHORD = 5;
static const uint8_t ID_MINOR_CHORD_7 = 6;
static const uint8_t ID_MAJOR_CHORD_7 = 7;
static const uint8_t ID_MINOR_PENTATONIC = 8;
static const uint8_t ID_MAJOR_PENTATONIC = 9;
static const uint8_t ID_OCTAVE = 10;
static const uint8_t ID_DIMINISHED = 11;
static const uint8_t NUM_OF_SCALES = 12;
static const std::vector<SCALE_TYPE>& get(const uint8_t pScaleID) {
switch (pScaleID) {
case ID_CHROMATIC:
return CHROMATIC;
case ID_FIFTH:
return FIFTH;
case ID_MINOR:
return MINOR;
case ID_MAJOR:
return MAJOR;
case ID_MINOR_CHORD:
return MINOR_CHORD;
case ID_MAJOR_CHORD:
return MAJOR_CHORD;
case ID_MINOR_CHORD_7:
return MINOR_CHORD_7;
case ID_MAJOR_CHORD_7:
return MAJOR_CHORD_7;
case ID_MINOR_PENTATONIC:
return MINOR_PENTATONIC;
case ID_MAJOR_PENTATONIC:
return MAJOR_PENTATONIC;
case ID_OCTAVE:
return OCTAVE;
case ID_DIMINISHED:
return DIMINISHED;
}
return CHROMATIC;
}
static int note(const std::vector<SCALE_TYPE>& pScales, const int pBaseNote, const int pNoteStepOffset) {
if (pNoteStepOffset > 0) {
const int mSize = (int)pScales.size();
const int mOctave = pNoteStepOffset / mSize;
const int mIndex = pNoteStepOffset % mSize;
const int mScaleEntry = pScales[mIndex];
const int mNote = pBaseNote + (mOctave * 12) + mScaleEntry;
return mNote;
} else if (pNoteStepOffset < 0) {
const int mSize = (int)pScales.size();
const int mNormalizedNoteStepOffset = -pNoteStepOffset + (mSize - 1);
const int mOctave = -mNormalizedNoteStepOffset / mSize;
const int mIndex = (mSize - 1) - (mNormalizedNoteStepOffset % mSize);
const int mScaleEntry = pScales[mIndex];
const int mNote = pBaseNote + (mOctave * 12) + mScaleEntry;
return mNote;
} else {
return pBaseNote;
}
}
};
} // namespace klang
#endif /* Scales_hpp */