1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     snd_MidiSequencePlayer.h
4 
5   Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Revision: 22432 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NW_SND_MIDI_SEQUENCE_PLAYER_H_
17 #define NW_SND_MIDI_SEQUENCE_PLAYER_H_
18 
19 #include <nw/snd/snd_SequenceSoundPlayer.h>
20 #include <nw/snd/snd_Channel.h>
21 
22 namespace nw {
23 namespace snd {
24 namespace internal {
25 namespace driver {
26 
27 /* ========================================================================
28         class definition
29    ======================================================================== */
30 
31 class MidiSequencePlayer : public SequenceSoundPlayer
32 {
33     /* ------------------------------------------------------------------------
34             type definition
35        ------------------------------------------------------------------------ */
36   public:
37     enum {
38         MIDI_MSG_NOTE_OFF = 0x80,
39         MIDI_MSG_NOTE_ON = 0x90,
40         MIDI_MSG_POLY_KEY_PRESSURE = 0xa0,
41         MIDI_MSG_CONTROL_CHANGE = 0xb0,
42         MIDI_MSG_PROGRAM_CHANGE = 0xc0,
43         MIDI_MSG_CHANNEL_PRESSURE = 0xd0,
44         MIDI_MSG_PITCH_BEND = 0xe0,
45         MIDI_MSG_SYSTEM = 0xf0
46     };
47 
48     enum {
49         MIDI_CTRLCHG_BANK_SELECT = 0,
50         MIDI_CTRLCHG_MOD_DEPTH = 1,
51         MIDI_CTRLCHG_INIT_PAN = 3,
52         MIDI_CTRLCHG_PORTA_TIME = 5,
53         MIDI_CTRLCHG_DATA_ENTRY = 6,
54         MIDI_CTRLCHG_VOLUME = 7,
55         MIDI_CTRLCHG_SPAN = 9,
56         MIDI_CTRLCHG_PAN = 10,
57         MIDI_CTRLCHG_EXPRESSION = 11,
58         MIDI_CTRLCHG_MAIN_VOLUME = 12,
59         MIDI_CTRLCHG_TRANSPOSE = 13,
60         MIDI_CTRLCHG_PRIORITY = 14,
61         MIDI_CTRLCHG_SETVAR_0 = 16,
62         MIDI_CTRLCHG_SETVAR_1 = 17,
63         MIDI_CTRLCHG_SETVAR_2 = 18,
64         MIDI_CTRLCHG_SETVAR_3 = 19,
65         MIDI_CTRLCHG_BEND_RANGE = 20,
66         MIDI_CTRLCHG_MOD_SPEED = 21,
67         MIDI_CTRLCHG_MOD_TYPE = 22,
68         MIDI_CTRLCHG_MOD_RANGE = 23,
69         MIDI_CTRLCHG_MOD_DELAY = 26,
70         MIDI_CTRLCHG_MOD_DELAY_10 = 27,
71         MIDI_CTRLCHG_SWEEP_PITCH = 28,
72         MIDI_CTRLCHG_SWEEP_PITCH_24 = 29,
73         MIDI_CTRLCHG_BIQUAD_TYPE = 30,
74         MIDI_CTRLCHG_BIQUAD_VALUE = 31,
75         MIDI_CTRLCHG_DAMPER = 64,
76         MIDI_CTRLCHG_PORTA = 65,
77         MIDI_CTRLCHG_MONOPHONIC = 68,
78         MIDI_CTRLCHG_CUTOFF = 74,
79         MIDI_CTRLCHG_ENV_HOLD = 79,
80         MIDI_CTRLCHG_PORTA_CONTROL = 84,
81         MIDI_CTRLCHG_ATTACK = 85,
82         MIDI_CTRLCHG_DECAY = 86,
83         MIDI_CTRLCHG_SUSTAIN = 87,
84         MIDI_CTRLCHG_RELEASE = 88,
85         MIDI_CTRLCHG_FXSEND_A = 91,
86         MIDI_CTRLCHG_FXSEND_B = 92,
87         MIDI_CTRLCHG_FXSEND_C = 93,
88         MIDI_CTRLCHG_MAINSEND = 95,
89         MIDI_CTRLCHG_NRPN_LSB = 98,
90         MIDI_CTRLCHG_NRPN_MSB = 99,
91         MIDI_CTRLCHG_RPN_LSB = 100,
92         MIDI_CTRLCHG_RPN_MSB = 101,
93         MIDI_CTRLCHG_FRONTBYPASS =119
94     };
95 
96     enum {
97         MIDI_MODEMSG_ALL_SOUND_OFF = 120,
98         MIDI_MODEMSG_RESET_ALL_CONTROLER = 121,
99         MIDI_MODEMSG_LOCAL_CONTROL = 122,
100         MIDI_MODEMSG_ALL_NOTE_OFF = 123,
101         MIDI_MODEMSG_OMNI_OFF = 124,
102         MIDI_MODEMSG_OMNI_ON = 125,
103         MIDI_MODEMSG_MONO_MODE = 126,
104         MIDI_MODEMSG_POLY_MODE = 127
105     };
106 
107     enum {
108         // ( msb << 8 ) + lsb
109         MIDI_RPN_PITCHBEND_SENSITIVITY = ( 0 << 8 ) + 0,
110         MIDI_RPN_NULL = ( 127 << 8 ) + 127
111     };
112 
113     enum {
114         // ( msb << 8 ) + lsb
115         MIDI_NRPN_ENV_RESET = ( 0 << 8 ) + 0,
116         MIDI_NRPN_NULL = ( 127 << 8 ) + 127
117     };
118 
119     static const int NOTE_INFO_COUNT = Channel::CHANNEL_NUM;
120 
121     struct NoteInfo
122     {
123         Channel* channel;
124         int channelIndex;
125         int key;
126     };
127 
128     struct ParameterControlInfo
129     {
130         enum Mode { RPN, NRPN };
131 
132         Mode mode;
133         u8 rpnLsb;
134         u8 rpnMsb;
135         u8 nrpnLsb;
136         u8 nrpnMsb;
137 
ParameterControlInfoParameterControlInfo138         ParameterControlInfo()
139         : mode(RPN),
140           rpnLsb(127),
141           rpnMsb(127),
142           nrpnLsb(127),
143           nrpnMsb(127)
144         {}
145     };
146 
147     /* ------------------------------------------------------------------------
148             class member
149        ------------------------------------------------------------------------ */
150   public:
151     MidiSequencePlayer();
152     virtual ~MidiSequencePlayer();
153 
154     virtual void Start();
155 
156     void SendMessage( u8 status, u8 data1, u8 data2 );
157     void Reset();
158 
159     void SetProgramNumber( int channelIndex, int prgNo );
160 
161   protected:
162     virtual void ChannelCallback( Channel* channel );
163 
164   private:
165     void NoteOn( u8 channelIndex, u8 key, u8 velocity );
166     void NoteOff( u8 channelIndex, u8 key, u8 velocity );
167 
168     void HandleControlChangeMessage( u8 channelIndex, u8 control, u8 value );
169     void HandleRpnMessage( u8 channelIndex, u8 value );
170     void HandleNrpnMessage( u8 channelIndex, u8 value );
171     void HandleChannelModeMessage( u8 control, u8 value );
172     void HandleProgramChangeMessage( u8 channelIndex, u8 program );
173     void HandlePitchBendMessage( u8 channelIndex, u8 lsb, u8 msb );
174 
175     void NoteOffAll();
176     void StopAllSound();
177     void ResetAllController();
178 
179     NoteInfo* FindFreeNoteInfo();
180     NoteInfo* FindNoteInfo( int channelIndex, int key );
181     NoteInfo* FindNoteInfo( int channelIndex );
182 
183     NoteInfo m_NoteInfo[ NOTE_INFO_COUNT ];
184     ParameterControlInfo m_ParameterControlInfo[ TRACK_NUM_PER_PLAYER ];
185 };
186 
187 } // namespace nw::snd::internal::driver
188 } // namespace nw::snd::internal
189 } // namespace nw::snd
190 } // namespace nw
191 
192 
193 #endif /* NW_SND_MIDI_SEQUENCE_PLAYER_H_ */
194 
195