455,515 Members | 1,848 Online
Need help? Post your question and get tips & solutions from a community of 455,515 IT Pros & Developers. It's quick & easy.

# Help with code for slef similar melodies

 P: n/a I am a very amatuer c++ programmer and a somewhat accomplished composer. I am trying to write some code that creates 'self similar' melodies from a base melody the user inputs. This musical idea was created by Tom Johnson. Apologies to those who are not musically literate, but as this is basically a mathmatical problem I think most here can follow the logic. Lets keep eveything in C Major, that's all the white keys on the piano. Being as that we are in C Major, the note C will be our base note. So: C=0 D=1 E=2 F=3 G=4 A=5 B=6 (next octave up) C=7 D=8 E=9 F=10 G=11 A=12 B=13 etc... Using this, we can enter a base melody: 0, 5, 6, 4, 1, 2, 5, 0 The idea of creating self similar melodies is to take all the intervals (the distance inbetween the neighboring notes) and double them. So, from this base melody, the first iteration would be: 0, 10, 12, 8, 2, 10, 0 next iteration: 0, 20, 24, 16, 4, 20, 0 etc... So anyway, here's my code. It won't compile. Please help, and thanks for wading through this. #include #include #include using namespace std; void exp_melod_self_similar(int [], int); int main() { int note_number = 1; int melod_length; cout << "Enter length of melody in 1/8 notes:"; cin >> melod_length; int base_melod[melod_length]; do { cout << "note " << note_number; cin >> base_melod[note_number]; note_number++; } while (note_number < melod_length); exp_melod_self_similar(base_melod, melod_length); return 0; } void exp_melod_self_similar(int new_melod[], int melod_length) { int new_melod[]; new_melod[0] = base_melod[0]; for (i=1, i<=melod_length, i++) { new_melod[i] = base_melod[i] * 2; cout << new_melod[i]; } } Nov 12 '05 #1
8 Replies

 P: n/a * in*****@yahoo.com: So anyway, here's my code. It won't compile. Please help, and thanks for wading through this. I fixed the syntax errors. What remains is to fix the logic. You should also try to use more self-descriptive names. #include #include #include using namespace std; void exp_melod_self_similar(int [], int); int main() { int note_number = 1; int melod_length; cout << "Enter length of melody in 1/8 notes:"; cin >> melod_length; int base_melod[melod_length]; do { cout << "note " << note_number; cin >> base_melod[note_number]; note_number++; } while (note_number < melod_length); exp_melod_self_similar(base_melod, melod_length); return 0; } void exp_melod_self_similar(int new_melod[], int melod_length) { int new_melod[]; new_melod[0] = base_melod[0]; for (i=1, i<=melod_length, i++) { new_melod[i] = base_melod[i] * 2; cout << new_melod[i]; } } Syntax errors (but not logic) fixed -- but you should really use the std::vector 'at' member function, which provides some safety, rather than the '[]' indexing operator, and then you'll find at least one bug: #include #include #include #include void exp_melod_self_similar( std::vector& base_melod ) { std::vector new_melod( base_melod.size() ); new_melod[0] = base_melod[0]; for( int i = 1; i <= base_melod.size(); ++i ) { new_melod[i] = base_melod[i] * 2; std::cout << new_melod[i]; } } int main() { int melod_length; std::cout << "Enter length of melody in 1/8 notes:"; std::cin >> melod_length; std::vector base_melod(melod_length); for( int note_number = 1; note_number < melod_length; ++note_number ) { std::cout << "note " << note_number; std::cin >> base_melod[note_number]; } exp_melod_self_similar( base_melod ); } -- A: Because it messes up the order in which people normally read text. Q: Why is it such a bad thing? A: Top-posting. Q: What is the most annoying thing on usenet and in e-mail? Nov 12 '05 #2

 P: n/a in*****@yahoo.com wrote: I am a very amatuer c++ programmer and a somewhat accomplished composer. I am trying to write some code that creates 'self similar' melodies from a base melody the user inputs. An excellent book on learning C++ is "Accelerated C++" by Koenig & Moo. #include #include You are not using anything from #include using namespace std; void exp_melod_self_similar(int [], int); int main() { int note_number = 1; int melod_length; cout << "Enter length of melody in 1/8 notes:"; cin >> melod_length; int base_melod[melod_length]; Use std::vector< int > instead. Then you don't even have to ask how long the melody is as the vector auto-expands. do { cout << "note " << note_number; cin >> base_melod[note_number]; note_number++; } while (note_number < melod_length); A for() loop may be more readable here. exp_melod_self_similar(base_melod, melod_length); You are not freeing the memory for base_melod here. Use: delete [] base_melod; return 0; } void exp_melod_self_similar(int new_melod[], int melod_length) The parameter name is wrong. Use "base_melod" instead of new_melod here. { int new_melod[]; new_melod[0] = base_melod[0]; Why not do this in the loop? Interesting btw. because somebody pointed this out on this list not too long ago that people make this mistake. Could you explain your reasoning, since I don't understand why you would do this? for (i=1, i<=melod_length, i++) You need to declare i here. Also, use semicolons to separate the condition etc. Like so: for ( int i=0; i here would work great. Cheers, Andre Cheers, Andre Nov 12 '05 #3

 P: n/a in*****@gmail.com wrote: int main() { int note_number = 1; int melod_length; cout << "Enter length of melody in 1/8 notes:"; cin >> melod_length; int base_melod[melod_length]; Use std::vector< int > instead. Then you don't even have to ask how long the melody is as the vector auto-expands. Well, that's cool. I had no idea about vector, other than the mathmatical idea of a direction and a velocity. I have only been studying c++ for about 2 months. do { cout << "note " << note_number; cin >> base_melod[note_number]; note_number++; } while (note_number < melod_length); A for() loop may be more readable here. Okay, but when I tried doing input with a for loop on some other code for class my teacher marked me down. He said to always use a do while loop for input becuase it is guarenteed to execute once. { int new_melod[]; new_melod[0] = base_melod[0]; Why not do this in the loop? Interesting btw. because somebody pointed this out on this list not too long ago that people make this mistake. Could you explain your reasoning, since I don't understand why you would do this? Well, the idea behind self similar melodies is that they all start with the same note, so since it isn't altered, I did it outside of the loop to make sure it was always identical. for ( int i=0; i here would work great. Well, that's all greek to me for now. Thanks for the reply. Nov 22 '05 #4

 P: n/a Alf P. Steinbach wrote: I fixed the syntax errors. What remains is to fix the logic. Thanks! Syntax errors (but not logic) fixed -- but you should really use the std::vector 'at' member function, which provides some safety, rather than the '[]' indexing operator, and then you'll find at least one bug: Haven't learned to vector yet. You say it makes it safer, are you taking about over-run? #include #include #include #include void exp_melod_self_similar( std::vector& base_melod ) I don't know what's going on here. Are you passing two arguments? What's the single <&> all about, I've only used <&&> for boolean statements? { std::vector new_melod( base_melod.size() ); Don't get this at all, what is this statement even doing? new_melod[0] = base_melod[0]; for( int i = 1; i <= base_melod.size(); ++i ) { new_melod[i] = base_melod[i] * 2; std::cout << new_melod[i]; Why add the before the cout here? } } int main() { int melod_length; std::cout << "Enter length of melody in 1/8 notes:"; std::cin >> melod_length; std::vector base_melod(melod_length); for( int note_number = 1; note_number < melod_length; ++note_number ) isn't acceptable? Well, thanks for trying to help but I think I've got more questions now than I cam in with! ;) Nov 22 '05 #5