Dear Fellow Programmers,
I've tried to organize the files according to best practices:
declarations all in "pitch.h"
definitions in "pitch.cpp"
program begins and ends in "main.cpp"
I'm getting a bunch of linker errors when I compile just like this one:
Error LNK2005 "public: __cdecl FisMoll::Pitch::Pitch(enum FisMoll::ePitchFisMoll)" (??0Pitch@FisMoll@@QEAA@W4ePitchFisMoll@1@@Z) already defined in main.obj recursionOfTwoPathsInAPitchField C:\Users\Adam\source\repos\recursionOfTwoPathsInAPitchField\recursionOfTwoPathsInAPitchField\pitch.obj 1
I'll outline a description of the code as it appears in the three files below
and also give a short overview of the program and what it's doing. The definitions are a bit long winded, so I'll abbreviate where possible.
A simple program that models the path traveled by individual pitches of a melody as they are transposed through a pitch field. In other words, these pitches are transposed by a set of diatonic intervals a number of times and the number of times that a specific pitch occurs is counted. The idea is an attempt to model the types of recursive algorithms used to generate strange attractors and other similar types of chaotic symmetries.
As in it's a music by numbers generator. Recurring pitches will be colored according to a statistical distribution. Color in this case refers to the use of a specific type of orchestration to differentiate between pitches. That's not part of the program, but maybe it helps to know.
Code has been designed using a pseudocode programming process, so the comments *should* convey a detailed description of the idea and what's happening.
A fresh pair of eyes and any pointers much appreciated!
pitch.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
#pragma once
#include "c:\Users\Adam\Documents\pppuc++\std_lib_facilities.h"
namespace FisMoll {
// Create pitch space
enum class ePitchFisMoll {
fis = 1, gis, a, b, bis, cis, d, dis, e, f
};
class Pitch {
public:
Pitch(); // default constructor
Pitch(ePitchFisMoll p); // initialize with pitch from F# minor and 1 steps
// nonmodifying operations
string GetPitchAsString(Pitch p);
ePitchFisMoll GetCurrentPitch();
string GetCurrentPitchString();
// modifying operations
ePitchFisMoll TransposeUpFifth(Pitch p);
//...
private:
int steps = 1;
ePitchFisMoll current_pitch = {ePitchFisMoll::fis};
string current_pitch_string = {"fis"};
};
}// FisMoll
|
pitch.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
#include "pitch.h"
#include <iterator>
namespace FisMoll {
// Create memory bank of pitches past
unordered_map<string, int> FisMemPath({
{"fis",0},{"gis",0},{"a",0},{"b",0},{"bis",0},{"cis",0},{"d",0},{"dis",0},{"e",0},{"f",0}
});
// increment map value for key 'c'
void SetStepCountFisPathMem(string c) {
FisMemPath[c]++;
};
//-------------------------------------------------------------
// construct PitchClass
Pitch::Pitch(ePitchFisMoll pp) : current_pitch{ pp } { } // initializes pitch with a member of enum class Fis Moll
//--------------------------------------------------------------
// Function definitions
ePitchFisMoll Pitch::GetCurrentPitch() { return current_pitch; }
string Pitch::GetCurrentPitchString(){ return current_pitch_string; }
void Pitch::SetCurrentPitch(Pitch cp) { current_pitch = cp.GetCurrentPitch(); }
void Pitch::SetCurrentPitchString(Pitch cp) { current_pitch_string = cp.GetCurrentPitchString(); }
//-------------------------------------------------------------------------------------------
string Pitch::GetPitchAsString(Pitch p) {
switch (p.GetCurrentPitch()) { // returns the current pitch from ePitchFisMoll
case ePitchFisMoll::fis:
return "fis"; // return transposed pitch
break;
case ePitchFisMoll::gis:
return "gis";
break;
case ePitchFisMoll::a:
return "a";
break;
case ePitchFisMoll::b:
return "b";
break;
case ePitchFisMoll::bis:
return "bis";
break;
case ePitchFisMoll::cis:
return "cis";
break;
case ePitchFisMoll::d:
return "d";
break;
case ePitchFisMoll::dis:
return "dis";
break;
case ePitchFisMoll::e:
return "e";
break;
case ePitchFisMoll::f:
return "f";
break;
}
};
//--------------------------------------------------------------
// Define transposition functions
//
// up a fifth()
ePitchFisMoll Pitch::TransposeUpFifth(Pitch p) {
// switch over input
switch (p.GetCurrentPitch()) {
//...
}
};
// up a third()
ePitchFisMoll Pitch::TransposeUpThird(Pitch p) {
// switch over input
switch (p.GetCurrentPitch()) {
//...
};
// down a sixth()
ePitchFisMoll Pitch::TransposeDownSixth(Pitch p) {
// switch over input
switch (p.GetCurrentPitch()) {
//...
};
//------------------------------------------------------------------
// Define Path One (ePitchFisMoll p)
// Move the pitch along path
void Pitch::SetPositionOnPathOne(Pitch p) {
// count steps in local path (path is a short, recursive loop)
int step_counter = 0;
ePitchFisMoll trans_pitch;
while (step_counter < 4) {
if (step_counter < 3) {
trans_pitch = TransposeUpFifth(p.GetCurrentPitch());
step_counter++;
p.IncrementSteps();
p.SetCurrentPitch(trans_pitch);
SetCurrentPitchString(p);
SetStepCountFisPathMem(p.GetCurrentPitchString());
}
else if (step_counter < 4) {
trans_pitch = TransposeUpThird(p);
step_counter++;
p.IncrementSteps();
p.SetCurrentPitch(trans_pitch);
SetCurrentPitchString(p);
// add pass of new pitch to memory of pitches past
SetStepCountFisPathMem(p.GetCurrentPitchString());
}
else break;
}
};
//--------------------------------------------------------------
// Steph through each path recursively
// for x iterations
// track pitch p along pathOne
// initialize this function with a starting pitch
void Pitch::TracePathOne(Pitch init_pitch) {
for (int i = 0; i < 5000; ++i) {
init_pitch.SetCurrentPitch(init_pitch);
init_pitch.SetPositionOnPathOne(init_pitch);
}
};
// follow pathTwo(pitch p)
//------------------------------------------------------------------
}// Fis Moll
|
main.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
#include "pitch.cpp"
int main()
try {
using namespace FisMoll;
Pitch PPathOne(ePitchFisMoll::fis); // instantiate initial pitch on PathOne
PPathOne.TracePathOne(PPathOne);
for (auto& e : FisMemPath) {
cout << '{' << e.first << ", " << e.second << '}' << '\n';
};
}
catch (exception& e) {
cerr << "exception: " << e.what() << endl;
}
catch (...) {
cerr << "exception\n";
}
|