writing a program which helps the tudio to convert midi note number to name and octave

Viewed 180

I want to write a C++ program that converts MIDI note number to name and octave using the switch statements ?

I am having a few errors in my code the code should print out a Note name and octave number (eg. input -> 24 ; output -> C1).

https://www.inspiredacoustics.com/en/MIDI_note_numbers_and_center_frequencies

int main() {
    int mi;
    cout <<"MIDI value: " << std::endl;
    cin >> mi;

    int oct_v;
    oct_v = (mi/12) - 1;

    string notes;
    notes = "C C# D D# E F F# G G# A A# B";

    string nt;
    nt = notes.substr((mi % 12) * 2 , (mi % 12) * 2 +2);

    cout <<"Note name " << nt << oct_v;

    return 0;
}

The code is not perfect and I am having doubts about what should I put into switch statements.

2 Answers

First some hints:

"I want to write a C++ script"

The term script is typically used for interpreted languages like shell scripts. As c++ is a compiled language we don't name them script. It is a c++ program or c++ source code.

" what should I put into switch statements."

You don't use any switch statement! You pick some substring from a string. That has nothing to do with a switch statement!

What is wrong with your code:

Your calculation for picking the sub string is quite fine, but you assume that your notes inside your string are always have a length of 2 but you use 2 chars for e.g. "C " or 3 chars for "A# ". You simply should write your string with 2 letters per note as:

std::string notes = "C C#D D#E F F#G G#A A#B";

The second parameter of substr is the length and not the end position.

In addition: You should not use using namespace std;

Here are some alternative solutions also with switch statement.

int main() {
    int mi;
    std::cout <<"MIDI value: " << std::endl;
    std::cin >> mi;

    unsigned int oct_v = mi/12 -1;

    // variant with array
    std::string notes[]={"C","C#","D","D#","E","F","F#","G","G#","A","A#","B"};
    std::string nt = notes[mi%12];

    // variant with substring ( from your code, but fixed )
    std::string notes2= "C C#D D#E F F#G G#A A#B";
    std::string nt2 = notes2.substr((mi % 12) * 2 , 2);

    std::string nt3;

    // with switch
    switch ( mi%12 )
    {
        case 0: nt3 = "C"; break;
        case 1: nt3 = "C#"; break;
        case 2: nt3 = "D"; break;
        case 3: nt3 = "D#"; break;
        case 4: nt3 = "E"; break;
        case 5: nt3 = "F"; break;
        case 6: nt3 = "F#"; break;
        case 7: nt3 = "G"; break;
        case 8: nt3 = "G#"; break;
        case 9: nt3 = "A"; break;
        case 10: nt3 = "A#"; break;
        case 11: nt3 = "B"; break;
    }


    std::cout <<"Note name  " << nt << ":" << oct_v << std::endl;
    std::cout <<"Note name2 " << nt2 << ":" << oct_v << std::endl;
    std::cout <<"Note name3 " << nt3 << ":" << oct_v << std::endl;

    return 0;
}

I think you'd better use a table of char arrays to store the notes. I propose the following code :

#include <iostream>
#include <string>

const char notes[12][4]={"C","C#","D","D#","E","F","F#","G","G#","A","A#","B"};

void midiToNote(int midi, int& octave,std::string& note)
{
octave = ( (midi-12)/12 );
note = std::string(notes[midi%12]);
}

int main()
{
int midi;
int oct;
std::string name;

midi = 29;
midiToNote(midi,oct,name);
std::cout << midi <<" is  " <<name << oct<< std::endl;

midi = 51;
midiToNote(midi,oct,name);
std::cout << midi <<" is  "<< name << oct << std::endl;



return 0;

}

Hope this helps.

Related