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