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