1 /*
2  * Hydrogen
3  * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
4  *
5  * http://www.hydrogen-music.org
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY, without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  */
22 
23 #include <hydrogen/midi_action.h>
24 #include <hydrogen/midi_map.h>
25 #include <map>
26 #include <QMutexLocker>
27 
28 /**
29 * @class MidiMap
30 *
31 * @brief The MidiMap maps MidiActions to MidiEvents
32 *
33 *
34 * The MidiMap stores the mapping between midi events
35 * and midi actions. Each event relates to at most 1
36 * midi action. Several events can relate to the same action.
37 * Midi events are note, mmc or cc messages.
38 *
39 *
40 * @author Sebastian Moors
41 *
42 */
43 
44 MidiMap * MidiMap::__instance = nullptr;
45 const char* MidiMap::__class_name = "MidiMap";
46 
MidiMap()47 MidiMap::MidiMap()
48 	: Object( __class_name )
49 {
50 	__instance = this;
51 	QMutexLocker mx(&__mutex);
52 
53 	//constructor
54 	for(int note = 0; note < 128; note++ ) {
55 		__note_array[ note ] = new Action("NOTHING");
56 		__cc_array[ note ] = new Action("NOTHING");
57 	}
58 	__pc_action = new Action("NOTHING");
59 }
60 
~MidiMap()61 MidiMap::~MidiMap()
62 {
63 	QMutexLocker mx(&__mutex);
64 
65 	map_t::iterator dIter( mmcMap.begin() );
66 
67 	for( dIter = mmcMap.begin(); dIter != mmcMap.end(); dIter++ ) {
68 		delete dIter->second;
69 	}
70 
71 	for( int i = 0; i < 128; i++ ) {
72 		delete __note_array[ i ];
73 		delete __cc_array[ i ];
74 	}
75 	delete __pc_action;
76 
77 	__instance = nullptr;
78 }
79 
create_instance()80 void MidiMap::create_instance()
81 {
82 	if( __instance == nullptr ) {
83 		__instance = new MidiMap;
84 	}
85 }
86 
reset_instance()87 void MidiMap::reset_instance()
88 {
89 	create_instance();
90 	__instance->reset();
91 }
92 
93 
94 /**
95  * Clears the complete midi map and releases the memory
96  * of the contained actions
97  */
reset()98 void MidiMap::reset()
99 {
100 	QMutexLocker mx(&__mutex);
101 
102 	map_t::iterator iter;
103 	for( iter = mmcMap.begin() ; iter != mmcMap.end() ; ++iter ) {
104 		delete iter->second;
105 	}
106 	mmcMap.clear();
107 
108 	int i;
109 	for( i = 0 ; i < 128 ; ++i ) {
110 		delete __note_array[ i ];
111 		delete __cc_array[ i ];
112 		__note_array[ i ] = new Action("NOTHING");
113 		__cc_array[ i ] = new Action("NOTHING");
114 	}
115 
116 	delete __pc_action;
117 	__pc_action = new Action("NOTHING");
118 }
119 
120 
getMMCMap()121 std::map< QString, Action* > MidiMap::getMMCMap()
122 {
123 	return mmcMap;
124 }
125 
126 
127 /**
128  * Sets up the relation between a mmc event and an action
129  */
registerMMCEvent(QString eventString,Action * pAction)130 void MidiMap::registerMMCEvent( QString eventString , Action* pAction )
131 {
132 	QMutexLocker mx(&__mutex);
133 
134 	if( mmcMap[ eventString ] != nullptr){
135 		delete mmcMap[ eventString ];
136 	}
137 	mmcMap[ eventString ] = pAction;
138 }
139 
140 
141 /**
142  * Sets up the relation between a note event and an action
143  */
registerNoteEvent(int note,Action * pAction)144 void MidiMap::registerNoteEvent( int note, Action* pAction )
145 {
146 	QMutexLocker mx(&__mutex);
147 	if( note >= 0 && note < 128 ) {
148 		delete __note_array[ note ];
149 		__note_array[ note ] = pAction;
150 	}
151 }
152 
153 
154 /**
155  * Sets up the relation between a cc event and an action
156  */
registerCCEvent(int parameter,Action * pAction)157 void MidiMap::registerCCEvent( int parameter , Action * pAction ){
158 	QMutexLocker mx(&__mutex);
159 	if( parameter >= 0 and parameter < 128 )
160 	{
161 		delete __cc_array[ parameter ];
162 		__cc_array[ parameter ] = pAction;
163 	}
164 }
165 
findCCValueByActionParam1(QString actionType,QString param1)166 int MidiMap::findCCValueByActionParam1( QString actionType, QString param1 )
167 {
168 	int nParam = -1;
169 
170 	for(int i=0; i < 128; i++)
171 	{
172 		Action* pTmpAction = __cc_array[i];
173 
174 		if(    pTmpAction->getType() == actionType
175 			&& pTmpAction->getParameter1() == param1 ){
176 			nParam = i;
177 		}
178 	}
179 
180 	return nParam;
181 }
182 
findCCValueByActionType(QString actionType)183 int MidiMap::findCCValueByActionType( QString actionType )
184 {
185 	int nParam = -1;
186 
187 	for(int i=0; i < 128; i++)
188 	{
189 		Action* pTmpAction = __cc_array[i];
190 
191 		if( pTmpAction->getType() == actionType ){
192 			nParam = i;
193 		}
194 	}
195 
196 	return nParam;
197 }
198 
199 /**
200  * Sets up the relation between a program change and an action
201  */
registerPCEvent(Action * pAction)202 void MidiMap::registerPCEvent( Action * pAction ){
203 	QMutexLocker mx(&__mutex);
204 	delete __pc_action;
205 	__pc_action = pAction;
206 }
207 
208 /**
209  * Returns the mmc action which was linked to the given event.
210  */
getMMCAction(QString eventString)211 Action* MidiMap::getMMCAction( QString eventString )
212 {
213 	QMutexLocker mx(&__mutex);
214 	std::map< QString, Action *>::iterator dIter = mmcMap.find( eventString );
215 	if ( dIter == mmcMap.end() ){
216 		return nullptr;
217 	}
218 
219 	return mmcMap[eventString];
220 }
221 
222 /**
223  * Returns the note action which was linked to the given event.
224  */
getNoteAction(int note)225 Action* MidiMap::getNoteAction( int note )
226 {
227 	QMutexLocker mx(&__mutex);
228 	return __note_array[ note ];
229 }
230 
231 /**
232  * Returns the cc action which was linked to the given event.
233  */
getCCAction(int parameter)234 Action * MidiMap::getCCAction( int parameter )
235 {
236 	QMutexLocker mx(&__mutex);
237 	return __cc_array[ parameter ];
238 }
239 
240 /**
241  * Returns the pc action which was linked to the given event.
242  */
getPCAction()243 Action * MidiMap::getPCAction()
244 {
245 	QMutexLocker mx(&__mutex);
246 	return __pc_action;
247 }
248 
249