zoukankan      html  css  js  c++  java
  • Roland钢琴开发中音符值、度、与音名之间的转换算法

    在Roland钢琴伴侣的开发中,首先将mid文件解析出来取到每一个音符的起始时间,每一个音符的时值,音符值(比如中央C的值是60),在绘五线谱的时候需要将每一个音符值与它对应的度(octave)和音名之间相互转换。

     

    WhiteNote.h

    /**@class WhiteNote

     * The WhiteNote class represents a white keynote, a non-sharp,non-flat note.  Todisplay midi notes as sheet music, the notes

     must be converted to white notes andaccidentals.

     *

     * White notes consist of a letter (A thru G)and an octave (0 thru 10).

     * The octave changes from G to A.  After G2 comes A3.  Middle-C is C4.

     *

     * The main operations are calculatingdistances between notes, and comparing notes.

     */

    /*The table below is very important,you must be understand it.

    @class WhiteNote includes two attributes(one is ‘letter’,another is‘Octave’)

    int letter;  /* The letter of the note, A thru G */

    int octave;   /* The octave, 0 thru 10. */

    */

    这个类里面有一个很重要的枚举类型:

    /** Enumeration of the notes in a scale (A, A#, ... G#) */

    enum {

        NoteScale_A       = 0,

        NoteScale_Asharp  = 1,

        NoteScale_Bflat   = 1,

        NoteScale_B       = 2,

        NoteScale_C       = 3,

        NoteScale_Csharp  = 4,

        NoteScale_Dflat   = 4,

        NoteScale_D       = 5,

        NoteScale_Dsharp  = 6,

        NoteScale_Eflat   = 6,

        NoteScale_E       = 7,

        NoteScale_F       = 8,

        NoteScale_Fsharp  = 9,

        NoteScale_Gflat   = 9,

        NoteScale_G       = 10,

        NoteScale_Gsharp  = 11,

        NoteScale_Aflat   = 11

    };

    这个枚举里面的值和下表里面的A   A#   B    C C# D   D#   E    F    F#   G    G# 这些值一一对应。

    /**Convert a note (A, A#, B, etc) and octave into a Midi Note number.

     */

    int notescale_to_number(int notescale, int octave) {

        return 9 + notescale +octave * 12;

    }

    notescale对应上面枚举里面的值,octave对应下表的组数,举一个例,我们找到第四组的的C,在上面枚举中查找C的值和NoteScale_C的值相等(等于3),

    所以notescale_to_number(NoteScale_C, 4) = 60,刚好和第四组的C的音符值对应。这是一个通过scale和octave转换成音符的核心算法。

    第-1组

    0      1     2     3     4     5     6     7     8      

    C    C#   D    D#   E    F    F#   G    G#  

     

    第0组

    9     10   11   12   13   14   15   16   17   18

    A    A#   B     C     C#    D   D#   E    F    F#

    19   20  

    G    G#

    第1组

    21    22   23    24   25   26   27   28   29   30

    A     A#   B      C    C#    D   D#    E    F     F#  

    31   32

    G    G#

    第2组

    33   34   35    36   37   38   39   40   41   42

    A    A#   B     C    C#   D    D#    E    F     F#

    43   44     

    G    G#  

    第3组

    45   46   47    48   49   50   51   52   53   54

    A    A#   B     C    C#    D    D#    E     F    F#

    55   56

    G    G#

     

     

    第4组

    57   58   59   60   61   62   63   64   65   66   

    A    A#   B     C   C#    D     D#    E     F     F#

    67   68   

    G    G#

                   

        

    第5组

    69   70   71    72   73   74   75   76   77   78

    A    A#   B     C    C#   D    D#   E    F    F#

    79   80  

    G    G#

     

    第6组

    81   82   83    84   85   86   87   88   89   90

    A    A#   B     C    C#    D    D#   E    F     F#

    91   92  

    G    G#

     

    第7组

    93    94   95    96   97   98   99   100  101  102

    A    A#    B      C     C#   D    D#    E      F     F#

    103  104 

    G     G#

     

    第8组

    105  106  107  108  109  110  111  112  113  114

    A       A#     B     C     C#      D    D#     E        F    F#
    115  116 

    G       G#

     

     

    第9组

    117  118  119  120  121  122  123  124  125  126

    A       A#      B     C    C#      D     D#    E       F    F#

    127

     G

    接下来介绍另外一个核心方法,这个方法是将音符值转换成NoteScale枚举值,例如60,转换之后notescale_from_number(60)就等于NoteScale_C( 3 ).

    int notescale_from_number(int number) {

        return (number + 3) % 12;

    }

    /** Return true if this notescale number is a black key */

    BOOL notescale_is_black_key(int notescale) {

        if (notescale == NoteScale_Asharp ||

            notescale == NoteScale_Csharp ||

            notescale == NoteScale_Dsharp ||

            notescale == NoteScale_Fsharp ||

            notescale == NoteScale_Gsharp) {

     

            return YES;

        }

        else {

            return NO;

        }

    }

    上面这个方法是判断一个音符是否为black key.

  • 相关阅读:
    微信二维码 场景二维码 用于推送事件,关注等 注册用户 ,经过测试
    简单的 Helper 封装 -- CookieHelper
    简单的 Helper 封装 -- SecurityHelper 安全助手:封装加密算法(MD5、SHA、HMAC、DES、RSA)
    Java反射机制
    Windows Azure Web Site (13) Azure Web Site备份
    Windows Azure Virtual Machine (1) IaaS用户手册
    Windows Azure Web Site (1) 用户手册
    Windows Azure Web Site (12) Azure Web Site配置文件
    Windows Azure Web Site (11) 使用源代码管理器管理Azure Web Site
    Windows Azure Web Site (10) Web Site测试环境
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3246754.html
Copyright © 2011-2022 走看看