编写一个程序,帮助 tudio 将 midi 音符编号转换为名称和八度

Posted

技术标签:

【中文标题】编写一个程序,帮助 tudio 将 midi 音符编号转换为名称和八度【英文标题】:writing a program which helps the tudio to convert midi note number to name and octave 【发布时间】:2020-06-13 20:02:30 【问题描述】:

我想编写一个 C++ 程序,使用 switch 语句将 MIDI 音符编号转换为名称和八度?

我的代码中有一些错误,代码应该打印出一个音符名称和八度数(例如,输入 -> 24 ;输出 -> 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;

代码并不完美,我怀疑应该在 switch 语句中添加什么。

【问题讨论】:

“我想写一个 C++ 脚本”——术语很重要。 C++不是脚本语言。 很抱歉,你能帮我完成这个项目吗? 【参考方案1】:

首先一些提示:

“我想写一个 C++ 脚本”

script 一词通常用于解释型语言,如 shell 脚本。由于 c++ 是一种编译语言,我们不将它们命名为 script。它是一个 c++ 程序或 c++ 源代码。

" 我应该在 switch 语句中添加什么。"

你没有使用任何 switch 语句!您从字符串中选择一些子字符串。这与 switch 语句无关!

你的代码有什么问题:

您选择子字符串的计算非常好,但是您假设字符串中的音符始终具有 2 的长度,但您使用 2 个字符,例如“C”或“A#”的 3 个字符。您只需将每个音符的字符串写成 2 个字母:

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

substr的第二个参数是长度,不是结束位置。

另外:你不应该使用using namespace std;

这里还有一些带有 switch 语句的替代解决方案。

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;

【讨论】:

【参考方案2】:

我认为您最好使用 char 数组表来存储笔记。我建议以下代码:

#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;


希望这会有所帮助。

【讨论】:

欣赏!

以上是关于编写一个程序,帮助 tudio 将 midi 音符编号转换为名称和八度的主要内容,如果未能解决你的问题,请参考以下文章

如何用 Python 编写 MIDI 文件?

在播放时捕捉 MIDI 音符?

在 IOS 上使用 AudioKit 将声音文件作为 MIDI 音符发送

C++ 在音符中转换 MIDI 音符 ID

iOS AUSampler 连续播放 MIDI 音符

iOS如何播放midi音符?