File: StavePosition.h

package info (click to toggle)
pianobooster 0.6.7~svn156-1
  • links: PTS, VCS
  • area: main
  • in suites: buster, stretch
  • size: 2,796 kB
  • ctags: 1,930
  • sloc: cpp: 11,738; makefile: 66; ansic: 26
file content (163 lines) | stat: -rw-r--r-- 6,050 bytes parent folder | download
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
151
152
153
154
155
156
157
158
159
160
161
162
163
/*********************************************************************************/
/*!
@file           StavePosition.h

@brief          xxxxxx.

@author         L. J. Barman

    Copyright (c)   2008-2009, L. J. Barman, all rights reserved

    This file is part of the PianoBooster application

    PianoBooster is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    PianoBooster is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with PianoBooster.  If not, see <http://www.gnu.org/licenses/>.

*/
/*********************************************************************************/

#ifndef __STAVE_POS_H__
#define __STAVE_POS_H__

#include "Util.h"
#include "Chord.h"

#include <stdio.h>

typedef  struct {
    int pianoNote;   // 1 is Middle C, 2 is D
    int accidental;
} staveLookup_t;

#define NOT_USED 0x7fffffff

#define MAX_STAVE_INDEX 16
#define MIN_STAVE_INDEX -16

//----------------------------------------------------------------------------
// CStavePos
//----------------------------------------------------------------------------
//! @brief Calculates the position on the stave from the stave index number.
class CStavePos
{
public:
    ////////////////////////////////////////////////////////////////////////////////
    //! @brief The default constructor.
    CStavePos()
    {
        m_staveIndex = 0;
        m_accidental = 0;
        setHand(PB_PART_none);
    };

    ////////////////////////////////////////////////////////////////////////////////
    //! @brief Constructs the Stave position object.
    //! @param hand         the top (right hand) or the bottom the (left hand) see @ref whichPart_t.
    //! @param index        the save index number: 0 central line, 5 = top line, -5 the bottom line.
    //! @param accidental   Indicates an accidental 0 = none, 1=sharp, -1 =flat.
    CStavePos(whichPart_t hand, int index, int accidental = 0)
    {
        m_staveIndex = index;
        m_accidental = accidental;
        setHand(hand);
    };

    ////////////////////////////////////////////////////////////////////////////////
    //! @brief Sets which stave the note will appear on
    //! @param hand         the top (right hand) or the bottom the (left hand) see @ref whichPart_t.
    void setHand(whichPart_t hand)
    {
        m_hand = hand;
        m_offsetY = getStaveCenterY();
        if (m_hand == PB_PART_right)
            m_offsetY += staveCentralOffset();
        else if (m_hand == PB_PART_left)
            m_offsetY -= staveCentralOffset();
    }

    void notePos(whichPart_t hand, int midiNote);


    ////////////////////////////////////////////////////////////////////////////////
    //! @brief Sets which stave the note will appear on
    //! return          The position on the stave.
    float getPosY()
    {
        return verticalNoteSpacing() * m_staveIndex + m_offsetY ;
    }

    float getPosYAccidental() {
        int accidental = m_accidental;
        if (accidental == 2) accidental = 1;
        else if (accidental == -2) accidental = -1;
        return getPosY() + accidental*verticalNoteSpacing()/2;
    }
    float getPosYRelative() { return getPosY() - m_staveCenterY;} // get the Y position relative to the stave centre

    ////////////////////////////////////////////////////////////////////////////////
    //! @brief          The accidental
    //! return          0 = none, 1=sharp, -1 =flat, 2=natural.
    int getAccidental() {return m_accidental;}

    int getStaveIndex() {return m_staveIndex;}
    whichPart_t getHand() {return m_hand;}

    static float getVerticalNoteSpacing(){return verticalNoteSpacing();}
    static float getStaveCenterY(){return m_staveCenterY;}
    static void setStaveCenterY(float y) { m_staveCenterY = y; }
    static void setKeySignature(int key, int majorMinor);
    static int getKeySignature() {return m_KeySignature;}
    static void setStaveCentralOffset(float gap) { m_staveCentralOffset = gap; }
    static float verticalNoteSpacing()      {return 7;}
    static float staveHeight()              {return verticalNoteSpacing() * 8;}
    static float staveCentralOffset()       {return m_staveCentralOffset;}
    // convert the midi note to the note name A B C D E F G
    static staveLookup_t midiNote2Name(int midiNote);
    static const staveLookup_t* getstaveLookupTable(int key);
    
    // do we show a sharp or a flat for this key signature
    // returns 0 = none, 1=sharp, -1 =flat, 2=natural (# Key) , -2=natural (b Key)
    static int getStaveAccidental(int midiNote)
    {
        return m_staveLookUpTable[midiNote%12].accidental;
    }

    // returns 0 = none, 1=above, -1 =below, (a natural is either above or below)
    static int getStaveAccidentalDirection(int midiNote)
    {
        int accidentalDirection = getStaveAccidental(midiNote);
        if (accidentalDirection == 2) // A natural so change to above
            accidentalDirection = 1;
        else if (accidentalDirection == -2) // A natural so change to below
            accidentalDirection = -1;           
            
        return accidentalDirection;
    }


private:
    // fixme TODO This could be improved as the calculations could a done in the constructor
    int m_staveIndex;    // 0 central line, 5 = top line, -5 the bottom line,
    int m_accidental;         // 0 = none, 1=sharp, -1 =flat, 2=natural
    float m_offsetY;
    whichPart_t m_hand;


    static int m_KeySignature;
    static int m_KeySignatureMajorMinor;
    static const staveLookup_t*  m_staveLookUpTable;
    static float m_staveCentralOffset;
    static float m_staveCenterY;
};

#endif //__STAVE_POS_H__