1 //-----------------------------------------------------------------------------
2 // Project : VST SDK
3 //
4 // Category : Helpers
5 // Filename : public.sdk/source/vst/vsteditcontroller.cpp
6 // Created by : Steinberg, 04/2005
7 // Description : VST Edit Controller Implementation
8 //
9 //-----------------------------------------------------------------------------
10 // LICENSE
11 // (c) 2018, Steinberg Media Technologies GmbH, All Rights Reserved
12 //-----------------------------------------------------------------------------
13 // Redistribution and use in source and binary forms, with or without modification,
14 // are permitted provided that the following conditions are met:
15 //
16 // * Redistributions of source code must retain the above copyright notice,
17 // this list of conditions and the following disclaimer.
18 // * Redistributions in binary form must reproduce the above copyright notice,
19 // this list of conditions and the following disclaimer in the documentation
20 // and/or other materials provided with the distribution.
21 // * Neither the name of the Steinberg Media Technologies nor the names of its
22 // contributors may be used to endorse or promote products derived from this
23 // software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
26 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
29 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
33 // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
34 // OF THE POSSIBILITY OF SUCH DAMAGE.
35 //-----------------------------------------------------------------------------
36
37 #include "public.sdk/source/vst/vsteditcontroller.h"
38 #include "base/source/updatehandler.h"
39 #include "pluginterfaces/base/ustring.h"
40
41 #include <stdio.h>
42
43 namespace Steinberg {
44 namespace Vst {
45
46 KnobMode EditController::hostKnobMode = kCircularMode;
47
48 //------------------------------------------------------------------------
49 // EditController Implementation
50 //------------------------------------------------------------------------
EditController()51 EditController::EditController () : componentHandler (nullptr), componentHandler2 (nullptr)
52 {
53 }
54
55 //------------------------------------------------------------------------
initialize(FUnknown * context)56 tresult PLUGIN_API EditController::initialize (FUnknown* context)
57 {
58 return ComponentBase::initialize (context);
59 }
60
61 //------------------------------------------------------------------------
terminate()62 tresult PLUGIN_API EditController::terminate ()
63 {
64 parameters.removeAll ();
65
66 if (componentHandler)
67 {
68 componentHandler->release ();
69 componentHandler = nullptr;
70 }
71
72 if (componentHandler2)
73 {
74 componentHandler2->release ();
75 componentHandler2 = nullptr;
76 }
77
78 return ComponentBase::terminate ();
79 }
80
81 //------------------------------------------------------------------------
setComponentState(IBStream *)82 tresult PLUGIN_API EditController::setComponentState (IBStream* /*state*/)
83 {
84 return kNotImplemented;
85 }
86
87 //------------------------------------------------------------------------
setState(IBStream *)88 tresult PLUGIN_API EditController::setState (IBStream* /*state*/)
89 {
90 return kNotImplemented;
91 }
92
93 //------------------------------------------------------------------------
getState(IBStream *)94 tresult PLUGIN_API EditController::getState (IBStream* /*state*/)
95 {
96 return kNotImplemented;
97 }
98
99 //------------------------------------------------------------------------
getParameterCount()100 int32 PLUGIN_API EditController::getParameterCount ()
101 {
102 return parameters.getParameterCount ();
103 }
104
105 //------------------------------------------------------------------------
getParameterInfo(int32 paramIndex,ParameterInfo & info)106 tresult PLUGIN_API EditController::getParameterInfo (int32 paramIndex, ParameterInfo& info)
107 {
108 Parameter* parameter = parameters.getParameterByIndex (paramIndex);
109 if (parameter)
110 {
111 info = parameter->getInfo ();
112 return kResultTrue;
113 }
114 return kResultFalse;
115 }
116
117 //------------------------------------------------------------------------
getParamStringByValue(ParamID tag,ParamValue valueNormalized,String128 string)118 tresult PLUGIN_API EditController::getParamStringByValue (ParamID tag, ParamValue valueNormalized,
119 String128 string)
120 {
121 Parameter* parameter = getParameterObject (tag);
122 if (parameter)
123 {
124 parameter->toString (valueNormalized, string);
125 return kResultTrue;
126 }
127 return kResultFalse;
128 }
129
130 //------------------------------------------------------------------------
getParamValueByString(ParamID tag,TChar * string,ParamValue & valueNormalized)131 tresult PLUGIN_API EditController::getParamValueByString (ParamID tag, TChar* string,
132 ParamValue& valueNormalized)
133 {
134 Parameter* parameter = getParameterObject (tag);
135 if (parameter)
136 {
137 if (parameter->fromString (string, valueNormalized))
138 {
139 return kResultTrue;
140 }
141 }
142 return kResultFalse;
143 }
144
145 //------------------------------------------------------------------------
normalizedParamToPlain(ParamID tag,ParamValue valueNormalized)146 ParamValue PLUGIN_API EditController::normalizedParamToPlain (ParamID tag,
147 ParamValue valueNormalized)
148 {
149 Parameter* parameter = getParameterObject (tag);
150 if (parameter)
151 {
152 return parameter->toPlain (valueNormalized);
153 }
154 return valueNormalized;
155 }
156
157 //------------------------------------------------------------------------
plainParamToNormalized(ParamID tag,ParamValue plainValue)158 ParamValue PLUGIN_API EditController::plainParamToNormalized (ParamID tag, ParamValue plainValue)
159 {
160 Parameter* parameter = getParameterObject (tag);
161 if (parameter)
162 {
163 return parameter->toNormalized (plainValue);
164 }
165 return plainValue;
166 }
167
168 //------------------------------------------------------------------------
getParamNormalized(ParamID tag)169 ParamValue PLUGIN_API EditController::getParamNormalized (ParamID tag)
170 {
171 Parameter* parameter = getParameterObject (tag);
172 if (parameter)
173 {
174 return parameter->getNormalized ();
175 }
176 return 0.;
177 }
178
179 //------------------------------------------------------------------------
setParamNormalized(ParamID tag,ParamValue value)180 tresult PLUGIN_API EditController::setParamNormalized (ParamID tag, ParamValue value)
181 {
182 Parameter* parameter = getParameterObject (tag);
183 if (parameter)
184 {
185 parameter->setNormalized (value);
186 return kResultTrue;
187 }
188 return kResultFalse;
189 }
190
191 //------------------------------------------------------------------------
setComponentHandler(IComponentHandler * newHandler)192 tresult PLUGIN_API EditController::setComponentHandler (IComponentHandler* newHandler)
193 {
194 if (componentHandler == newHandler)
195 {
196 return kResultTrue;
197 }
198
199 if (componentHandler)
200 {
201 componentHandler->release ();
202 }
203
204 componentHandler = newHandler;
205 if (componentHandler)
206 {
207 componentHandler->addRef ();
208 }
209
210 // try to get the extended version
211 if (componentHandler2)
212 {
213 componentHandler2->release ();
214 componentHandler2 = nullptr;
215 }
216
217 if (newHandler)
218 {
219 newHandler->queryInterface (IComponentHandler2::iid, (void**)&componentHandler2);
220 }
221 return kResultTrue;
222 }
223
224 //------------------------------------------------------------------------
beginEdit(ParamID tag)225 tresult EditController::beginEdit (ParamID tag)
226 {
227 if (componentHandler)
228 {
229 return componentHandler->beginEdit (tag);
230 }
231 return kResultFalse;
232 }
233
234 //------------------------------------------------------------------------
performEdit(ParamID tag,ParamValue valueNormalized)235 tresult EditController::performEdit (ParamID tag, ParamValue valueNormalized)
236 {
237 if (componentHandler)
238 {
239 return componentHandler->performEdit (tag, valueNormalized);
240 }
241 return kResultFalse;
242 }
243
244 //------------------------------------------------------------------------
endEdit(ParamID tag)245 tresult EditController::endEdit (ParamID tag)
246 {
247 if (componentHandler)
248 {
249 return componentHandler->endEdit (tag);
250 }
251 return kResultFalse;
252 }
253
254 //------------------------------------------------------------------------
startGroupEdit()255 tresult EditController::startGroupEdit ()
256 {
257 if (componentHandler2)
258 {
259 return componentHandler2->startGroupEdit ();
260 }
261 return kNotImplemented;
262 }
263
264 //------------------------------------------------------------------------
finishGroupEdit()265 tresult EditController::finishGroupEdit ()
266 {
267 if (componentHandler2)
268 {
269 return componentHandler2->finishGroupEdit ();
270 }
271 return kNotImplemented;
272 }
273
274 //------------------------------------------------------------------------
getParameterInfoByTag(ParamID tag,ParameterInfo & info)275 tresult EditController::getParameterInfoByTag (ParamID tag, ParameterInfo& info)
276 {
277 Parameter* parameter = getParameterObject (tag);
278 if (parameter)
279 {
280 info = parameter->getInfo ();
281 return kResultTrue;
282 }
283 return kResultFalse;
284 }
285
286 //------------------------------------------------------------------------
setDirty(TBool state)287 tresult EditController::setDirty (TBool state)
288 {
289 if (componentHandler2)
290 {
291 return componentHandler2->setDirty (state);
292 }
293 return kNotImplemented;
294 }
295
296 //------------------------------------------------------------------------
requestOpenEditor(FIDString name)297 tresult EditController::requestOpenEditor (FIDString name)
298 {
299 if (componentHandler2)
300 {
301 return componentHandler2->requestOpenEditor (name);
302 }
303 return kNotImplemented;
304 }
305
306 //------------------------------------------------------------------------
307 // EditorView Implementation
308 //------------------------------------------------------------------------
EditorView(EditController * controller,ViewRect * size)309 EditorView::EditorView (EditController* controller, ViewRect* size)
310 : CPluginView (size), controller (controller)
311 {
312 if (controller)
313 {
314 controller->addRef ();
315 }
316 }
317
318 //------------------------------------------------------------------------
~EditorView()319 EditorView::~EditorView ()
320 {
321 if (controller)
322 {
323 controller->editorDestroyed (this);
324 controller->release ();
325 }
326 }
327
328 //------------------------------------------------------------------------
attachedToParent()329 void EditorView::attachedToParent ()
330 {
331 if (controller)
332 {
333 controller->editorAttached (this);
334 }
335 }
336
337 //------------------------------------------------------------------------
removedFromParent()338 void EditorView::removedFromParent ()
339 {
340 if (controller)
341 {
342 controller->editorRemoved (this);
343 }
344 }
345
346 //------------------------------------------------------------------------
347 // EditControllerEx1 implementation
348 //------------------------------------------------------------------------
EditControllerEx1()349 EditControllerEx1::EditControllerEx1 () : selectedUnit (kRootUnitId)
350 {
351 UpdateHandler::instance ();
352 }
353
354 //------------------------------------------------------------------------
~EditControllerEx1()355 EditControllerEx1::~EditControllerEx1 ()
356 {
357 for (ProgramListVector::const_iterator it = programLists.begin (), end = programLists.end ();
358 it != end; ++it)
359 {
360 if (*it)
361 (*it)->removeDependent (this);
362 }
363 }
364
365 //------------------------------------------------------------------------
addUnit(Unit * unit)366 bool EditControllerEx1::addUnit (Unit* unit)
367 {
368 units.push_back (IPtr<Unit> (unit, false));
369 return true;
370 }
371
372 //------------------------------------------------------------------------
getUnitInfo(int32 unitIndex,UnitInfo & info)373 tresult PLUGIN_API EditControllerEx1::getUnitInfo (int32 unitIndex, UnitInfo& info /*out*/)
374 {
375 Unit* unit = units.at (unitIndex);
376 if (unit)
377 {
378 info = unit->getInfo ();
379 return kResultTrue;
380 }
381 return kResultFalse;
382 }
383
384 //------------------------------------------------------------------------
notifyUnitSelection()385 tresult EditControllerEx1::notifyUnitSelection ()
386 {
387 tresult result = kResultFalse;
388 FUnknownPtr<IUnitHandler> unitHandler (componentHandler);
389 if (unitHandler)
390 result = unitHandler->notifyUnitSelection (selectedUnit);
391 return result;
392 }
393
394 //------------------------------------------------------------------------
addProgramList(ProgramList * list)395 bool EditControllerEx1::addProgramList (ProgramList* list)
396 {
397 programIndexMap[list->getID ()] = programLists.size ();
398 programLists.push_back (IPtr<ProgramList> (list, false));
399 list->addDependent (this);
400 return true;
401 }
402
403 //------------------------------------------------------------------------
getProgramList(ProgramListID listId) const404 ProgramList* EditControllerEx1::getProgramList (ProgramListID listId) const
405 {
406 auto it = programIndexMap.find (listId);
407 return it == programIndexMap.end () ? nullptr : programLists[it->second];
408 }
409
410 //------------------------------------------------------------------------
notifyProgramListChange(ProgramListID listId,int32 programIndex)411 tresult EditControllerEx1::notifyProgramListChange (ProgramListID listId, int32 programIndex)
412 {
413 tresult result = kResultFalse;
414 FUnknownPtr<IUnitHandler> unitHandler (componentHandler);
415 if (unitHandler)
416 result = unitHandler->notifyProgramListChange (listId, programIndex);
417 return result;
418 }
419
420 //------------------------------------------------------------------------
getProgramListCount()421 int32 PLUGIN_API EditControllerEx1::getProgramListCount ()
422 {
423 return static_cast<int32> (programLists.size ());
424 }
425
426 //------------------------------------------------------------------------
getProgramListInfo(int32 listIndex,ProgramListInfo & info)427 tresult PLUGIN_API EditControllerEx1::getProgramListInfo (int32 listIndex,
428 ProgramListInfo& info /*out*/)
429 {
430 if (listIndex < 0 || listIndex >= static_cast<int32> (programLists.size ()))
431 return kResultFalse;
432 info = programLists[listIndex]->getInfo ();
433 return kResultTrue;
434 }
435
436 //------------------------------------------------------------------------
getProgramName(ProgramListID listId,int32 programIndex,String128 name)437 tresult PLUGIN_API EditControllerEx1::getProgramName (ProgramListID listId, int32 programIndex,
438 String128 name /*out*/)
439 {
440 ProgramIndexMap::const_iterator it = programIndexMap.find (listId);
441 if (it != programIndexMap.end ())
442 {
443 return programLists[it->second]->getProgramName (programIndex, name);
444 }
445 return kResultFalse;
446 }
447
448 //------------------------------------------------------------------------
setProgramName(ProgramListID listId,int32 programIndex,const String128 name)449 tresult EditControllerEx1::setProgramName (ProgramListID listId, int32 programIndex,
450 const String128 name /*in*/)
451 {
452 ProgramIndexMap::const_iterator it = programIndexMap.find (listId);
453 if (it != programIndexMap.end ())
454 {
455 return programLists[it->second]->setProgramName (programIndex, name);
456 }
457 return kResultFalse;
458 }
459
460 //------------------------------------------------------------------------
getProgramInfo(ProgramListID listId,int32 programIndex,CString attributeId,String128 attributeValue)461 tresult PLUGIN_API EditControllerEx1::getProgramInfo (ProgramListID listId, int32 programIndex,
462 CString attributeId /*in*/,
463 String128 attributeValue /*out*/)
464 {
465 ProgramIndexMap::const_iterator it = programIndexMap.find (listId);
466 if (it != programIndexMap.end ())
467 {
468 return programLists[it->second]->getProgramInfo (programIndex, attributeId, attributeValue);
469 }
470 return kResultFalse;
471 }
472
473 //------------------------------------------------------------------------
hasProgramPitchNames(ProgramListID listId,int32 programIndex)474 tresult PLUGIN_API EditControllerEx1::hasProgramPitchNames (ProgramListID listId,
475 int32 programIndex)
476 {
477 ProgramIndexMap::const_iterator it = programIndexMap.find (listId);
478 if (it != programIndexMap.end ())
479 {
480 return programLists[it->second]->hasPitchNames (programIndex);
481 }
482 return kResultFalse;
483 }
484
485 //------------------------------------------------------------------------
getProgramPitchName(ProgramListID listId,int32 programIndex,int16 midiPitch,String128 name)486 tresult PLUGIN_API EditControllerEx1::getProgramPitchName (ProgramListID listId, int32 programIndex,
487 int16 midiPitch, String128 name /*out*/)
488 {
489 ProgramIndexMap::const_iterator it = programIndexMap.find (listId);
490 if (it != programIndexMap.end ())
491 {
492 return programLists[it->second]->getPitchName (programIndex, midiPitch, name);
493 }
494 return kResultFalse;
495 }
496
497 //------------------------------------------------------------------------
update(FUnknown * changedUnknown,int32)498 void PLUGIN_API EditControllerEx1::update (FUnknown* changedUnknown, int32 /*message*/)
499 {
500 auto* programList = FCast<ProgramList> (changedUnknown);
501 if (programList)
502 {
503 FUnknownPtr<IUnitHandler> unitHandler (componentHandler);
504 if (unitHandler)
505 unitHandler->notifyProgramListChange (programList->getID (), kAllProgramInvalid);
506 }
507 }
508
509 //------------------------------------------------------------------------
510 // Unit implementation
511 //------------------------------------------------------------------------
Unit()512 Unit::Unit ()
513 {
514 memset (&info, 0, sizeof (UnitInfo));
515 }
516
517 //------------------------------------------------------------------------
Unit(const String128 name,UnitID unitId,UnitID parentUnitId,ProgramListID programListId)518 Unit::Unit (const String128 name, UnitID unitId, UnitID parentUnitId, ProgramListID programListId)
519 {
520 setName (name);
521 info.id = unitId;
522 info.parentUnitId = parentUnitId;
523 info.programListId = programListId;
524 }
525
526 //------------------------------------------------------------------------
Unit(const UnitInfo & info)527 Unit::Unit (const UnitInfo& info) : info (info)
528 {
529 }
530
531 //------------------------------------------------------------------------
setName(const String128 newName)532 void Unit::setName (const String128 newName)
533 {
534 UString128 (newName).copyTo (info.name, 128);
535 }
536
537 //------------------------------------------------------------------------
538 // ProgramList implementation
539 //------------------------------------------------------------------------
ProgramList(const String128 name,ProgramListID listId,UnitID unitId)540 ProgramList::ProgramList (const String128 name, ProgramListID listId, UnitID unitId)
541 : unitId (unitId), parameter (nullptr)
542 {
543 UString128 (name).copyTo (info.name, 128);
544 info.id = listId;
545 info.programCount = 0;
546 }
547
548 //------------------------------------------------------------------------
ProgramList(const ProgramList & programList)549 ProgramList::ProgramList (const ProgramList& programList)
550 : info (programList.info)
551 , unitId (programList.unitId)
552 , programNames (programList.programNames)
553 , parameter (nullptr)
554 {
555 }
556
557 //------------------------------------------------------------------------
addProgram(const String128 name)558 int32 ProgramList::addProgram (const String128 name)
559 {
560 ++info.programCount;
561 programNames.push_back (name);
562 programInfos.push_back (ProgramInfoVector::value_type ());
563 return static_cast<int32> (programNames.size ()) - 1;
564 }
565
566 //------------------------------------------------------------------------
setProgramInfo(int32 programIndex,CString attributeId,const String128 value)567 bool ProgramList::setProgramInfo (int32 programIndex, CString attributeId, const String128 value)
568 {
569 if (programIndex >= 0 && programIndex < static_cast<int32> (programNames.size ()))
570 {
571 programInfos.at (programIndex).insert (std::make_pair (attributeId, value));
572 return true;
573 }
574 return false;
575 }
576
577 //------------------------------------------------------------------------
getProgramInfo(int32 programIndex,CString attributeId,String128 value)578 tresult ProgramList::getProgramInfo (int32 programIndex, CString attributeId,
579 String128 value /*out*/)
580 {
581 if (programIndex >= 0 && programIndex < static_cast<int32> (programNames.size ()))
582 {
583 StringMap::const_iterator it = programInfos[programIndex].find (attributeId);
584 if (it != programInfos[programIndex].end ())
585 {
586 if (!it->second.isEmpty ())
587 {
588 it->second.copyTo16 (value, 0, 128);
589 return kResultTrue;
590 }
591 }
592 }
593 return kResultFalse;
594 }
595
596 //------------------------------------------------------------------------
getProgramName(int32 programIndex,String128 name)597 tresult ProgramList::getProgramName (int32 programIndex, String128 name /*out*/)
598 {
599 if (programIndex >= 0 && programIndex < static_cast<int32> (programNames.size ()))
600 {
601 programNames.at (programIndex).copyTo16 (name, 0, 128);
602 return kResultTrue;
603 }
604 return kResultFalse;
605 }
606
607 //------------------------------------------------------------------------
setProgramName(int32 programIndex,const String128 name)608 tresult ProgramList::setProgramName (int32 programIndex, const String128 name /*in*/)
609 {
610 if (programIndex >= 0 && programIndex < static_cast<int32> (programNames.size ()))
611 {
612 programNames.at (programIndex) = name;
613 if (parameter)
614 {
615 static_cast<StringListParameter*> (parameter)->replaceString (programIndex, name);
616 }
617 return kResultTrue;
618 }
619 return kResultFalse;
620 }
621
622 //------------------------------------------------------------------------
getParameter()623 Parameter* ProgramList::getParameter ()
624 {
625 if (parameter == nullptr)
626 {
627 auto* listParameter = new StringListParameter (
628 info.name, info.id, nullptr,
629 ParameterInfo::kCanAutomate | ParameterInfo::kIsList | ParameterInfo::kIsProgramChange,
630 unitId);
631 for (StringVector::const_iterator it = programNames.begin (), end = programNames.end ();
632 it != end; ++it)
633 {
634 listParameter->appendString (*it);
635 }
636 parameter = listParameter;
637 }
638 return parameter;
639 }
640
641 //------------------------------------------------------------------------
642 // ProgramListWithPitchNames implementation
643 //-----------------------------------------------------------------------------
ProgramListWithPitchNames(const String128 name,ProgramListID listId,UnitID unitId)644 ProgramListWithPitchNames::ProgramListWithPitchNames (const String128 name, ProgramListID listId,
645 UnitID unitId)
646 : ProgramList (name, listId, unitId)
647 {
648 }
649
650 //-----------------------------------------------------------------------------
addProgram(const String128 name)651 int32 ProgramListWithPitchNames::addProgram (const String128 name)
652 {
653 int32 index = ProgramList::addProgram (name);
654 if (index >= 0)
655 pitchNames.push_back (PitchNamesVector::value_type ());
656 return index;
657 }
658
659 //-----------------------------------------------------------------------------
setPitchName(int32 programIndex,int16 pitch,const String128 pitchName)660 bool ProgramListWithPitchNames::setPitchName (int32 programIndex, int16 pitch,
661 const String128 pitchName)
662 {
663 if (programIndex < 0 || programIndex >= getCount ())
664 return false;
665
666 bool nameChanged = true;
667 std::pair<PitchNameMap::iterator, bool> res =
668 pitchNames[programIndex].insert (std::make_pair (pitch, pitchName));
669 if (!res.second)
670 {
671 if (res.first->second == pitchName)
672 nameChanged = false;
673 else
674 res.first->second = pitchName;
675 }
676
677 if (nameChanged)
678 changed ();
679 return true;
680 }
681
682 //-----------------------------------------------------------------------------
removePitchName(int32 programIndex,int16 pitch)683 bool ProgramListWithPitchNames::removePitchName (int32 programIndex, int16 pitch)
684 {
685 bool result = false;
686 if (programIndex >= 0 && programIndex < getCount ())
687 {
688 result = pitchNames.at (programIndex).erase (pitch) != 0;
689 }
690 if (result)
691 changed ();
692 return result;
693 }
694
695 //-----------------------------------------------------------------------------
hasPitchNames(int32 programIndex)696 tresult ProgramListWithPitchNames::hasPitchNames (int32 programIndex)
697 {
698 if (programIndex >= 0 && programIndex < getCount ())
699 return pitchNames.at (programIndex).empty () ? kResultFalse : kResultTrue;
700 return kResultFalse;
701 }
702
703 //-----------------------------------------------------------------------------
getPitchName(int32 programIndex,int16 midiPitch,String128 name)704 tresult ProgramListWithPitchNames::getPitchName (int32 programIndex, int16 midiPitch,
705 String128 name /*out*/)
706 {
707 if (programIndex >= 0 && programIndex < getCount ())
708 {
709 PitchNameMap::const_iterator it = pitchNames[programIndex].find (midiPitch);
710 if (it != pitchNames[programIndex].end ())
711 {
712 it->second.copyTo16 (name, 0, 128);
713 return kResultTrue;
714 }
715 }
716 return kResultFalse;
717 }
718
719 //------------------------------------------------------------------------
720 } // namespace Vst
721 } // namespace Steinberg
722