Rev 1542 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1131 | tk | 1 | /* -*- mode:C++; tab-width:4; c-basic-offset:4; indent-tabs-mode:nil -*- */ |
2 | // $Id: MbCvTool.cpp 936 2010-02-28 01:27:18Z tk $ |
||
3 | /* |
||
4 | * MBHP_MF Tool Window |
||
5 | * |
||
6 | * ========================================================================== |
||
7 | * |
||
8 | * Copyright (C) 2010 Thorsten Klose (tk@midibox.org) |
||
9 | * Licensed for personal non-commercial use only. |
||
10 | * All other rights reserved. |
||
11 | * |
||
12 | * ========================================================================== |
||
13 | */ |
||
14 | |||
15 | #include "MbhpMfTool.h" |
||
16 | #include "MiosStudio.h" |
||
17 | |||
18 | |||
19 | MbhpMfToolConfigGlobals::MbhpMfToolConfigGlobals(MbhpMfTool* _mbhpMfTool) |
||
20 | : mbhpMfTool(_mbhpMfTool) |
||
21 | { |
||
22 | addAndMakeVisible(nameLabel = new Label(String::empty, T("Patch Name:"))); |
||
23 | nameLabel->setJustificationType(Justification::right); |
||
24 | addAndMakeVisible(nameEditor = new TextEditor(String::empty)); |
||
25 | nameEditor->setTextToShowWhenEmpty(T("<No Name>"), Colours::grey); |
||
26 | nameEditor->setInputRestrictions(16); |
||
27 | |||
28 | addAndMakeVisible(numberFadersLabel = new Label(String::empty, T("Number of Faders:"))); |
||
29 | numberFadersLabel->setJustificationType(Justification::right); |
||
30 | addAndMakeVisible(numberFadersSlider = new Slider(T("Number of Faders"))); |
||
31 | numberFadersSlider->setWantsKeyboardFocus(true); |
||
32 | numberFadersSlider->setSliderStyle(Slider::LinearHorizontal); |
||
33 | numberFadersSlider->setTextBoxStyle(Slider::TextBoxLeft, false, 80, 20); |
||
34 | numberFadersSlider->setRange(1, 8, 1); |
||
35 | numberFadersSlider->setValue(8); |
||
36 | numberFadersSlider->addListener(this); |
||
37 | |||
38 | addAndMakeVisible(operationModeLabel = new Label(String::empty, T("Operation Mode:"))); |
||
39 | operationModeLabel->setJustificationType(Justification::right); |
||
40 | addAndMakeVisible(operationModeComboBox = new ComboBox(String::empty)); |
||
41 | operationModeComboBox->setWantsKeyboardFocus(true); |
||
42 | operationModeComboBox->addItem(T("PitchBender Chn#1..#8"), 1); |
||
43 | operationModeComboBox->addItem(T("PitchBender Chn#9..#16"), 2); |
||
1464 | tk | 44 | operationModeComboBox->addItem(T("CC#7 Chn#1..#8"), 3); |
45 | operationModeComboBox->addItem(T("CC#7 Chn#9..#16"), 4); |
||
46 | operationModeComboBox->addItem(T("CC#0..#7 Chn#1"), 5); |
||
47 | operationModeComboBox->addItem(T("CC#8..#15 Chn#1"), 6); |
||
48 | operationModeComboBox->addItem(T("CC#16..#23 Chn#1"), 7); |
||
49 | operationModeComboBox->addItem(T("CC#24..#31 Chn#1"), 8); |
||
50 | operationModeComboBox->addItem(T("CC#32..#39 Chn#1"), 9); |
||
51 | operationModeComboBox->addItem(T("CC#40..#47 Chn#1"), 10); |
||
52 | operationModeComboBox->addItem(T("CC#48..#55 Chn#1"), 11); |
||
53 | operationModeComboBox->addItem(T("CC#56..#63 Chn#1"), 12); |
||
54 | operationModeComboBox->addItem(T("CC#64..#71 Chn#1"), 13); |
||
55 | operationModeComboBox->addItem(T("CC#72..#79 Chn#1"), 14); |
||
56 | operationModeComboBox->addItem(T("CC#80..#87 Chn#1"), 15); |
||
57 | operationModeComboBox->addItem(T("CC#88..#95 Chn#1"), 16); |
||
58 | operationModeComboBox->addItem(T("CC#96..#103 Chn#1"), 17); |
||
59 | operationModeComboBox->addItem(T("CC#104..#111 Chn#1"), 18); |
||
60 | operationModeComboBox->addItem(T("CC#112..#119 Chn#1"), 19); |
||
61 | operationModeComboBox->addItem(T("CC#120..#127 Chn#1"), 20); |
||
1481 | tk | 62 | operationModeComboBox->addItem(T("Emulated Logic Control"), 21); |
63 | operationModeComboBox->addItem(T("Emulated Logic Control Extension"), 22); |
||
64 | operationModeComboBox->addItem(T("Emulated Mackie Control"), 23); |
||
65 | operationModeComboBox->addItem(T("Emulated Mackie Control Extension"), 24); |
||
66 | operationModeComboBox->addItem(T("Emulated Mackie HUI"), 25); |
||
67 | operationModeComboBox->addItem(T("Emulated Motormix"), 26); |
||
1131 | tk | 68 | operationModeComboBox->setSelectedId(1, true); |
1133 | tk | 69 | operationModeComboBox->addListener(this); |
1131 | tk | 70 | |
1505 | tk | 71 | addAndMakeVisible(midiChannelLabel = new Label(String::empty, T("MIDI Channel:"))); |
72 | midiChannelLabel->setJustificationType(Justification::right); |
||
73 | addAndMakeVisible(midiChannelSlider = new Slider(T("MIDI Channel"))); |
||
74 | midiChannelSlider->setWantsKeyboardFocus(true); |
||
75 | midiChannelSlider->setSliderStyle(Slider::LinearHorizontal); |
||
76 | midiChannelSlider->setTextBoxStyle(Slider::TextBoxLeft, false, 80, 20); |
||
77 | midiChannelSlider->setRange(1, 16, 1); |
||
78 | midiChannelSlider->setValue(1); |
||
79 | midiChannelSlider->addListener(this); |
||
80 | |||
1131 | tk | 81 | addAndMakeVisible(mergerLabel = new Label(String::empty, T("MIDI Merger:"))); |
82 | mergerLabel->setJustificationType(Justification::right); |
||
83 | addAndMakeVisible(mergerComboBox = new ComboBox(String::empty)); |
||
84 | mergerComboBox->setWantsKeyboardFocus(true); |
||
85 | mergerComboBox->addItem(T("Disabled"), 1); |
||
86 | mergerComboBox->addItem(T("Enabled (received MIDI events forwarded to MIDI Out)"), 2); |
||
1134 | tk | 87 | mergerComboBox->addItem(T("MIDIbox Link Endpoint (last core in the MIDIbox chain)"), 3); |
88 | mergerComboBox->addItem(T("MIDIbox Link Forwarding Point (core in a MIDIbox chain)"), 4); |
||
1131 | tk | 89 | mergerComboBox->setSelectedId(1, true); |
1133 | tk | 90 | mergerComboBox->addListener(this); |
1131 | tk | 91 | |
92 | addAndMakeVisible(pwmStepsLabel = new Label(String::empty, T("PWM Steps:"))); |
||
93 | pwmStepsLabel->setJustificationType(Justification::right); |
||
94 | addAndMakeVisible(pwmStepsSlider = new Slider(T("PWM Period"))); |
||
95 | pwmStepsSlider->setWantsKeyboardFocus(true); |
||
96 | pwmStepsSlider->setSliderStyle(Slider::LinearHorizontal); |
||
97 | pwmStepsSlider->setTextBoxStyle(Slider::TextBoxLeft, false, 80, 20); |
||
98 | pwmStepsSlider->setRange(0, 255, 1); |
||
99 | pwmStepsSlider->setValue(64); |
||
100 | pwmStepsSlider->addListener(this); |
||
101 | |||
102 | addAndMakeVisible(ainDeadbandLabel = new Label(String::empty, T("AIN Deadband:"))); |
||
103 | ainDeadbandLabel->setJustificationType(Justification::right); |
||
104 | addAndMakeVisible(ainDeadbandSlider = new Slider(T("AIN Deadband"))); |
||
105 | ainDeadbandSlider->setWantsKeyboardFocus(true); |
||
106 | ainDeadbandSlider->setSliderStyle(Slider::LinearHorizontal); |
||
107 | ainDeadbandSlider->setTextBoxStyle(Slider::TextBoxLeft, false, 80, 20); |
||
108 | ainDeadbandSlider->setRange(0, 63, 1); |
||
109 | ainDeadbandSlider->setValue(3); |
||
110 | ainDeadbandSlider->addListener(this); |
||
111 | |||
112 | addAndMakeVisible(mfDeadbandLabel = new Label(String::empty, T("MF Deadband:"))); |
||
113 | mfDeadbandLabel->setJustificationType(Justification::right); |
||
114 | addAndMakeVisible(mfDeadbandSlider = new Slider(T("MF Deadband"))); |
||
115 | mfDeadbandSlider->setWantsKeyboardFocus(true); |
||
116 | mfDeadbandSlider->setSliderStyle(Slider::LinearHorizontal); |
||
117 | mfDeadbandSlider->setTextBoxStyle(Slider::TextBoxLeft, false, 80, 20); |
||
118 | mfDeadbandSlider->setRange(0, 63, 1); |
||
119 | mfDeadbandSlider->setValue(3); |
||
120 | mfDeadbandSlider->addListener(this); |
||
121 | |||
122 | addAndMakeVisible(touchSensorModeLabel = new Label(String::empty, T("TouchSensor Mode:"))); |
||
123 | touchSensorModeLabel->setJustificationType(Justification::right); |
||
124 | addAndMakeVisible(touchSensorModeComboBox = new ComboBox(String::empty)); |
||
125 | touchSensorModeComboBox->setWantsKeyboardFocus(true); |
||
126 | touchSensorModeComboBox->addItem(T("Disabled"), 1); |
||
127 | touchSensorModeComboBox->addItem(T("Pressed/Depressed Events forwarded to MIDI Out"), 2); |
||
128 | touchSensorModeComboBox->addItem(T("Like previous, but additionally motors will be suspended"), 3); |
||
129 | touchSensorModeComboBox->addItem(T("Like previous, but additionally no fader event as long as sensor not pressed"), 4); |
||
130 | touchSensorModeComboBox->setSelectedId(2, true); |
||
1133 | tk | 131 | touchSensorModeComboBox->addListener(this); |
1131 | tk | 132 | |
133 | addAndMakeVisible(touchSensorSensitivityLabel = new Label(String::empty, T("Touchsensor Sensitivity:"))); |
||
134 | touchSensorSensitivityLabel->setJustificationType(Justification::right); |
||
135 | addAndMakeVisible(touchSensorSensitivitySlider = new Slider(T("Touchsensor Sensitivity"))); |
||
136 | touchSensorSensitivitySlider->setWantsKeyboardFocus(true); |
||
137 | touchSensorSensitivitySlider->setSliderStyle(Slider::LinearHorizontal); |
||
138 | touchSensorSensitivitySlider->setTextBoxStyle(Slider::TextBoxLeft, false, 80, 20); |
||
139 | touchSensorSensitivitySlider->setRange(1, 32, 1); |
||
140 | touchSensorSensitivitySlider->setValue(3); |
||
141 | touchSensorSensitivitySlider->addListener(this); |
||
142 | |||
143 | } |
||
144 | |||
145 | |||
146 | MbhpMfToolConfigGlobals::~MbhpMfToolConfigGlobals() |
||
147 | { |
||
148 | } |
||
149 | |||
150 | //============================================================================== |
||
151 | void MbhpMfToolConfigGlobals::resized() |
||
152 | { |
||
153 | int labelX = 10; |
||
154 | int labelY0 = 10; |
||
155 | int labelYOffset = 28; |
||
156 | int labelWidth = 250; |
||
157 | int labelHeight = 24; |
||
158 | |||
159 | int controlX = labelX + labelWidth + 20; |
||
160 | int controlY0 = labelY0; |
||
161 | int controlYOffset = labelYOffset; |
||
162 | int controlWidth = getWidth()-labelWidth-40-2*labelX; |
||
163 | int controlHeight = labelHeight; |
||
164 | |||
165 | nameLabel->setBounds(labelX, labelY0 + 0*labelYOffset, labelWidth, labelHeight); |
||
166 | nameEditor->setBounds(controlX, controlY0 + 0*controlYOffset, controlWidth, controlHeight); |
||
167 | |||
168 | numberFadersLabel->setBounds(labelX, labelY0 + 1*labelYOffset, labelWidth, labelHeight); |
||
169 | numberFadersSlider->setBounds(controlX, controlY0 + 1*controlYOffset, controlWidth, controlHeight); |
||
170 | |||
171 | operationModeLabel->setBounds(labelX, labelY0 + 2*labelYOffset, labelWidth, labelHeight); |
||
172 | operationModeComboBox->setBounds(controlX, controlY0 + 2*controlYOffset, controlWidth, controlHeight); |
||
173 | |||
1505 | tk | 174 | midiChannelLabel->setBounds(labelX, labelY0 + 3*labelYOffset, labelWidth, labelHeight); |
175 | midiChannelSlider->setBounds(controlX, controlY0 + 3*controlYOffset, controlWidth, controlHeight); |
||
1131 | tk | 176 | |
1505 | tk | 177 | mergerLabel->setBounds(labelX, labelY0 + 4*labelYOffset, labelWidth, labelHeight); |
178 | mergerComboBox->setBounds(controlX, controlY0 + 4*controlYOffset, controlWidth, controlHeight); |
||
1131 | tk | 179 | |
1505 | tk | 180 | pwmStepsLabel->setBounds(labelX, labelY0 + 5*labelYOffset, labelWidth, labelHeight); |
181 | pwmStepsSlider->setBounds(controlX, controlY0 + 5*controlYOffset, controlWidth, controlHeight); |
||
1131 | tk | 182 | |
1505 | tk | 183 | ainDeadbandLabel->setBounds(labelX, labelY0 + 6*labelYOffset, labelWidth, labelHeight); |
184 | ainDeadbandSlider->setBounds(controlX, controlY0 + 6*controlYOffset, controlWidth, controlHeight); |
||
1131 | tk | 185 | |
1505 | tk | 186 | mfDeadbandLabel->setBounds(labelX, labelY0 + 7*labelYOffset, labelWidth, labelHeight); |
187 | mfDeadbandSlider->setBounds(controlX, controlY0 + 7*controlYOffset, controlWidth, controlHeight); |
||
1131 | tk | 188 | |
1505 | tk | 189 | touchSensorModeLabel->setBounds(labelX, labelY0 + 8*labelYOffset, labelWidth, labelHeight); |
190 | touchSensorModeComboBox->setBounds(controlX, controlY0 + 8*controlYOffset, controlWidth, controlHeight); |
||
1131 | tk | 191 | |
1505 | tk | 192 | touchSensorSensitivityLabel->setBounds(labelX, labelY0 + 9*labelYOffset, labelWidth, labelHeight); |
193 | touchSensorSensitivitySlider->setBounds(controlX, controlY0 + 9*controlYOffset, controlWidth, controlHeight); |
||
194 | |||
1131 | tk | 195 | } |
196 | |||
197 | |||
198 | //============================================================================== |
||
199 | void MbhpMfToolConfigGlobals::sliderValueChanged(Slider* slider) |
||
200 | { |
||
201 | if( slider == pwmStepsSlider ) { |
||
202 | pwmStepsLabel->setText(String::formatted(T("PWM Steps (resulting period: %4.2f mS):"), (float)(slider->getValue()*0.05)), true); |
||
203 | } |
||
1133 | tk | 204 | |
205 | // request SysEx update |
||
206 | if( mbhpMfTool->mbhpMfToolControl != NULL ) |
||
207 | mbhpMfTool->mbhpMfToolControl->sysexUpdateRequest(); |
||
1131 | tk | 208 | } |
209 | |||
1505 | tk | 210 | void MbhpMfToolConfigGlobals::comboBoxChanged(ComboBox* comboBox) |
1133 | tk | 211 | { |
212 | // request SysEx update |
||
213 | if( mbhpMfTool->mbhpMfToolControl != NULL ) |
||
214 | mbhpMfTool->mbhpMfToolControl->sysexUpdateRequest(); |
||
215 | } |
||
216 | |||
217 | |||
1131 | tk | 218 | //============================================================================== |
219 | void MbhpMfToolConfigGlobals::getDump(Array<uint8> &syxDump) |
||
220 | { |
||
221 | int numberFaders = numberFadersSlider->getValue(); |
||
222 | int operationMode = operationModeComboBox->getSelectedId()-1; |
||
1505 | tk | 223 | int midiChannel = midiChannelSlider->getValue()-1; |
1131 | tk | 224 | int merger = mergerComboBox->getSelectedId()-1; |
225 | int pwmSteps = pwmStepsSlider->getValue(); |
||
226 | int ainDeadband = ainDeadbandSlider->getValue(); |
||
227 | int mfDeadband = mfDeadbandSlider->getValue(); |
||
228 | int touchSensorMode = touchSensorModeComboBox->getSelectedId()-1; |
||
229 | int touchSensorSensitivity = touchSensorSensitivitySlider->getValue(); |
||
230 | |||
231 | int i; |
||
232 | String txt = nameEditor->getText(); |
||
233 | for(i=0; i<16 && i<txt.length(); ++i) |
||
234 | syxDump.set(i, txt[i]); |
||
235 | while( i < 16 ) { |
||
236 | syxDump.set(i, 0); |
||
237 | i++; |
||
238 | } |
||
239 | syxDump.set(0x10, numberFaders); |
||
240 | syxDump.set(0x11, operationMode); |
||
241 | syxDump.set(0x12, merger); |
||
242 | syxDump.set(0x13, pwmSteps); |
||
243 | syxDump.set(0x14, ainDeadband); |
||
244 | syxDump.set(0x15, mfDeadband); |
||
245 | syxDump.set(0x16, touchSensorMode); |
||
246 | syxDump.set(0x17, touchSensorSensitivity); |
||
1505 | tk | 247 | syxDump.set(0x18, midiChannel); |
1131 | tk | 248 | } |
249 | |||
250 | void MbhpMfToolConfigGlobals::setDump(const Array<uint8> &syxDump) |
||
251 | { |
||
252 | int numberFaders = syxDump[0x10]; |
||
253 | int operationMode = syxDump[0x11]; |
||
254 | int merger = syxDump[0x12]; |
||
255 | int pwmSteps = syxDump[0x13]; |
||
256 | int ainDeadband = syxDump[0x14]; |
||
257 | int mfDeadband = syxDump[0x15]; |
||
258 | int touchSensorMode = syxDump[0x16]; |
||
259 | int touchSensorSensitivity = syxDump[0x17]; |
||
1505 | tk | 260 | int midiChannel = syxDump[0x18] & 0x0f; |
1131 | tk | 261 | |
262 | String txt; |
||
263 | for(int i=0; i<16 && syxDump[i]; ++i) { |
||
264 | char dummy = syxDump[i]; |
||
265 | txt += String(&dummy, 1); |
||
266 | } |
||
267 | nameEditor->setText(txt); |
||
268 | |||
269 | numberFadersSlider->setValue(numberFaders); |
||
270 | operationModeComboBox->setSelectedId(operationMode+1); |
||
271 | mergerComboBox->setSelectedId(merger+1); |
||
272 | pwmStepsSlider->setValue(pwmSteps); |
||
273 | ainDeadbandSlider->setValue(ainDeadband); |
||
274 | mfDeadbandSlider->setValue(mfDeadband); |
||
275 | touchSensorModeComboBox->setSelectedId(touchSensorMode+1); |
||
276 | touchSensorSensitivitySlider->setValue(touchSensorSensitivity); |
||
1505 | tk | 277 | midiChannelSlider->setValue(midiChannel+1); |
1131 | tk | 278 | } |
279 | |||
280 | |||
281 | //============================================================================== |
||
282 | //============================================================================== |
||
283 | //============================================================================== |
||
284 | MbhpMfToolCalibrationTable::MbhpMfToolCalibrationTable(MbhpMfTool* _mbhpMfTool) |
||
285 | : mbhpMfTool(_mbhpMfTool) |
||
286 | , font(14.0f) |
||
287 | , numRows(8) |
||
288 | { |
||
289 | for(int fader=0; fader<numRows; ++fader) { |
||
290 | mfMode.add(0x01); // enabled and not inverted |
||
1133 | tk | 291 | mfMinValue.add(20); // Default Min Value |
292 | mfMaxValue.add(1000); // Default Max Value |
||
293 | mfMinDutyUp.add(48); // Default Min Duty Upward Direction |
||
294 | mfMaxDutyUp.add(64); // Default Max Duty Upward Direction |
||
295 | mfMinDutyDown.add(48); // Default Min Duty Upward Direction |
||
296 | mfMaxDutyDown.add(64); // Default Max Duty Upward Direction |
||
1131 | tk | 297 | } |
298 | |||
299 | addAndMakeVisible(table = new TableListBox(T("Motorfader Table"), this)); |
||
300 | table->setColour(ListBox::outlineColourId, Colours::grey); |
||
301 | table->setOutlineThickness(1); |
||
302 | |||
1187 | tk | 303 | table->getHeader().addColumn(T("MF"), 1, 25); |
304 | table->getHeader().addColumn(T("Use"), 2, 40); |
||
305 | table->getHeader().addColumn(T("InvM"), 3, 40); |
||
306 | table->getHeader().addColumn(T("MinValue"), 4, 80); |
||
307 | table->getHeader().addColumn(T("MaxValue"), 5, 80); |
||
308 | table->getHeader().addColumn(T("MinDutyUp"), 6, 80); |
||
309 | table->getHeader().addColumn(T("MaxDutyUp"), 7, 80); |
||
310 | table->getHeader().addColumn(T("MinDutyDn"), 8, 80); |
||
311 | table->getHeader().addColumn(T("MaxDutyDn"), 9, 80); |
||
1131 | tk | 312 | |
1133 | tk | 313 | setSize(400, 200); |
1131 | tk | 314 | } |
315 | |||
316 | MbhpMfToolCalibrationTable::~MbhpMfToolCalibrationTable() |
||
317 | { |
||
318 | } |
||
319 | |||
320 | //============================================================================== |
||
321 | int MbhpMfToolCalibrationTable::getNumRows() |
||
322 | { |
||
323 | return numRows; |
||
324 | } |
||
325 | |||
326 | void MbhpMfToolCalibrationTable::paintRowBackground(Graphics &g, int rowNumber, int width, int height, bool rowIsSelected) |
||
327 | { |
||
328 | if( rowIsSelected ) |
||
329 | g.fillAll(Colours::lightblue); |
||
330 | } |
||
331 | |||
332 | void MbhpMfToolCalibrationTable::paintCell(Graphics &g, int rowNumber, int columnId, int width, int height, bool rowIsSelected) |
||
333 | { |
||
334 | g.setColour(Colours::black); |
||
335 | g.setFont(font); |
||
336 | |||
337 | switch( columnId ) { |
||
338 | case 1: { |
||
339 | const String text(rowNumber); |
||
340 | g.drawText(text, 2, 0, width - 4, height, Justification::centred, true); |
||
341 | } break; |
||
342 | } |
||
343 | |||
344 | g.setColour(Colours::black.withAlpha (0.2f)); |
||
345 | g.fillRect(width - 1, 0, 1, height); |
||
346 | } |
||
347 | |||
348 | |||
349 | Component* MbhpMfToolCalibrationTable::refreshComponentForCell(int rowNumber, int columnId, bool isRowSelected, Component* existingComponentToUpdate) |
||
350 | { |
||
351 | switch( columnId ) { |
||
352 | case 2: |
||
353 | case 3: { |
||
354 | ConfigTableToggleButton *toggleButton = (ConfigTableToggleButton *)existingComponentToUpdate; |
||
355 | |||
356 | if( toggleButton == 0 ) |
||
357 | toggleButton = new ConfigTableToggleButton(*this); |
||
358 | |||
359 | toggleButton->setRowAndColumn(rowNumber, columnId); |
||
360 | return toggleButton; |
||
361 | } break; |
||
362 | |||
1133 | tk | 363 | case 4: { |
364 | ConfigTableSlider *slider = (ConfigTableSlider *)existingComponentToUpdate; |
||
365 | |||
366 | if( slider == 0 ) { |
||
367 | slider = new ConfigTableSlider(*this); |
||
368 | slider->setRange(0, 255); |
||
369 | } |
||
370 | |||
371 | slider->setRowAndColumn(rowNumber, columnId); |
||
372 | return slider; |
||
373 | } break; |
||
374 | |||
1131 | tk | 375 | case 5: { |
376 | ConfigTableSlider *slider = (ConfigTableSlider *)existingComponentToUpdate; |
||
377 | |||
378 | if( slider == 0 ) { |
||
379 | slider = new ConfigTableSlider(*this); |
||
1133 | tk | 380 | slider->setRange(768, 1023); |
1131 | tk | 381 | } |
382 | |||
383 | slider->setRowAndColumn(rowNumber, columnId); |
||
384 | return slider; |
||
385 | } break; |
||
386 | |||
387 | case 6: |
||
1133 | tk | 388 | case 7: |
389 | case 8: |
||
390 | case 9: { |
||
1131 | tk | 391 | ConfigTableSlider *slider = (ConfigTableSlider *)existingComponentToUpdate; |
392 | |||
393 | if( slider == 0 ) { |
||
394 | slider = new ConfigTableSlider(*this); |
||
395 | slider->setRange(0, 255); |
||
396 | } |
||
397 | |||
398 | slider->setRowAndColumn(rowNumber, columnId); |
||
399 | return slider; |
||
400 | } break; |
||
401 | } |
||
402 | |||
403 | return 0; |
||
404 | } |
||
405 | |||
406 | |||
407 | //============================================================================== |
||
408 | void MbhpMfToolCalibrationTable::resized() |
||
409 | { |
||
410 | // position our table with a gap around its edge |
||
1724 | tk | 411 | table->setBoundsInset(BorderSize<int>(8)); |
1131 | tk | 412 | } |
413 | |||
414 | |||
415 | //============================================================================== |
||
416 | int MbhpMfToolCalibrationTable::getTableValue(const int rowNumber, const int columnId) |
||
417 | { |
||
418 | switch( columnId ) { |
||
1133 | tk | 419 | case 1: return rowNumber + 1; // doesn't work! :-/ |
1131 | tk | 420 | case 2: return (mfMode[rowNumber] & 1) ? 1 : 0; |
421 | case 3: return (mfMode[rowNumber] & 2) ? 1 : 0; |
||
422 | case 4: return mfMinValue[rowNumber]; |
||
423 | case 5: return mfMaxValue[rowNumber]; |
||
1133 | tk | 424 | case 6: return mfMinDutyUp[rowNumber]; |
425 | case 7: return mfMaxDutyUp[rowNumber]; |
||
426 | case 8: return mfMinDutyDown[rowNumber]; |
||
427 | case 9: return mfMaxDutyDown[rowNumber]; |
||
1131 | tk | 428 | } |
429 | return 0; |
||
430 | } |
||
431 | |||
432 | void MbhpMfToolCalibrationTable::setTableValue(const int rowNumber, const int columnId, const int newValue) |
||
433 | { |
||
434 | switch( columnId ) { |
||
435 | case 2: mfMode.set(rowNumber, (mfMode[rowNumber] & 0xfe) | (newValue ? 1 : 0)); break; |
||
436 | case 3: mfMode.set(rowNumber, (mfMode[rowNumber] & 0xfd) | (newValue ? 2 : 0)); break; |
||
437 | case 4: mfMinValue.set(rowNumber, newValue); break; |
||
438 | case 5: mfMaxValue.set(rowNumber, newValue); break; |
||
1133 | tk | 439 | case 6: mfMinDutyUp.set(rowNumber, newValue); break; |
440 | case 7: mfMaxDutyUp.set(rowNumber, newValue); break; |
||
441 | case 8: mfMinDutyDown.set(rowNumber, newValue); break; |
||
442 | case 9: mfMaxDutyDown.set(rowNumber, newValue); break; |
||
1131 | tk | 443 | } |
444 | |||
445 | // request SysEx update |
||
446 | if( mbhpMfTool->mbhpMfToolControl != NULL ) |
||
447 | mbhpMfTool->mbhpMfToolControl->sysexUpdateRequest(); |
||
448 | } |
||
449 | |||
450 | |||
451 | //============================================================================== |
||
452 | //============================================================================== |
||
453 | //============================================================================== |
||
454 | MbhpMfToolCalibrationCurve::MbhpMfToolCalibrationCurve() |
||
455 | { |
||
456 | } |
||
457 | |||
458 | |||
459 | MbhpMfToolCalibrationCurve::~MbhpMfToolCalibrationCurve() |
||
460 | { |
||
461 | } |
||
462 | |||
463 | //============================================================================== |
||
464 | // set from MbhpMfToolControl::handleIncomingMidiMessage once trace has been received |
||
465 | void MbhpMfToolCalibrationCurve::setTrace(const Array<uint16>& newTrace) |
||
466 | { |
||
467 | traceMem = newTrace; |
||
468 | repaint(); // update view |
||
469 | } |
||
470 | |||
471 | //============================================================================== |
||
472 | void MbhpMfToolCalibrationCurve::paint(Graphics& g) |
||
473 | { |
||
474 | unsigned X0 = 0; |
||
475 | unsigned Y0 = getHeight(); |
||
476 | |||
477 | g.fillAll(Colour(0xffeeeeee)); |
||
478 | |||
479 | // frame around diagram |
||
480 | { |
||
481 | Path p; |
||
482 | p.startNewSubPath(0, 0); |
||
483 | p.lineTo(getWidth(), 0); |
||
484 | p.lineTo(getWidth(), getHeight()); |
||
485 | p.lineTo(0, getHeight()); |
||
486 | //p.lineTo(0, 0); |
||
487 | p.closeSubPath(); |
||
488 | |||
489 | PathStrokeType stroke(2.0f); |
||
490 | g.setColour(Colour(0xff222222)); |
||
491 | g.strokePath (p, stroke, AffineTransform::identity); |
||
492 | } |
||
493 | |||
494 | |||
495 | // getWidth() usually 256, so that each traced mS can be displayed |
||
496 | // vertical lines w/ 50 mS distance |
||
497 | for(int x=50; x<getWidth(); x+=50) { |
||
498 | Path p; |
||
499 | p.startNewSubPath(x+0, Y0-0); |
||
500 | p.lineTo(x+0, 0); |
||
501 | //p.closeSubPath(); |
||
502 | |||
503 | PathStrokeType stroke(1.0f); |
||
504 | g.setColour(Colour(0xff888888)); |
||
505 | g.strokePath (p, stroke, AffineTransform::identity); |
||
506 | } |
||
507 | |||
508 | // getHeight() usually 256 (mfValue / 4) |
||
509 | // horizontal lines w/ 64 pixel distance |
||
510 | for(int y=64; y<getHeight(); y+=64) { |
||
511 | Path p; |
||
512 | p.startNewSubPath(0, y); |
||
513 | p.lineTo(getWidth(), y); |
||
514 | //p.closeSubPath(); |
||
515 | |||
516 | PathStrokeType stroke(1.0f); |
||
517 | g.setColour(Colour(0xff888888)); |
||
518 | g.strokePath (p, stroke, AffineTransform::identity); |
||
519 | } |
||
520 | |||
521 | // the final curve |
||
522 | if( traceMem.size() && traceMem[0] < 0x400 ) { |
||
523 | Path p; |
||
524 | p.startNewSubPath(X0, Y0 - (traceMem[0] / 4)); |
||
525 | |||
526 | for(int i=1; i<traceMem.size(); ++i) { |
||
527 | if( traceMem[i] >= 0x400 ) // end marker |
||
528 | break; |
||
529 | p.lineTo(X0+i, Y0 - (traceMem[i] / 4)); |
||
530 | } |
||
531 | //p.closeSubPath(); |
||
532 | |||
533 | PathStrokeType stroke(3.0f); |
||
534 | g.setColour(Colours::purple.withAlpha ((float)1.0)); |
||
535 | g.strokePath (p, stroke, AffineTransform::identity); |
||
536 | } |
||
537 | |||
538 | } |
||
539 | |||
540 | |||
541 | //============================================================================== |
||
542 | //============================================================================== |
||
543 | //============================================================================== |
||
544 | MbhpMfToolCalibration::MbhpMfToolCalibration(MbhpMfTool* _mbhpMfTool) |
||
545 | : mbhpMfTool(_mbhpMfTool) |
||
546 | , timerGeneratesSineWaveform(false) |
||
547 | , sinePhase(0.0) |
||
548 | { |
||
549 | addAndMakeVisible(calibrationTable = new MbhpMfToolCalibrationTable(_mbhpMfTool)); |
||
550 | |||
551 | addAndMakeVisible(calibrationCurve = new MbhpMfToolCalibrationCurve); |
||
552 | addAndMakeVisible(calibrationCurveLabel = new Label(String::empty, T("x=50 mS per unit, y=256 steps per unit"))); |
||
553 | calibrationCurveLabel->setJustificationType(Justification::horizontallyCentred); |
||
554 | |||
555 | addAndMakeVisible(traceSliderLabel = new Label(String::empty, T("Fader which should be traced:"))); |
||
556 | traceSliderLabel->setJustificationType(Justification::left); |
||
557 | |||
558 | addAndMakeVisible(traceSlider = new Slider(T("Trace Fader"))); |
||
559 | traceSlider->setRange(1, 8, 1); |
||
560 | traceSlider->setValue(1); |
||
561 | traceSlider->setSliderStyle(Slider::IncDecButtons); |
||
1133 | tk | 562 | traceSlider->setTextBoxStyle(Slider::TextBoxLeft, false, 50, 20); |
1131 | tk | 563 | traceSlider->setDoubleClickReturnValue(true, 0); |
564 | traceSlider->addListener(this); |
||
565 | |||
566 | addAndMakeVisible(traceScaleSliderLabel = new Label(String::empty, T("Trace Scale (x * mS):"))); |
||
567 | traceScaleSliderLabel->setJustificationType(Justification::left); |
||
568 | |||
569 | addAndMakeVisible(traceScaleSlider = new Slider(T("TraceScale Fader"))); |
||
570 | traceScaleSlider->setRange(1, 10, 1); |
||
571 | traceScaleSlider->setValue(1); |
||
572 | traceScaleSlider->setSliderStyle(Slider::IncDecButtons); |
||
1133 | tk | 573 | traceScaleSlider->setTextBoxStyle(Slider::TextBoxLeft, false, 50, 20); |
1131 | tk | 574 | traceScaleSlider->setDoubleClickReturnValue(true, 0); |
575 | traceScaleSlider->addListener(this); |
||
576 | |||
1133 | tk | 577 | addAndMakeVisible(directMoveSliderLabel = new Label(String::empty, T("Direct Move:"))); |
578 | directMoveSliderLabel->setJustificationType(Justification::left); |
||
579 | |||
580 | addAndMakeVisible(directMoveSlider = new Slider(T("DirectMove Fader"))); |
||
581 | directMoveSlider->setRange(0, 1023, 1); |
||
582 | directMoveSlider->setValue(512); |
||
583 | directMoveSlider->setSliderStyle(Slider::IncDecButtons); |
||
584 | directMoveSlider->setTextBoxStyle(Slider::TextBoxLeft, false, 50, 20); |
||
585 | directMoveSlider->setDoubleClickReturnValue(true, 0); |
||
586 | directMoveSlider->addListener(this); |
||
587 | |||
1131 | tk | 588 | addAndMakeVisible(upperButton = new TextButton(T("Upper"))); |
1502 | tk | 589 | upperButton->addListener(this); |
1131 | tk | 590 | |
591 | addAndMakeVisible(middleButton = new TextButton(T("Middle"))); |
||
1502 | tk | 592 | middleButton->addListener(this); |
1131 | tk | 593 | |
594 | addAndMakeVisible(lowerButton = new TextButton(T("Lower"))); |
||
1502 | tk | 595 | lowerButton->addListener(this); |
1131 | tk | 596 | |
597 | addAndMakeVisible(slashButton = new TextButton(T("Slash"))); |
||
1502 | tk | 598 | slashButton->addListener(this); |
1131 | tk | 599 | |
600 | addAndMakeVisible(backslashButton = new TextButton(T("Backslash"))); |
||
1502 | tk | 601 | backslashButton->addListener(this); |
1131 | tk | 602 | |
603 | addAndMakeVisible(slowUpperButton = new TextButton(T("Slow Upper"))); |
||
1502 | tk | 604 | slowUpperButton->addListener(this); |
1131 | tk | 605 | |
606 | addAndMakeVisible(slowMiddleButton = new TextButton(T("Slow Middle"))); |
||
1502 | tk | 607 | slowMiddleButton->addListener(this); |
1131 | tk | 608 | |
609 | addAndMakeVisible(slowLowerButton = new TextButton(T("Slow Lower"))); |
||
1502 | tk | 610 | slowLowerButton->addListener(this); |
1131 | tk | 611 | |
612 | addAndMakeVisible(slowSineButton = new TextButton(T("Slow Sine"))); |
||
1502 | tk | 613 | slowSineButton->addListener(this); |
1131 | tk | 614 | |
615 | addAndMakeVisible(delayLabel = new Label(String::empty, T("Slow Delay:"))); |
||
616 | delayLabel->setJustificationType(Justification::left); |
||
617 | |||
618 | addAndMakeVisible(delaySlider = new Slider(T("Delay"))); |
||
619 | delaySlider->setRange(0, 200, 1); |
||
620 | delaySlider->setValue(10); |
||
621 | delaySlider->setSliderStyle(Slider::IncDecButtons); |
||
622 | delaySlider->setTextBoxStyle(Slider::TextBoxLeft, false, 30, 20); |
||
623 | delaySlider->setDoubleClickReturnValue(true, 0); |
||
624 | |||
625 | addAndMakeVisible(delayStepsLabel = new Label(String::empty, T("Slow Steps:"))); |
||
626 | delayStepsLabel->setJustificationType(Justification::left); |
||
627 | |||
628 | addAndMakeVisible(delayStepsSlider = new Slider(T("DelaySteps"))); |
||
629 | delayStepsSlider->setRange(1, 100, 1); |
||
630 | delayStepsSlider->setValue(4); |
||
631 | delayStepsSlider->setSliderStyle(Slider::IncDecButtons); |
||
632 | delayStepsSlider->setTextBoxStyle(Slider::TextBoxLeft, false, 30, 20); |
||
633 | delayStepsSlider->setDoubleClickReturnValue(true, 0); |
||
634 | |||
635 | // for slow calibration moves |
||
636 | for(int mf=0; mf<8; ++mf) { |
||
637 | targetMfValues.set(mf, 0); |
||
638 | currentMfValues.set(mf, 0xffff); // ensure that current values are invalid |
||
639 | } |
||
640 | |||
641 | setSize(800, 300); |
||
642 | } |
||
643 | |||
644 | MbhpMfToolCalibration::~MbhpMfToolCalibration() |
||
645 | { |
||
646 | } |
||
647 | |||
648 | //============================================================================== |
||
649 | void MbhpMfToolCalibration::resized() |
||
650 | { |
||
651 | int buttonWidth = 72; |
||
652 | int buttonHeight = 20; |
||
653 | |||
654 | int tableX0 = 0; |
||
655 | int tableY0 = 0; |
||
1133 | tk | 656 | int tableWidth = 700; |
1131 | tk | 657 | int tableHeight = 230; |
658 | |||
659 | calibrationTable->setBounds(tableX0, tableY0, tableWidth, tableHeight); |
||
660 | |||
1133 | tk | 661 | int curveX0 = 8; |
662 | int curveY0 = tableY0 + tableHeight; |
||
1131 | tk | 663 | int curveWidth = 256; |
664 | int curveHeight = 256; |
||
665 | calibrationCurve->setBounds(curveX0, curveY0, curveWidth, curveHeight); |
||
666 | calibrationCurveLabel->setBounds(curveX0, curveY0+curveHeight, curveWidth, buttonHeight); |
||
667 | |||
1133 | tk | 668 | int traceSliderWidth = 90; |
669 | traceSliderLabel->setBounds(curveX0, curveY0+curveHeight+1*buttonHeight, curveWidth-traceSliderWidth-10, buttonHeight); |
||
670 | traceSlider->setBounds(curveX0 + curveWidth-traceSliderWidth, curveY0+curveHeight+1*buttonHeight, traceSliderWidth, buttonHeight); |
||
671 | traceScaleSliderLabel->setBounds(curveX0, curveY0+curveHeight+2*buttonHeight, curveWidth-traceSliderWidth-10, buttonHeight); |
||
672 | traceScaleSlider->setBounds(curveX0 + curveWidth-traceSliderWidth, curveY0+curveHeight+2*buttonHeight, traceSliderWidth, buttonHeight); |
||
673 | directMoveSliderLabel->setBounds(curveX0, curveY0+curveHeight+3*buttonHeight, curveWidth-traceSliderWidth-10, buttonHeight); |
||
674 | directMoveSlider->setBounds(curveX0 + curveWidth-traceSliderWidth, curveY0+curveHeight+3*buttonHeight, traceSliderWidth, buttonHeight); |
||
675 | |||
676 | int buttonX0 = curveX0 + curveWidth + 10; |
||
677 | int buttonY0 = curveY0 + 10; |
||
1131 | tk | 678 | int buttonYd = buttonHeight + 4; |
679 | |||
680 | upperButton->setBounds(buttonX0, buttonY0 + 0*buttonYd, buttonWidth, buttonHeight); |
||
681 | middleButton->setBounds(buttonX0, buttonY0 + 1*buttonYd, buttonWidth, buttonHeight); |
||
682 | lowerButton->setBounds(buttonX0, buttonY0 + 2*buttonYd, buttonWidth, buttonHeight); |
||
683 | slashButton->setBounds(buttonX0, buttonY0 + 3*buttonYd, buttonWidth, buttonHeight); |
||
684 | backslashButton->setBounds(buttonX0, buttonY0 + 4*buttonYd, buttonWidth, buttonHeight); |
||
685 | |||
686 | slowUpperButton->setBounds(buttonX0+buttonWidth+8, buttonY0 + 0*buttonYd, buttonWidth, buttonHeight); |
||
687 | slowMiddleButton->setBounds(buttonX0+buttonWidth+8, buttonY0 + 1*buttonYd, buttonWidth, buttonHeight); |
||
688 | slowLowerButton->setBounds(buttonX0+buttonWidth+8, buttonY0 + 2*buttonYd, buttonWidth, buttonHeight); |
||
689 | slowSineButton->setBounds(buttonX0+buttonWidth+8, buttonY0 + 3*buttonYd, buttonWidth, buttonHeight); |
||
690 | |||
691 | delayLabel->setBounds(buttonX0, buttonY0 + 6*buttonYd, buttonWidth, buttonHeight); |
||
692 | delaySlider->setBounds(buttonX0+buttonWidth+8, buttonY0 + 6*buttonYd, buttonWidth, buttonHeight); |
||
693 | delayStepsLabel->setBounds(buttonX0, buttonY0 + 7*buttonYd, buttonWidth, buttonHeight); |
||
694 | delayStepsSlider->setBounds(buttonX0+buttonWidth+8, buttonY0 + 7*buttonYd, buttonWidth, buttonHeight); |
||
695 | |||
696 | } |
||
697 | |||
698 | //============================================================================== |
||
699 | void MbhpMfToolCalibration::sliderValueChanged(Slider* slider) |
||
700 | { |
||
701 | if( slider == traceScaleSlider ) { |
||
702 | calibrationCurveLabel->setText(String:: |
||
703 | formatted(T("x=%d mS per unit, y=256 steps per unit"), (unsigned)traceScaleSlider->getValue()*50), true); |
||
704 | Array<uint16> emptyTrace; |
||
705 | calibrationCurve->setTrace(emptyTrace); |
||
706 | } else if( slider == traceSlider ) { |
||
707 | Array<uint16> emptyTrace; |
||
708 | calibrationCurve->setTrace(emptyTrace); |
||
1133 | tk | 709 | } else if( slider == directMoveSlider ) { |
710 | uint8 traceFader = traceSlider->getValue() - 1; |
||
711 | uint8 traceFaderScale = traceScaleSlider->getValue(); |
||
712 | |||
713 | // request trace update |
||
714 | { |
||
715 | |||
716 | Array<uint16> emptyTrace; |
||
717 | calibrationCurve->setTrace(emptyTrace); |
||
718 | |||
719 | // request values |
||
720 | Array<uint8> requestTraceSyx = SysexHelper::createMbhpMfTraceRequest((uint8)mbhpMfTool->mbhpMfToolControl->deviceIdSlider->getValue(), |
||
721 | traceFader, |
||
722 | traceFaderScale); |
||
723 | MidiMessage message = SysexHelper::createMidiMessage(requestTraceSyx); |
||
724 | mbhpMfTool->miosStudio->sendMidiMessage(message); |
||
725 | } |
||
726 | |||
727 | // send new fader pos |
||
728 | Array<uint16> faderValue; |
||
729 | faderValue.add(directMoveSlider->getValue()); |
||
730 | |||
731 | Array<uint8> faderSnapshotSyx = SysexHelper::createMbhpMfFadersSet((uint8)mbhpMfTool->mbhpMfToolControl->deviceIdSlider->getValue(), |
||
732 | traceFader, |
||
733 | faderValue); |
||
734 | MidiMessage message = SysexHelper::createMidiMessage(faderSnapshotSyx); |
||
735 | mbhpMfTool->miosStudio->sendMidiMessage(message); |
||
1131 | tk | 736 | } |
737 | } |
||
738 | |||
739 | //============================================================================== |
||
740 | void MbhpMfToolCalibration::buttonClicked(Button* buttonThatWasClicked) |
||
741 | { |
||
742 | unsigned delay = 0; |
||
743 | uint8 traceFader = traceSlider->getValue() - 1; |
||
744 | uint8 traceFaderScale = traceScaleSlider->getValue(); |
||
745 | |||
746 | if( buttonThatWasClicked == upperButton ) { |
||
747 | for(int mf=0; mf<8; ++mf) |
||
748 | targetMfValues.set(mf, 1023); |
||
749 | } else if( buttonThatWasClicked == middleButton ) { |
||
750 | for(int mf=0; mf<8; ++mf) |
||
751 | targetMfValues.set(mf, 512); |
||
752 | } else if( buttonThatWasClicked == lowerButton ) { |
||
753 | for(int mf=0; mf<8; ++mf) |
||
754 | targetMfValues.set(mf, 0); |
||
755 | } else if( buttonThatWasClicked == slashButton ) { |
||
756 | for(int mf=0; mf<8; ++mf) |
||
757 | targetMfValues.set(mf, mf*128 + 64); |
||
758 | } else if( buttonThatWasClicked == backslashButton ) { |
||
759 | for(int mf=0; mf<8; ++mf) |
||
760 | targetMfValues.set(mf, 1024 - (mf*128 + 64)); |
||
761 | } else if( buttonThatWasClicked == slowUpperButton ) { |
||
762 | for(int mf=0; mf<8; ++mf) |
||
763 | targetMfValues.set(mf, 1023); |
||
764 | delay = delaySlider->getValue(); |
||
765 | } else if( buttonThatWasClicked == slowMiddleButton ) { |
||
766 | for(int mf=0; mf<8; ++mf) |
||
767 | targetMfValues.set(mf, 512); |
||
768 | delay = delaySlider->getValue(); |
||
769 | } else if( buttonThatWasClicked == slowLowerButton ) { |
||
770 | for(int mf=0; mf<8; ++mf) |
||
771 | targetMfValues.set(mf, 0); |
||
772 | delay = delaySlider->getValue(); |
||
773 | } else if( buttonThatWasClicked == slowSineButton ) { |
||
774 | for(int mf=0; mf<8; ++mf) // values generated by timer |
||
775 | targetMfValues.set(mf, 0); |
||
776 | delay = delaySlider->getValue(); |
||
777 | } |
||
778 | |||
779 | if( targetMfValues.size() ) { |
||
780 | timerGeneratesSineWaveform = buttonThatWasClicked == slowSineButton; |
||
781 | |||
782 | // request trace update |
||
783 | { |
||
784 | Array<uint16> emptyTrace; |
||
785 | calibrationCurve->setTrace(emptyTrace); |
||
786 | |||
787 | // request values |
||
788 | Array<uint8> requestTraceSyx = SysexHelper::createMbhpMfTraceRequest((uint8)mbhpMfTool->mbhpMfToolControl->deviceIdSlider->getValue(), |
||
789 | traceFader, |
||
790 | traceFaderScale); |
||
791 | MidiMessage message = SysexHelper::createMidiMessage(requestTraceSyx); |
||
792 | mbhpMfTool->miosStudio->sendMidiMessage(message); |
||
793 | } |
||
794 | |||
795 | if( !delay ) { |
||
796 | // stop any timer operation |
||
797 | stopTimer(); |
||
798 | |||
799 | // set fader values |
||
800 | Array<uint8> faderSnapshotSyx = SysexHelper::createMbhpMfFadersSet((uint8)mbhpMfTool->mbhpMfToolControl->deviceIdSlider->getValue(), |
||
801 | 0x00, |
||
802 | targetMfValues); |
||
803 | MidiMessage message = SysexHelper::createMidiMessage(faderSnapshotSyx); |
||
804 | mbhpMfTool->miosStudio->sendMidiMessage(message); |
||
805 | |||
806 | // store new values for slow moves |
||
807 | for(int mf=0; mf<8; ++mf) |
||
808 | currentMfValues.set(mf, targetMfValues[mf]); |
||
809 | } else { |
||
810 | // initial state: if currentMfValues 0xffff, we have to initialize them somehow |
||
811 | for(int mf=0; mf<8; ++mf) |
||
812 | if( currentMfValues[mf] == 0xffff ) |
||
813 | currentMfValues.set(mf, 0x3ff-targetMfValues[mf]); |
||
814 | |||
815 | // start timer which moves the faders slowly |
||
816 | startTimer(1); |
||
817 | } |
||
818 | } |
||
1133 | tk | 819 | |
820 | // update "direct move" slider |
||
821 | directMoveSlider->setValue(currentMfValues[traceFader]); |
||
1131 | tk | 822 | } |
823 | |||
824 | //============================================================================== |
||
825 | void MbhpMfToolCalibration::timerCallback() |
||
826 | { |
||
1133 | tk | 827 | uint8 traceFader = traceSlider->getValue() - 1; |
828 | |||
1131 | tk | 829 | stopTimer(); // will be restarted if required |
830 | bool targetReached = true; |
||
831 | |||
832 | // move faders into target direction depending on specified range |
||
833 | int stepRange = delayStepsSlider->getValue(); |
||
834 | if( !stepRange ) stepRange = 1; |
||
835 | |||
836 | if( timerGeneratesSineWaveform ) { |
||
837 | targetReached = false; // target never reached... endless waveform generation (until another button has been pressed) |
||
838 | sinePhase += (float)stepRange; |
||
839 | while( sinePhase >= 360 ) |
||
840 | sinePhase -= 360; |
||
841 | |||
842 | for(int mf=0; mf<8; ++mf) { |
||
843 | int value = 0x200 + 0x200 * sin(2*3.14159 * ((sinePhase+mf*20) / 360)); |
||
844 | if( value >= 0x400 ) value = 0x3ff; |
||
845 | if( value < 0 ) value = 0; |
||
846 | currentMfValues.set(mf, value); |
||
847 | } |
||
848 | } else { |
||
849 | for(int mf=0; mf<8; ++mf) { |
||
850 | int current = currentMfValues[mf]; |
||
851 | int target = targetMfValues[mf]; |
||
852 | |||
853 | if( current != target ) { |
||
854 | if( target > current ) { |
||
855 | current += stepRange; |
||
856 | if( current > target ) |
||
857 | current = target; |
||
858 | } else { |
||
859 | current -= stepRange; |
||
860 | if( current < target ) |
||
861 | current = target; |
||
862 | } |
||
863 | |||
864 | currentMfValues.set(mf, current); |
||
865 | } |
||
866 | } |
||
867 | |||
868 | // restart timer if target values not reached yet |
||
869 | for(int mf=0; mf<8 && targetReached; ++mf) |
||
870 | if( currentMfValues[mf] != targetMfValues[mf] ) |
||
871 | targetReached = false; |
||
872 | } |
||
873 | |||
874 | // set fader values |
||
875 | Array<uint8> faderSnapshotSyx = SysexHelper::createMbhpMfFadersSet((uint8)mbhpMfTool->mbhpMfToolControl->deviceIdSlider->getValue(), |
||
876 | 0x00, |
||
877 | currentMfValues); |
||
878 | MidiMessage message = SysexHelper::createMidiMessage(faderSnapshotSyx); |
||
879 | mbhpMfTool->miosStudio->sendMidiMessage(message); |
||
880 | |||
1133 | tk | 881 | // update "direct move" slider |
882 | directMoveSlider->setValue(currentMfValues[traceFader]); |
||
883 | |||
1131 | tk | 884 | // restart timer? |
885 | if( !targetReached ) { |
||
886 | int delay = delaySlider->getValue(); |
||
887 | if( !delay ) delay = 1; |
||
888 | startTimer(delay); |
||
889 | } |
||
890 | } |
||
891 | |||
892 | //============================================================================== |
||
893 | void MbhpMfToolCalibration::getDump(Array<uint8> &syxDump) |
||
894 | { |
||
895 | for(int mf=0; mf<8; ++mf) { |
||
896 | syxDump.set(0x20 + 0*8+mf, calibrationTable->mfMode[mf]); |
||
1133 | tk | 897 | syxDump.set(0x20 + 1*8+mf, calibrationTable->mfMinValue[mf] & 0xff); // only low-byte will be stored (0..255) |
898 | syxDump.set(0x20 + 2*8+mf, calibrationTable->mfMaxValue[mf] & 0xff); // only low-byte will be stored (768..1023) |
||
899 | syxDump.set(0x20 + 3*8+mf, calibrationTable->mfMinDutyUp[mf]); |
||
900 | syxDump.set(0x20 + 4*8+mf, calibrationTable->mfMaxDutyUp[mf]); |
||
901 | syxDump.set(0x20 + 5*8+mf, calibrationTable->mfMinDutyDown[mf]); |
||
902 | syxDump.set(0x20 + 6*8+mf, calibrationTable->mfMaxDutyDown[mf]); |
||
1131 | tk | 903 | } |
904 | } |
||
905 | |||
906 | void MbhpMfToolCalibration::setDump(const Array<uint8> &syxDump) |
||
907 | { |
||
908 | for(int mf=0; mf<8; ++mf) { |
||
909 | calibrationTable->mfMode.set(mf, syxDump[0x20 + 0*8+mf]); |
||
1133 | tk | 910 | unsigned minValue = syxDump[0x20 + 1*8+mf]; // only low-byte will be stored (0..255) |
1131 | tk | 911 | calibrationTable->mfMinValue.set(mf, minValue); |
1133 | tk | 912 | unsigned maxValue = syxDump[0x20 + 2*8+mf] + 768; // only low-byte will be stored (768..1023) |
1131 | tk | 913 | calibrationTable->mfMaxValue.set(mf, maxValue); |
1133 | tk | 914 | calibrationTable->mfMinDutyUp.set(mf, syxDump[0x20 + 3*8+mf]); |
915 | calibrationTable->mfMaxDutyUp.set(mf, syxDump[0x20 + 4*8+mf]); |
||
916 | calibrationTable->mfMinDutyDown.set(mf, syxDump[0x20 + 5*8+mf]); |
||
917 | calibrationTable->mfMaxDutyDown.set(mf, syxDump[0x20 + 6*8+mf]); |
||
1131 | tk | 918 | } |
919 | calibrationTable->table->updateContent(); |
||
920 | } |
||
921 | |||
922 | |||
923 | |||
924 | //============================================================================== |
||
925 | //============================================================================== |
||
926 | //============================================================================== |
||
927 | MbhpMfToolConfig::MbhpMfToolConfig(MbhpMfTool *_mbhpMfTool) |
||
928 | : mbhpMfTool(_mbhpMfTool) |
||
929 | , TabbedComponent(TabbedButtonBar::TabsAtTop) |
||
930 | { |
||
931 | addTab(T("Global"), Colour(0xfff0f0e0), configGlobals = new MbhpMfToolConfigGlobals(mbhpMfTool), true); |
||
932 | addTab(T("Calibration"), Colour(0xfff0f0d0), calibration = new MbhpMfToolCalibration(mbhpMfTool), true); |
||
933 | setSize(800, 300); |
||
934 | } |
||
935 | |||
936 | MbhpMfToolConfig::~MbhpMfToolConfig() |
||
937 | { |
||
938 | } |
||
939 | |||
940 | //============================================================================== |
||
941 | void MbhpMfToolConfig::getDump(Array<uint8> &syxDump) |
||
942 | { |
||
943 | for(int addr=0x000; addr<0x460; ++addr) |
||
944 | syxDump.set(addr, 0x00); |
||
945 | for(int addr=0x460; addr<0x600; ++addr) |
||
946 | syxDump.set(addr, 0x7f); |
||
947 | |||
948 | configGlobals->getDump(syxDump); |
||
949 | calibration->getDump(syxDump); |
||
950 | } |
||
951 | |||
952 | void MbhpMfToolConfig::setDump(const Array<uint8> &syxDump) |
||
953 | { |
||
954 | configGlobals->setDump(syxDump); |
||
955 | calibration->setDump(syxDump); |
||
956 | } |
||
957 | |||
958 | |||
959 | |||
960 | //============================================================================== |
||
961 | //============================================================================== |
||
962 | //============================================================================== |
||
963 | MbhpMfToolControl::MbhpMfToolControl(MiosStudio *_miosStudio, MbhpMfToolConfig *_mbhpMfToolConfig) |
||
964 | : miosStudio(_miosStudio) |
||
965 | , mbhpMfToolConfig(_mbhpMfToolConfig) |
||
966 | , progress(0) |
||
967 | , receiveDump(false) |
||
1133 | tk | 968 | , sendCompleteDump(false) |
969 | , sendChangedDump(false) |
||
1131 | tk | 970 | , dumpRequested(false) |
971 | , dumpReceived(false) |
||
972 | , checksumError(false) |
||
973 | , dumpSent(false) |
||
974 | { |
||
975 | addAndMakeVisible(loadButton = new TextButton(T("Load"))); |
||
1502 | tk | 976 | loadButton->addListener(this); |
1131 | tk | 977 | |
978 | addAndMakeVisible(saveButton = new TextButton(T("Save"))); |
||
1502 | tk | 979 | saveButton->addListener(this); |
1131 | tk | 980 | |
981 | addAndMakeVisible(deviceIdLabel = new Label(T("Device ID"), T("Device ID:"))); |
||
982 | deviceIdLabel->setJustificationType(Justification::right); |
||
983 | |||
984 | addAndMakeVisible(deviceIdSlider = new Slider(T("Device ID"))); |
||
985 | deviceIdSlider->setRange(0, 127, 1); |
||
986 | deviceIdSlider->setSliderStyle(Slider::IncDecButtons); |
||
987 | deviceIdSlider->setTextBoxStyle(Slider::TextBoxLeft, false, 30, 20); |
||
988 | deviceIdSlider->setDoubleClickReturnValue(true, 0); |
||
989 | |||
990 | addAndMakeVisible(patchLabel = new Label(T("Patch"), T("Patch:"))); |
||
991 | patchLabel->setJustificationType(Justification::right); |
||
992 | patchLabel->setVisible(false); // no patches provided by MBHP_MF |
||
993 | |||
994 | addAndMakeVisible(patchSlider = new Slider(T("Patch"))); |
||
995 | patchSlider->setRange(1, 128, 1); |
||
996 | patchSlider->setSliderStyle(Slider::IncDecButtons); |
||
997 | patchSlider->setTextBoxStyle(Slider::TextBoxLeft, false, 30, 20); |
||
998 | patchSlider->setDoubleClickReturnValue(true, 0); |
||
999 | patchSlider->setVisible(false); // no patches provided by MBHP_MF |
||
1000 | |||
1001 | addAndMakeVisible(receiveButton = new TextButton(T("Receive"))); |
||
1502 | tk | 1002 | receiveButton->addListener(this); |
1131 | tk | 1003 | |
1004 | addAndMakeVisible(sendButton = new TextButton(T("Send"))); |
||
1502 | tk | 1005 | sendButton->addListener(this); |
1131 | tk | 1006 | |
1007 | addAndMakeVisible(progressBar = new ProgressBar(progress)); |
||
1008 | |||
1009 | // restore settings |
||
1724 | tk | 1010 | PropertiesFile *propertiesFile = MiosStudioProperties::getInstance()->getCommonSettings(true); |
1131 | tk | 1011 | if( propertiesFile ) { |
1012 | deviceIdSlider->setValue(propertiesFile->getIntValue(T("mbhpMfDeviceId"), 0) & 0x7f); |
||
1013 | patchSlider->setValue(propertiesFile->getIntValue(T("mbhpMfPatch"), 0) & 0x7f); |
||
1014 | String syxFileName(propertiesFile->getValue(T("mbhpMfSyxFile"), String::empty)); |
||
1015 | if( syxFileName != String::empty ) |
||
1016 | syxFile = File(syxFileName); |
||
1017 | } |
||
1018 | |||
1019 | // revert patch number change - no patches provided by MBHP_MF |
||
1020 | patchSlider->setValue(0); |
||
1021 | |||
1022 | setSize(800, 300); |
||
1023 | } |
||
1024 | |||
1025 | MbhpMfToolControl::~MbhpMfToolControl() |
||
1026 | { |
||
1027 | } |
||
1028 | |||
1029 | //============================================================================== |
||
1030 | void MbhpMfToolControl::paint (Graphics& g) |
||
1031 | { |
||
1032 | g.fillAll(Colours::white); |
||
1033 | } |
||
1034 | |||
1035 | void MbhpMfToolControl::resized() |
||
1036 | { |
||
1037 | int buttonX0 = 10; |
||
1038 | int buttonXOffset = 80; |
||
1039 | int buttonY = 8; |
||
1040 | int buttonWidth = 72; |
||
1041 | int buttonHeight = 24; |
||
1042 | |||
1043 | loadButton->setBounds(buttonX0 + 0*buttonXOffset, buttonY, buttonWidth, buttonHeight); |
||
1044 | saveButton->setBounds(buttonX0 + 1*buttonXOffset, buttonY, buttonWidth, buttonHeight); |
||
1045 | |||
1046 | deviceIdLabel->setBounds(buttonX0 + 20+2*buttonXOffset, buttonY, buttonWidth, buttonHeight); |
||
1047 | deviceIdSlider->setBounds(buttonX0 + 20+3*buttonXOffset, buttonY, buttonWidth, buttonHeight); |
||
1048 | |||
1133 | tk | 1049 | #if 0 |
1131 | tk | 1050 | patchLabel->setBounds(buttonX0 + 20+4*buttonXOffset, buttonY, buttonWidth, buttonHeight); |
1051 | patchSlider->setBounds(buttonX0 + 20+5*buttonXOffset, buttonY, buttonWidth, buttonHeight); |
||
1052 | |||
1053 | receiveButton->setBounds(buttonX0 + 40+6*buttonXOffset, buttonY, buttonWidth, buttonHeight); |
||
1054 | sendButton->setBounds(buttonX0 + 40+7*buttonXOffset, buttonY, buttonWidth, buttonHeight); |
||
1133 | tk | 1055 | #else |
1056 | receiveButton->setBounds(buttonX0 + 40+4*buttonXOffset, buttonY, buttonWidth, buttonHeight); |
||
1057 | sendButton->setBounds(buttonX0 + 40+5*buttonXOffset, buttonY, buttonWidth, buttonHeight); |
||
1058 | #endif |
||
1131 | tk | 1059 | |
1060 | int progressBarX = sendButton->getX() + buttonWidth + 20; |
||
1061 | progressBar->setBounds(progressBarX, buttonY, getWidth()-progressBarX-buttonX0, buttonHeight); |
||
1062 | } |
||
1063 | |||
1064 | //============================================================================== |
||
1065 | void MbhpMfToolControl::buttonClicked(Button* buttonThatWasClicked) |
||
1066 | { |
||
1067 | if( buttonThatWasClicked == loadButton ) { |
||
1068 | FileChooser fc(T("Choose a .syx file that you want to open..."), |
||
1069 | syxFile, |
||
1070 | T("*.syx")); |
||
1071 | |||
1072 | if( fc.browseForFileToOpen() ) { |
||
1073 | syxFile = fc.getResult(); |
||
1074 | if( loadSyx(syxFile) ) { |
||
1724 | tk | 1075 | PropertiesFile *propertiesFile = MiosStudioProperties::getInstance()->getCommonSettings(true); |
1131 | tk | 1076 | if( propertiesFile ) |
1077 | propertiesFile->setValue(T("mbhpMfSyxFile"), syxFile.getFullPathName()); |
||
1078 | } |
||
1079 | } |
||
1080 | } else if( buttonThatWasClicked == saveButton ) { |
||
1081 | FileChooser fc(T("Choose a .syx file that you want to save..."), |
||
1082 | syxFile, |
||
1083 | T("*.syx")); |
||
1084 | if( fc.browseForFileToSave(true) ) { |
||
1085 | syxFile = fc.getResult(); |
||
1086 | if( saveSyx(syxFile) ) { |
||
1724 | tk | 1087 | PropertiesFile *propertiesFile = MiosStudioProperties::getInstance()->getCommonSettings(true); |
1131 | tk | 1088 | if( propertiesFile ) |
1089 | propertiesFile->setValue(T("mbhpMfSyxFile"), syxFile.getFullPathName()); |
||
1090 | } |
||
1091 | } |
||
1092 | } else if( buttonThatWasClicked == sendButton || buttonThatWasClicked == receiveButton ) { |
||
1093 | loadButton->setEnabled(false); |
||
1094 | saveButton->setEnabled(false); |
||
1095 | sendButton->setEnabled(false); |
||
1096 | receiveButton->setEnabled(false); |
||
1097 | progress = 0; |
||
1502 | tk | 1098 | checksumError = false; |
1131 | tk | 1099 | if( buttonThatWasClicked == receiveButton ) { |
1100 | dumpRequested = false; |
||
1101 | receiveDump = true; |
||
1133 | tk | 1102 | sendCompleteDump = false; |
1103 | sendChangedDump = false; |
||
1131 | tk | 1104 | currentSyxDump.clear(); |
1105 | } else { |
||
1106 | receiveDump = false; |
||
1133 | tk | 1107 | sendCompleteDump = true; |
1108 | sendChangedDump = false; |
||
1131 | tk | 1109 | dumpSent = false; |
1110 | } |
||
1111 | startTimer(1); |
||
1112 | } |
||
1113 | } |
||
1114 | |||
1115 | //============================================================================== |
||
1116 | void MbhpMfToolControl::sliderValueChanged(Slider* slider) |
||
1117 | { |
||
1118 | if( slider == deviceIdSlider ) { |
||
1119 | // store setting |
||
1724 | tk | 1120 | PropertiesFile *propertiesFile = MiosStudioProperties::getInstance()->getCommonSettings(true); |
1131 | tk | 1121 | if( propertiesFile ) |
1122 | propertiesFile->setValue(T("mbhpMfDeviceId"), (int)slider->getValue()); |
||
1123 | } else if( slider == patchSlider ) { |
||
1124 | // store setting |
||
1724 | tk | 1125 | PropertiesFile *propertiesFile = MiosStudioProperties::getInstance()->getCommonSettings(true); |
1131 | tk | 1126 | if( propertiesFile ) |
1127 | propertiesFile->setValue(T("mbhpMfPatch"), (int)slider->getValue()); |
||
1128 | } |
||
1129 | } |
||
1130 | |||
1131 | |||
1132 | //============================================================================== |
||
1133 | void MbhpMfToolControl::sysexUpdateRequest(void) |
||
1134 | { |
||
1133 | tk | 1135 | // get initial dump |
1136 | // this will already happen after startup of MIOS Studio, the function is called |
||
1137 | // from MbhpMfTool constructor as well! |
||
1138 | if( !currentSyxDump.size() ) |
||
1139 | mbhpMfToolConfig->getDump(currentSyxDump); |
||
1140 | |||
1141 | // send changed dump values within 10 mS |
||
1131 | tk | 1142 | // can be called whenever a configuration value has been changed |
1133 | tk | 1143 | if( sendButton->isEnabled() ) { |
1131 | tk | 1144 | receiveDump = false; |
1133 | tk | 1145 | sendCompleteDump = false; |
1146 | sendChangedDump = true; |
||
1131 | tk | 1147 | dumpSent = false; |
1148 | loadButton->setEnabled(false); |
||
1149 | saveButton->setEnabled(false); |
||
1150 | sendButton->setEnabled(false); |
||
1151 | receiveButton->setEnabled(false); |
||
1152 | startTimer(10); |
||
1153 | } |
||
1154 | } |
||
1155 | |||
1156 | //============================================================================== |
||
1157 | void MbhpMfToolControl::timerCallback() |
||
1158 | { |
||
1159 | stopTimer(); // will be restarted if required |
||
1160 | |||
1161 | bool transferFinished = false; |
||
1162 | |||
1163 | if( receiveDump ) { |
||
1164 | if( dumpRequested ) { |
||
1165 | if( !dumpReceived ) { |
||
1166 | transferFinished = true; |
||
1167 | AlertWindow::showMessageBox(AlertWindow::WarningIcon, |
||
1168 | T("No response from core."), |
||
1169 | T("Check:\n- MIDI In/Out connections\n- Device ID\n- that MBHP_MF firmware has been uploaded"), |
||
1170 | String::empty); |
||
1171 | } else if( checksumError ) { |
||
1172 | transferFinished = true; |
||
1173 | AlertWindow::showMessageBox(AlertWindow::WarningIcon, |
||
1174 | T("Detected checksum error!"), |
||
1175 | T("Check:\n- MIDI In/Out connections\n- your MIDI interface"), |
||
1176 | String::empty); |
||
1177 | } else { |
||
1178 | mbhpMfToolConfig->setDump(currentSyxDump); |
||
1179 | transferFinished = true; |
||
1180 | } |
||
1181 | } else { |
||
1182 | dumpReceived = false; |
||
1183 | checksumError = false; |
||
1184 | dumpRequested = true; |
||
1185 | Array<uint8> data = SysexHelper::createMbhpMfReadPatch((uint8)deviceIdSlider->getValue(), |
||
1186 | (int)patchSlider->getValue()-1); |
||
1187 | MidiMessage message = SysexHelper::createMidiMessage(data); |
||
1188 | miosStudio->sendMidiMessage(message); |
||
1189 | |||
1190 | progress = 1.0; |
||
1191 | startTimer(1000); |
||
1192 | } |
||
1133 | tk | 1193 | } else if( sendCompleteDump || sendChangedDump ) { |
1131 | tk | 1194 | if( dumpSent ) { |
1195 | transferFinished = true; |
||
1133 | tk | 1196 | sendCompleteDump = false; |
1197 | sendChangedDump = false; |
||
1131 | tk | 1198 | } else { |
1133 | tk | 1199 | bool anyValueChanged = false; |
1131 | tk | 1200 | |
1133 | tk | 1201 | if( sendCompleteDump ) { |
1202 | mbhpMfToolConfig->getDump(currentSyxDump); |
||
1203 | anyValueChanged = true; |
||
1204 | Array<uint8> data = SysexHelper::createMbhpMfWritePatch((uint8)deviceIdSlider->getValue(), |
||
1205 | (int)patchSlider->getValue()-1, |
||
1206 | ¤tSyxDump.getReference(0)); |
||
1207 | MidiMessage message = SysexHelper::createMidiMessage(data); |
||
1208 | miosStudio->sendMidiMessage(message); |
||
1209 | } else if( sendChangedDump ) { |
||
1210 | Array<uint8> lastSyxDump(currentSyxDump); |
||
1211 | mbhpMfToolConfig->getDump(currentSyxDump); |
||
1212 | |||
1213 | // send only changes via direct write |
||
1214 | for(int addr=0; addr<lastSyxDump.size(); ++addr) { |
||
1215 | if( currentSyxDump[addr] != lastSyxDump[addr] ) { |
||
1216 | anyValueChanged = true; |
||
1217 | |||
1218 | uint8 value = currentSyxDump[addr]; |
||
1219 | Array<uint8> data = SysexHelper::createMbhpMfWriteDirect((uint8)deviceIdSlider->getValue(), |
||
1220 | addr, |
||
1221 | &value, |
||
1222 | 1); |
||
1223 | MidiMessage message = SysexHelper::createMidiMessage(data); |
||
1224 | miosStudio->sendMidiMessage(message); |
||
1225 | } |
||
1226 | } |
||
1227 | } |
||
1228 | |||
1229 | if( anyValueChanged ) { |
||
1230 | dumpSent = true; |
||
1231 | progress = 1.0; |
||
1232 | startTimer(1000); |
||
1233 | } else { |
||
1234 | transferFinished = true; |
||
1235 | sendCompleteDump = false; |
||
1236 | sendChangedDump = false; |
||
1237 | } |
||
1131 | tk | 1238 | } |
1239 | } |
||
1240 | |||
1241 | if( transferFinished ) { |
||
1242 | progress = 0; |
||
1243 | loadButton->setEnabled(true); |
||
1244 | saveButton->setEnabled(true); |
||
1245 | sendButton->setEnabled(true); |
||
1246 | receiveButton->setEnabled(true); |
||
1247 | } |
||
1248 | } |
||
1249 | |||
1250 | //============================================================================== |
||
1251 | void MbhpMfToolControl::handleIncomingMidiMessage(const MidiMessage& message, uint8 runningStatus) |
||
1252 | { |
||
1724 | tk | 1253 | uint8 *data = (uint8 *)message.getRawData(); |
1131 | tk | 1254 | uint32 size = message.getRawDataSize(); |
1255 | |||
1256 | if( SysexHelper::isValidMbhpMfTraceDump(data, size, (int)deviceIdSlider->getValue()) ) { |
||
1257 | Array<uint16> newTrace; |
||
1258 | |||
1259 | for(int pos=7; pos<(size-1) && data[pos] != 0xf7; pos+=2) |
||
1260 | newTrace.add(data[pos+0] | (data[pos+1] << 7)); |
||
1261 | |||
1262 | mbhpMfToolConfig->calibration->calibrationCurve->setTrace(newTrace); |
||
1263 | return; |
||
1264 | } |
||
1265 | |||
1266 | if( receiveDump ) { |
||
1267 | if( dumpRequested && |
||
1268 | SysexHelper::isValidMbhpMfWritePatch(data, size, (int)deviceIdSlider->getValue()) && |
||
1269 | data[7] == ((int)patchSlider->getValue()-1) ) { |
||
1270 | dumpReceived = true; |
||
1271 | |||
1272 | if( size != 522 ) { |
||
1273 | checksumError = true; |
||
1274 | } else { |
||
1275 | uint8 checksum = 0x00; |
||
1276 | int pos; |
||
1277 | for(pos=8; pos<7+1+512; ++pos) |
||
1278 | checksum += data[pos]; |
||
1279 | if( data[pos] != (-(int)checksum & 0x7f) ) |
||
1280 | checksumError = true; |
||
1281 | else { |
||
1282 | for(pos=8; pos<7+1+512; pos+=2) { |
||
1283 | uint8 b = (data[pos+0] & 0x0f) | ((data[pos+1] << 4) & 0xf0); |
||
1284 | currentSyxDump.add(b); |
||
1285 | } |
||
1286 | } |
||
1287 | } |
||
1288 | |||
1289 | // trigger timer immediately |
||
1290 | stopTimer(); |
||
1291 | startTimer(1); |
||
1292 | } |
||
1293 | } else if( isTimerRunning() ) { |
||
1294 | if( SysexHelper::isValidMbhpMfAcknowledge(data, size, (int)deviceIdSlider->getValue()) ) { |
||
1295 | // trigger timer immediately |
||
1296 | stopTimer(); |
||
1297 | startTimer(1); |
||
1298 | } |
||
1299 | } |
||
1300 | } |
||
1301 | |||
1302 | |||
1303 | //============================================================================== |
||
1304 | bool MbhpMfToolControl::loadSyx(File &syxFile) |
||
1305 | { |
||
1306 | FileInputStream *inFileStream = syxFile.createInputStream(); |
||
1307 | |||
1542 | tk | 1308 | if( !inFileStream ) { |
1131 | tk | 1309 | AlertWindow::showMessageBox(AlertWindow::WarningIcon, |
1310 | T("The file ") + syxFile.getFileName(), |
||
1311 | T("doesn't exist!"), |
||
1312 | String::empty); |
||
1313 | return false; |
||
1314 | } else if( inFileStream->isExhausted() || !inFileStream->getTotalLength() ) { |
||
1315 | AlertWindow::showMessageBox(AlertWindow::WarningIcon, |
||
1316 | T("The file ") + syxFile.getFileName(), |
||
1317 | T("is empty!"), |
||
1318 | String::empty); |
||
1319 | return false; |
||
1320 | } |
||
1321 | |||
1322 | int64 size = inFileStream->getTotalLength(); |
||
1323 | uint8 *buffer = (uint8 *)juce_malloc(size); |
||
1324 | int64 readNumBytes = inFileStream->read(buffer, size); |
||
1325 | int numValidPatches = 0; |
||
1326 | Array<uint8> syxDump; |
||
1327 | String errorMessage; |
||
1328 | |||
1329 | if( readNumBytes != size ) { |
||
1330 | errorMessage = String(T("cannot be read completely!")); |
||
1331 | } else { |
||
1332 | for(int pos=0; pos<size; ++pos) { |
||
1333 | if( SysexHelper::isValidMbhpMfWritePatch(buffer+pos, size - pos, -1) ) { |
||
1334 | pos += 7; |
||
1335 | |||
1336 | if( pos < size ) { |
||
1337 | int patch = buffer[pos++]; // not relevant, will be ignored |
||
1338 | int patchPos = 0; |
||
1339 | uint8 checksum = 0x00; |
||
1340 | while( pos < size && buffer[pos] != 0xf7 && patchPos < 256 ) { |
||
1341 | uint8 bl = buffer[pos++] & 0x0f; |
||
1342 | checksum += bl; |
||
1343 | uint8 bh = buffer[pos++] & 0x0f; |
||
1344 | checksum += bh; |
||
1345 | |||
1346 | syxDump.set(patchPos, (bh << 4) | bl); |
||
1347 | ++patchPos; |
||
1348 | } |
||
1349 | |||
1350 | if( patchPos != 256 ) { |
||
1351 | errorMessage = String::formatted(T("contains invalid data: patch %d not complete (only %d bytes)"), patch, patchPos); |
||
1352 | } else { |
||
1353 | checksum = (-(int)checksum) & 0x7f; |
||
1354 | if( buffer[pos] != checksum ) { |
||
1355 | errorMessage = String::formatted(T("contains invalid checksum in patch %d (expected %02X but read %02X)!"), patch, checksum, buffer[pos]); |
||
1356 | } else { |
||
1357 | ++pos; |
||
1358 | ++numValidPatches; |
||
1359 | } |
||
1360 | } |
||
1361 | } |
||
1362 | } |
||
1363 | } |
||
1364 | } |
||
1365 | |||
1366 | juce_free(buffer); |
||
1367 | |||
1368 | if( errorMessage == String::empty ) { |
||
1369 | if( !numValidPatches ) |
||
1370 | errorMessage = String(T("doesn't contain a valid patch!")); |
||
1371 | } |
||
1372 | |||
1373 | if( errorMessage != String::empty ) { |
||
1374 | AlertWindow::showMessageBox(AlertWindow::WarningIcon, |
||
1375 | T("The file ") + syxFile.getFileName(), |
||
1376 | errorMessage, |
||
1377 | String::empty); |
||
1378 | return false; |
||
1379 | } |
||
1380 | |||
1381 | mbhpMfToolConfig->setDump(syxDump); |
||
1382 | |||
1383 | return true; |
||
1384 | } |
||
1385 | |||
1386 | bool MbhpMfToolControl::saveSyx(File &syxFile) |
||
1387 | { |
||
1388 | syxFile.deleteFile(); |
||
1389 | FileOutputStream *outFileStream = syxFile.createOutputStream(); |
||
1390 | |||
1391 | if( !outFileStream || outFileStream->failedToOpen() ) { |
||
1392 | AlertWindow::showMessageBox(AlertWindow::WarningIcon, |
||
1393 | String::empty, |
||
1394 | T("File cannot be created!"), |
||
1395 | String::empty); |
||
1396 | return false; |
||
1397 | } |
||
1398 | |||
1399 | Array<uint8> syxDump; |
||
1400 | mbhpMfToolConfig->getDump(syxDump); |
||
1401 | |||
1402 | Array<uint8> data = SysexHelper::createMbhpMfWritePatch((uint8)deviceIdSlider->getValue(), |
||
1403 | (int)patchSlider->getValue()-1, |
||
1404 | &syxDump.getReference(0)); |
||
1405 | outFileStream->write(&data.getReference(0), data.size()); |
||
1406 | |||
1407 | delete outFileStream; |
||
1408 | |||
1409 | return true; |
||
1410 | } |
||
1411 | |||
1412 | |||
1413 | //============================================================================== |
||
1414 | //============================================================================== |
||
1415 | //============================================================================== |
||
1416 | MbhpMfTool::MbhpMfTool(MiosStudio *_miosStudio) |
||
1417 | : miosStudio(_miosStudio) |
||
1418 | , mbhpMfToolControl(NULL) |
||
1419 | { |
||
1420 | addAndMakeVisible(mbhpMfToolConfig = new MbhpMfToolConfig(this)); |
||
1421 | addAndMakeVisible(mbhpMfToolControl = new MbhpMfToolControl(miosStudio, mbhpMfToolConfig)); |
||
1422 | |||
1133 | tk | 1423 | // get initial dump |
1424 | mbhpMfToolControl->sysexUpdateRequest(); |
||
1425 | |||
1131 | tk | 1426 | resizeLimits.setSizeLimits(100, 300, 2048, 2048); |
1427 | addAndMakeVisible(resizer = new ResizableCornerComponent(this, &resizeLimits)); |
||
1428 | |||
1133 | tk | 1429 | setSize(700, 630); |
1131 | tk | 1430 | } |
1431 | |||
1432 | MbhpMfTool::~MbhpMfTool() |
||
1433 | { |
||
1434 | } |
||
1435 | |||
1436 | //============================================================================== |
||
1437 | void MbhpMfTool::paint (Graphics& g) |
||
1438 | { |
||
1439 | //g.fillAll(Colour(0xffc1d0ff)); |
||
1440 | g.fillAll(Colours::white); |
||
1441 | } |
||
1442 | |||
1443 | void MbhpMfTool::resized() |
||
1444 | { |
||
1445 | mbhpMfToolControl->setBounds(0, 0, getWidth(), 40); |
||
1446 | mbhpMfToolConfig->setBounds(0, 40, getWidth(), getHeight()-40); |
||
1447 | resizer->setBounds(getWidth()-16, getHeight()-16, 16, 16); |
||
1448 | } |