Search This Blog

Simplicity is the ultimate sophistication.” — Leonardo da Vinci
Contact me: sreramk360@gmail.com

Friday, 6 February 2015

Music chord generator



Music chord generator
 

The following is a simple implementation of music cord generator created by me and my friend Elanchezhian in c++11. The main task of this console CUI application is to get command line inputs like "C major" or "C minor 6" and display the respective notes that constitute that cords. Please excuse any spelling mistakes or improper variable, function, constants  naming. I haven't got the slightest idea of music, and that lead to making me use silly names for many data type declaration. Again, this program was developed JUST FOR FUN.

compiling this program:
you may compile this program by pasting the code under the specified file name. For example, the main.cpp contents should be under main.cpp, the Ui.h contents should be under the Ui.h. Now create a visual studio empty project and add all these files to it. Once you are done adding, compile the project. The resultant binary release will be the final output.    


/* main.cpp
*the musical chord generator computational method copyright (c) Elanchezhian 2015 algorithmic
* implementation in c++ and coding  copyright (c) 2015 K Sreram 
* this source is published without WITHOUT ANY WARRANTY of any sort.
*/
#include "UI.h"
#include "cordGenerator.h"
#include <stdlib.h>
int main()
{
    userInterface newUI;
    generateCord gen1;
    newUI.documentation();
    while (true)
    {
        newUI.getCommand();
        newUI.seperateCommands();
        gen1.getChordTypeAndChordFamily(newUI);
        if (gen1.exit_process)
            return 0;
        if (gen1.error_in_process)
            continue;
        gen1.generatetheChord();
        if (gen1.scaleOrCord)
            std::cout << "the chord :" << gen1.theChord << "\n";
        else
            std::cout << "the scale :" << gen1.theChord << "\n";
    }
    system("pause");
    return 0;
}

/* UI.h
*the musical chord generator computational method copyright (c) Elanchezhian 2015 algorithmic
* implementation in c++ and coding  copyright (c) 2015 K Sreram 
* this source is published without WITHOUT ANY WARRANTY of any sort.
*/#ifndef UI_H
#define UI_H
#include <vector>
#include <string>
#include <iostream>
#include <string.h>
class userInterface{
public:
    size_t data_size; // size of data. Same as commandList.size();
    std::string command; // the command given by the user
    std::vector<std::string> commandList; // list of words given as commands (neglets space)
    void getCommand(); // reserves command from the user
    void seperateCommands(); // seperates commands for checking
    userInterface(); // initializer
    void documentation(); // file documentaton output
private:
    std::string tempData;
   
};
#endif // UI_H

/* UI.cpp
*the musical chord generator computational method copyright (c) Elanchezhian 2015 algorithmic
* implementation in c++ and coding  copyright (c) 2015 K Sreram 
* this source is published without WITHOUT ANY WARRANTY of any sort.
*/
#include "UI.h"
userInterface::userInterface()
{
    this->data_size = 0;
}
void userInterface::getCommand()
{
    data_size = 0;
    command.clear();
    std::cout << "->";
    std::getline(std::cin, command);
}

void userInterface::seperateCommands()
{
    tempData.clear();
    commandList.clear();
    size_t index = 0;
    if (command.size() == 0)
        return;
    while (index < command.size())
    {
        if (command[index] != ' ')
            tempData.push_back(command[index]);
        else
        {
            commandList.push_back(tempData);
            ++data_size;
            tempData.clear();
        }
        ++index;
    }
    commandList.push_back(tempData);
    ++data_size;
}

void userInterface::documentation()
{
    std::cout << "the musical chord generator algorithm and computational methord \n copyright (c) Elanchezhian 2015\n"
                 <<"algorithamic implementation in c++ and coading \n compright (c) 2015 K Sreram \n";

}



/* cordGenerator.h
*the musical chord generator computational method copyright (c) Elanchezhian 2015 algorithmic
* implementation in c++ and coding  copyright (c) 2015 K Sreram 
* this source is published without WITHOUT ANY WARRANTY of any sort.
*/
#ifndef CORD_GENERATOR_H
#define CORD_GENERATOR_H
#include "UI.h"

enum cordFamily{
    major,    sus_2,
    sus_4,    diminished,    major_add_9,
    argumented,    dominant_11, dominant_13,    /// argumented is augumented
    dominant_7,    dominant_9,
    power_cord_5, major_7, minor, minor_6,
    minor_7, minor_9,
    major_cord_family, minor_chord_family, major_9, major_6,
    diminished_7
};

enum notes_sharp{
    C_, C_sharp, D_, D_sharp,
    E_, F_, F_sharp, G_,
    G_sharp, A_, A_sharp, B_
};

enum notes_flat{
    C, D_flat, D, E_flat,
    E, F, G_flat, G,
    A_flat, A, B_flat, B
};
union chordType
{
    notes_flat flat;
    notes_sharp sharp;
};
enum CH_type{sharp_, flat_};
class generateCord{
public:
    bool scaleOrCord;
    bool exit_process;
    bool error_in_process; // shows error
    std::string theChord; // the result
    chordType type; // which chord? eg, C chord or D chord...
    cordFamily chord_family; // type of chord used
    CH_type t_type; // sharp_ or flat_
    generateCord();
    void getChordTypeAndChordFamily(userInterface& newUI); // extracts information from the command
    void generatetheChord(); // provides the result
private:
    bool search_string(std::vector<std::string> strList, std::string str); // searches for string
    bool find_words(std::vector<std::string> strList1, std::vector<std::string> theseWords, std::vector<std::string> notThesewords);
};

extern const std::vector<std::vector<int>> control;
extern const notes_sharp notes_sharp_Order[12];
extern const notes_flat notes_flat_Order[12];
extern const std::vector<std::string> notes_sharp_chr;
extern const std::vector<std::string> notes_flat_chr;
extern const size_t size_of_notes_series;
#endif



/* cordGenerator.cpp
*the musical chord generator computational method copyright (c) Elanchezhian 2015 algorithmic
* implementation in c++ and coding  copyright (c) 2015 K Sreram 
* this source is published without WITHOUT ANY WARRANTY of any sort.
*/
#include "cordGenerator.h"
const std::vector<std::vector<int>> control = {  //indexed by chord_family
    {  4, 3 }, {  2, 5 }, { 5, 2}, { 3, 3},
    {  4, 3, 7 }, {  4, 4 }, { 4, 3, 3, 4, 3},
    {  4, 3, 3, 4, 7 }, {  4, 3, 3 }, { 4, 3, 3, 4},
    {  7 }, {  4, 3, 4 }, {  3, 4 }, { 3, 4, 2},
    { 3, 4, 3 }, { 4, 3, 2, 5 }, { 2, 2, 1, 2, 2, 2, 1 },
    { 2, 1, 2, 2, 1, 2, 2 }, { 4, 3, 4, 3 }, { 4, 3, 2 }, {3, 3, 3}
};

const notes_sharp notes_sharp_Order[] = { C_, C_sharp, D_, D_sharp,
                                    E_, F_, F_sharp, G_,
                                    G_sharp, A_, A_sharp, B_ };

const notes_flat notes_flat_Order[] = { C, D_flat, D, E_flat,
                                        E, F, G_flat, G,
                                        A_flat, A, B_flat, B };

const std::vector<std::string> notes_sharp_chr = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};
const std::vector<std::string> notes_flat_chr = { "C", "D_b", "D", "E_b", "E", "F", "G_b", "G", "A_b", "A", "B_b", "B"};
const size_t size_of_notes_series = 12;

generateCord::generateCord()
{
    error_in_process = false;
    exit_process = false;
    scaleOrCord = true; // chord is true
}
bool generateCord::search_string(std::vector<std::string> strList, std::string str)
{
    size_t i;
    for (i = 0; i < strList.size(); i++)
        if (strList[i] == str)
            return true;
    return false;
}
bool generateCord::find_words(std::vector<std::string> strList1, std::vector<std::string> theseWords, std::vector<std::string> notThesewords)
{ // <<<<<<<<"not used yet:: to be used in future releases"-K Sreram>>>>>>>>>>>>>>>>>>
    const size_t theseWords_size = theseWords.size();
    const size_t notTheseWords_size = notThesewords.size();
    const size_t strList1_size = strList1.size();
    size_t i;
    for (i = 0; i < theseWords_size; i++)
    {
        if (!search_string(strList1, theseWords[i]))
            return false;
    }
    for (i = 0; i < notTheseWords_size; i++)
    {
        if (search_string(strList1, notThesewords[i]))
            return false;

    }
    return true;

}
void generateCord::getChordTypeAndChordFamily(userInterface& newUI)
{// extracts information from the command
    scaleOrCord = true;
    size_t i;
    bool trigger = true;
    error_in_process = false;
    exit_process = false;
    /// chord type
    for (i = 0; i < 12; i++)
    {
        if (search_string(newUI.commandList, notes_sharp_chr[i]))
        {
            type.sharp = (notes_sharp)i; // records the chord
            t_type = sharp_;
            trigger = false;
            break;
        }
       
    }
    if (trigger) /// ie the search failed
        for (i = 0; i < 12; i++)
        {
            if (search_string(newUI.commandList, notes_flat_chr[i]))
            {
                type.flat = (notes_flat)i;// records the chord
                t_type = flat_;
                trigger = false;
                break;
            }
           
        }
    if (search_string(newUI.commandList, "exit"))
    {
        exit_process = true;
        return;
    }
    else if (trigger)
    {
        std::cout << "\nerror: the command,\"" << newUI.command << "\" is unidentifiable\n";
        error_in_process = true;
        return;
    }

    if (search_string(newUI.commandList, "major"))
    {
        if ((search_string(newUI.commandList, "add")) &&
            (search_string(newUI.commandList, "9")))
        {
            chord_family = major_add_9;
        }
        else if ((search_string(newUI.commandList, "add")) &&
            (search_string(newUI.commandList, "7")))
        {
            chord_family = major_7;
        }
        else if (search_string(newUI.commandList, "major") &&
            search_string(newUI.commandList, "scale"))
        {
            scaleOrCord = false;
            chord_family = major_cord_family;
        }
        else if (search_string(newUI.commandList, "9"))
        {
            chord_family = major_9;
        }
        else if (search_string(newUI.commandList, "6"))
        {
            chord_family = major_6;
        }
        else // for only major
            chord_family = major;
    }
    else if (search_string(newUI.commandList, "sus"))
    {
        if (search_string(newUI.commandList, "2"))
            chord_family = sus_2;
        else if (search_string(newUI.commandList, "4"))
            chord_family = sus_4;
        else
        {
            std::cout << "\nerror: the command,\"" << newUI.command << "\" is unidentifiable\n";
            error_in_process = true;
        }
    }
    else if (search_string(newUI.commandList, "diminished"))
    {
        if (search_string(newUI.commandList, "7"))
            chord_family = diminished_7;
        else
            chord_family = diminished;
    }
    else if (search_string(newUI.commandList, "major") &&
        (search_string(newUI.commandList, "add")) &&
        (search_string(newUI.commandList, "9"))&&
        !(search_string(newUI.commandList, "7")))
    {
        chord_family = major_add_9;
    }
    else if (search_string(newUI.commandList, "augumented"))
    {
        chord_family = argumented;
    }
    else if (search_string(newUI.commandList, "dominant"))
    {
        if (search_string(newUI.commandList, "11"))
            chord_family = dominant_11;
        else if (search_string(newUI.commandList, "13"))
            chord_family = dominant_13;
        else if (search_string(newUI.commandList, "7"))
            chord_family = dominant_7;
        else if (search_string(newUI.commandList, "9"))
            chord_family = dominant_9;
        else
        {
            std::cout << "\nerror: the command,\"" << newUI.command << "\" is unidentifiable\n";
            error_in_process = true;
        }
    }
    else if (search_string(newUI.commandList, "power") &&
        search_string(newUI.commandList, "chord") &&
        search_string(newUI.commandList, "5"))
    {
        chord_family = power_cord_5;
    }
    else if (search_string(newUI.commandList, "minor"))
    {
        if (search_string(newUI.commandList, "scale"))
        {
            scaleOrCord = false;
            chord_family = minor_chord_family;
        }
        else if (search_string(newUI.commandList, "6"))
        {
            chord_family = minor_6;
        }
        else if (search_string(newUI.commandList, "7"))
        {
            chord_family = minor_7;
        }
        else if (search_string(newUI.commandList, "9"))
        {
            chord_family = minor_9;
        }
        else
        {
            chord_family = minor;
        }
    }
    else
    {
        std::cout << "\nerror: the command,\"" << newUI.command << "\" is unidentifiable\n";
        error_in_process = true;
    }
}

void generateCord::generatetheChord()
{
    size_t index;
    size_t index_temp = 0;
    const size_t size_control= control[chord_family].size(); // common for both
    theChord.clear();
    /// the main generator
    if (t_type == sharp_)
    {
            index_temp = type.sharp;
            theChord = notes_sharp_chr[type.sharp]; // store the initial cord (no. 1 is default)
            for (index = 0; index < size_control; index++)
            {
                index_temp += (control[chord_family][index]); //i.e (type.sharp + 1 + control[chord_family][index]+1) -1
                theChord += " ";
                theChord += notes_sharp_chr[(index_temp) % size_of_notes_series]; // add to the result
            }
    }
    else if (t_type == flat_)
    {
        index_temp = type.flat;
        theChord = notes_flat_chr[type.flat]; // store the initial cord (no. 1 is default)
        for (index = 0; index < size_control; index++)
        {
            index_temp += (control[chord_family][index] ) % size_of_notes_series;
            theChord += " ";
            theChord += notes_flat_chr[(index_temp) % size_of_notes_series]; // add to the result
        }
    }
    else
    {
        std::cout << "error: variable t_type is uninitialised. consider calling getChordTypeAndChordFamily() before calling generatetheChord()\n";
    }
}

About my blog

1 comment:

  1. This program can only be compiled using a C++ 11 compiler

    ReplyDelete

Featured post

Why complicating matters is not good

“ Simplicity is the ultimate sophistication.” — Leonardo da Vinci Why is complicating things wrong ? - K Sr...