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) 2020, 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 <cstdio>
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 if (Parameter* parameter = parameters.getParameterByIndex (paramIndex))
109 {
110 info = parameter->getInfo ();
111 return kResultTrue;
112 }
113 return kResultFalse;
114 }
115
116 //------------------------------------------------------------------------
getParamStringByValue(ParamID tag,ParamValue valueNormalized,String128 string)117 tresult PLUGIN_API EditController::getParamStringByValue (ParamID tag, ParamValue valueNormalized,
118 String128 string)
119 {
120 if (Parameter* parameter = getParameterObject (tag))
121 {
122 parameter->toString (valueNormalized, string);
123 return kResultTrue;
124 }
125 return kResultFalse;
126 }
127
128 //------------------------------------------------------------------------
getParamValueByString(ParamID tag,TChar * string,ParamValue & valueNormalized)129 tresult PLUGIN_API EditController::getParamValueByString (ParamID tag, TChar* string,
130 ParamValue& valueNormalized)
131 {
132 if (Parameter* parameter = getParameterObject (tag))
133 {
134 if (parameter->fromString (string, valueNormalized))
135 {
136 return kResultTrue;
137 }
138 }
139 return kResultFalse;
140 }
141
142 //------------------------------------------------------------------------
normalizedParamToPlain(ParamID tag,ParamValue valueNormalized)143 ParamValue PLUGIN_API EditController::normalizedParamToPlain (ParamID tag,
144 ParamValue valueNormalized)
145 {
146 if (Parameter* parameter = getParameterObject (tag))
147 {
148 return parameter->toPlain (valueNormalized);
149 }
150 return valueNormalized;
151 }
152
153 //------------------------------------------------------------------------
plainParamToNormalized(ParamID tag,ParamValue plainValue)154 ParamValue PLUGIN_API EditController::plainParamToNormalized (ParamID tag, ParamValue plainValue)
155 {
156 if (Parameter* parameter = getParameterObject (tag))
157 {
158 return parameter->toNormalized (plainValue);
159 }
160 return plainValue;
161 }
162
163 //------------------------------------------------------------------------
getParamNormalized(ParamID tag)164 ParamValue PLUGIN_API EditController::getParamNormalized (ParamID tag)
165 {
166 if (Parameter* parameter = getParameterObject (tag))
167 {
168 return parameter->getNormalized ();
169 }
170 return 0.;
171 }
172
173 //------------------------------------------------------------------------
setParamNormalized(ParamID tag,ParamValue value)174 tresult PLUGIN_API EditController::setParamNormalized (ParamID tag, ParamValue value)
175 {
176 if (Parameter* parameter = getParameterObject (tag))
177 {
178 parameter->setNormalized (value);
179 return kResultTrue;
180 }
181 return kResultFalse;
182 }
183
184 //------------------------------------------------------------------------
setComponentHandler(IComponentHandler * newHandler)185 tresult PLUGIN_API EditController::setComponentHandler (IComponentHandler* newHandler)
186 {
187 if (componentHandler == newHandler)
188 {
189 return kResultTrue;
190 }
191
192 if (componentHandler)
193 {
194 componentHandler->release ();
195 }
196
197 componentHandler = newHandler;
198 if (componentHandler)
199 {
200 componentHandler->addRef ();
201 }
202
203 // try to get the extended version
204 if (componentHandler2)
205 {
206 componentHandler2->release ();
207 componentHandler2 = nullptr;
208 }
209
210 if (newHandler)
211 {
212 newHandler->queryInterface (IComponentHandler2::iid, (void**)&componentHandler2);
213 }
214 return kResultTrue;
215 }
216
217 //------------------------------------------------------------------------
beginEdit(ParamID tag)218 tresult EditController::beginEdit (ParamID tag)
219 {
220 if (componentHandler)
221 {
222 return componentHandler->beginEdit (tag);
223 }
224 return kResultFalse;
225 }
226
227 //------------------------------------------------------------------------
performEdit(ParamID tag,ParamValue valueNormalized)228 tresult EditController::performEdit (ParamID tag, ParamValue valueNormalized)
229 {
230 if (componentHandler)
231 {
232 return componentHandler->performEdit (tag, valueNormalized);
233 }
234 return kResultFalse;
235 }
236
237 //------------------------------------------------------------------------
endEdit(ParamID tag)238 tresult EditController::endEdit (ParamID tag)
239 {
240 if (componentHandler)
241 {
242 return componentHandler->endEdit (tag);
243 }
244 return kResultFalse;
245 }
246
247 //------------------------------------------------------------------------
startGroupEdit()248 tresult EditController::startGroupEdit ()
249 {
250 if (componentHandler2)
251 {
252 return componentHandler2->startGroupEdit ();
253 }
254 return kNotImplemented;
255 }
256
257 //------------------------------------------------------------------------
finishGroupEdit()258 tresult EditController::finishGroupEdit ()
259 {
260 if (componentHandler2)
261 {
262 return componentHandler2->finishGroupEdit ();
263 }
264 return kNotImplemented;
265 }
266
267 //------------------------------------------------------------------------
getParameterInfoByTag(ParamID tag,ParameterInfo & info)268 tresult EditController::getParameterInfoByTag (ParamID tag, ParameterInfo& info)
269 {
270 if (Parameter* parameter = getParameterObject (tag))
271 {
272 info = parameter->getInfo ();
273 return kResultTrue;
274 }
275 return kResultFalse;
276 }
277
278 //------------------------------------------------------------------------
setDirty(TBool state)279 tresult EditController::setDirty (TBool state)
280 {
281 if (componentHandler2)
282 {
283 return componentHandler2->setDirty (state);
284 }
285 return kNotImplemented;
286 }
287
288 //------------------------------------------------------------------------
requestOpenEditor(FIDString name)289 tresult EditController::requestOpenEditor (FIDString name)
290 {
291 if (componentHandler2)
292 {
293 return componentHandler2->requestOpenEditor (name);
294 }
295 return kNotImplemented;
296 }
297
298 #ifndef NO_PLUGUI
299 //------------------------------------------------------------------------
300 // EditorView Implementation
301 //------------------------------------------------------------------------
EditorView(EditController * _controller,ViewRect * size)302 EditorView::EditorView (EditController* _controller, ViewRect* size)
303 : CPluginView (size), controller (_controller)
304 {
305 if (controller)
306 {
307 controller->addRef ();
308 }
309 }
310
311 //------------------------------------------------------------------------
~EditorView()312 EditorView::~EditorView ()
313 {
314 if (controller)
315 {
316 controller->editorDestroyed (this);
317 controller->release ();
318 }
319 }
320
321 //------------------------------------------------------------------------
attachedToParent()322 void EditorView::attachedToParent ()
323 {
324 if (controller)
325 {
326 controller->editorAttached (this);
327 }
328 }
329
330 //------------------------------------------------------------------------
removedFromParent()331 void EditorView::removedFromParent ()
332 {
333 if (controller)
334 {
335 controller->editorRemoved (this);
336 }
337 }
338 #endif // NO_PLUGUI
339
340 //------------------------------------------------------------------------
341 // EditControllerEx1 implementation
342 //------------------------------------------------------------------------
EditControllerEx1()343 EditControllerEx1::EditControllerEx1 () : selectedUnit (kRootUnitId)
344 {
345 UpdateHandler::instance ();
346 }
347
348 //------------------------------------------------------------------------
~EditControllerEx1()349 EditControllerEx1::~EditControllerEx1 ()
350 {
351 }
352
353 //------------------------------------------------------------------------
terminate()354 tresult PLUGIN_API EditControllerEx1::terminate ()
355 {
356 units.clear ();
357
358 for (const auto& programList : programLists)
359 {
360 if (programList)
361 programList->removeDependent (this);
362 }
363 programLists.clear ();
364 programIndexMap.clear ();
365
366 return EditController::terminate ();
367 }
368
369 //------------------------------------------------------------------------
addUnit(Unit * unit)370 bool EditControllerEx1::addUnit (Unit* unit)
371 {
372 units.emplace_back (unit, false);
373 return true;
374 }
375
376 //------------------------------------------------------------------------
getUnitInfo(int32 unitIndex,UnitInfo & info)377 tresult PLUGIN_API EditControllerEx1::getUnitInfo (int32 unitIndex, UnitInfo& info /*out*/)
378 {
379 if (Unit* unit = units.at (unitIndex))
380 {
381 info = unit->getInfo ();
382 return kResultTrue;
383 }
384 return kResultFalse;
385 }
386
387 //------------------------------------------------------------------------
notifyUnitSelection()388 tresult EditControllerEx1::notifyUnitSelection ()
389 {
390 tresult result = kResultFalse;
391 FUnknownPtr<IUnitHandler> unitHandler (componentHandler);
392 if (unitHandler)
393 result = unitHandler->notifyUnitSelection (selectedUnit);
394 return result;
395 }
396
397 //------------------------------------------------------------------------
addProgramList(ProgramList * list)398 bool EditControllerEx1::addProgramList (ProgramList* list)
399 {
400 programIndexMap[list->getID ()] = programLists.size ();
401 programLists.emplace_back (list, false);
402 list->addDependent (this);
403 return true;
404 }
405
406 //------------------------------------------------------------------------
getProgramList(ProgramListID listId) const407 ProgramList* EditControllerEx1::getProgramList (ProgramListID listId) const
408 {
409 auto it = programIndexMap.find (listId);
410 return it == programIndexMap.end () ? nullptr : programLists[it->second];
411 }
412
413 //------------------------------------------------------------------------
notifyProgramListChange(ProgramListID listId,int32 programIndex)414 tresult EditControllerEx1::notifyProgramListChange (ProgramListID listId, int32 programIndex)
415 {
416 tresult result = kResultFalse;
417 FUnknownPtr<IUnitHandler> unitHandler (componentHandler);
418 if (unitHandler)
419 result = unitHandler->notifyProgramListChange (listId, programIndex);
420 return result;
421 }
422
423 //------------------------------------------------------------------------
getProgramListCount()424 int32 PLUGIN_API EditControllerEx1::getProgramListCount ()
425 {
426 return static_cast<int32> (programLists.size ());
427 }
428
429 //------------------------------------------------------------------------
getProgramListInfo(int32 listIndex,ProgramListInfo & info)430 tresult PLUGIN_API EditControllerEx1::getProgramListInfo (int32 listIndex,
431 ProgramListInfo& info /*out*/)
432 {
433 if (listIndex < 0 || listIndex >= static_cast<int32> (programLists.size ()))
434 return kResultFalse;
435 info = programLists[listIndex]->getInfo ();
436 return kResultTrue;
437 }
438
439 //------------------------------------------------------------------------
getProgramName(ProgramListID listId,int32 programIndex,String128 name)440 tresult PLUGIN_API EditControllerEx1::getProgramName (ProgramListID listId, int32 programIndex,
441 String128 name /*out*/)
442 {
443 ProgramIndexMap::const_iterator it = programIndexMap.find (listId);
444 if (it != programIndexMap.end ())
445 {
446 return programLists[it->second]->getProgramName (programIndex, name);
447 }
448 return kResultFalse;
449 }
450
451 //------------------------------------------------------------------------
setProgramName(ProgramListID listId,int32 programIndex,const String128 name)452 tresult EditControllerEx1::setProgramName (ProgramListID listId, int32 programIndex,
453 const String128 name /*in*/)
454 {
455 ProgramIndexMap::const_iterator it = programIndexMap.find (listId);
456 if (it != programIndexMap.end ())
457 {
458 return programLists[it->second]->setProgramName (programIndex, name);
459 }
460 return kResultFalse;
461 }
462
463 //------------------------------------------------------------------------
getProgramInfo(ProgramListID listId,int32 programIndex,CString attributeId,String128 attributeValue)464 tresult PLUGIN_API EditControllerEx1::getProgramInfo (ProgramListID listId, int32 programIndex,
465 CString attributeId /*in*/,
466 String128 attributeValue /*out*/)
467 {
468 ProgramIndexMap::const_iterator it = programIndexMap.find (listId);
469 if (it != programIndexMap.end ())
470 {
471 return programLists[it->second]->getProgramInfo (programIndex, attributeId, attributeValue);
472 }
473 return kResultFalse;
474 }
475
476 //------------------------------------------------------------------------
hasProgramPitchNames(ProgramListID listId,int32 programIndex)477 tresult PLUGIN_API EditControllerEx1::hasProgramPitchNames (ProgramListID listId,
478 int32 programIndex)
479 {
480 ProgramIndexMap::const_iterator it = programIndexMap.find (listId);
481 if (it != programIndexMap.end ())
482 {
483 return programLists[it->second]->hasPitchNames (programIndex);
484 }
485 return kResultFalse;
486 }
487
488 //------------------------------------------------------------------------
getProgramPitchName(ProgramListID listId,int32 programIndex,int16 midiPitch,String128 name)489 tresult PLUGIN_API EditControllerEx1::getProgramPitchName (ProgramListID listId, int32 programIndex,
490 int16 midiPitch, String128 name /*out*/)
491 {
492 ProgramIndexMap::const_iterator it = programIndexMap.find (listId);
493 if (it != programIndexMap.end ())
494 {
495 return programLists[it->second]->getPitchName (programIndex, midiPitch, name);
496 }
497 return kResultFalse;
498 }
499
500 //------------------------------------------------------------------------
update(FUnknown * changedUnknown,int32)501 void PLUGIN_API EditControllerEx1::update (FUnknown* changedUnknown, int32 /*message*/)
502 {
503 auto* programList = FCast<ProgramList> (changedUnknown);
504 if (programList)
505 {
506 FUnknownPtr<IUnitHandler> unitHandler (componentHandler);
507 if (unitHandler)
508 unitHandler->notifyProgramListChange (programList->getID (), kAllProgramInvalid);
509 }
510 }
511
512 //------------------------------------------------------------------------
513 // Unit implementation
514 //------------------------------------------------------------------------
Unit()515 Unit::Unit ()
516 {
517 memset (&info, 0, sizeof (UnitInfo));
518 }
519
520 //------------------------------------------------------------------------
Unit(const String128 name,UnitID unitId,UnitID parentUnitId,ProgramListID programListId)521 Unit::Unit (const String128 name, UnitID unitId, UnitID parentUnitId, ProgramListID programListId)
522 {
523 setName (name);
524 info.id = unitId;
525 info.parentUnitId = parentUnitId;
526 info.programListId = programListId;
527 }
528
529 //------------------------------------------------------------------------
Unit(const UnitInfo & info)530 Unit::Unit (const UnitInfo& info) : info (info)
531 {
532 }
533
534 //------------------------------------------------------------------------
setName(const String128 newName)535 void Unit::setName (const String128 newName)
536 {
537 UString128 (newName).copyTo (info.name, 128);
538 }
539
540 //------------------------------------------------------------------------
541 // ProgramList implementation
542 //------------------------------------------------------------------------
ProgramList(const String128 name,ProgramListID listId,UnitID unitId)543 ProgramList::ProgramList (const String128 name, ProgramListID listId, UnitID unitId)
544 : unitId (unitId), parameter (nullptr)
545 {
546 UString128 (name).copyTo (info.name, 128);
547 info.id = listId;
548 info.programCount = 0;
549 }
550
551 //------------------------------------------------------------------------
ProgramList(const ProgramList & programList)552 ProgramList::ProgramList (const ProgramList& programList)
553 : info (programList.info)
554 , unitId (programList.unitId)
555 , programNames (programList.programNames)
556 , parameter (nullptr)
557 {
558 }
559
560 //------------------------------------------------------------------------
addProgram(const String128 name)561 int32 ProgramList::addProgram (const String128 name)
562 {
563 ++info.programCount;
564 programNames.emplace_back (name);
565 programInfos.emplace_back ();
566 return static_cast<int32> (programNames.size ()) - 1;
567 }
568
569 //------------------------------------------------------------------------
setProgramInfo(int32 programIndex,CString attributeId,const String128 value)570 bool ProgramList::setProgramInfo (int32 programIndex, CString attributeId, const String128 value)
571 {
572 if (programIndex >= 0 && programIndex < static_cast<int32> (programNames.size ()))
573 {
574 programInfos.at (programIndex).insert (std::make_pair (attributeId, value));
575 return true;
576 }
577 return false;
578 }
579
580 //------------------------------------------------------------------------
getProgramInfo(int32 programIndex,CString attributeId,String128 value)581 tresult ProgramList::getProgramInfo (int32 programIndex, CString attributeId,
582 String128 value /*out*/)
583 {
584 if (programIndex >= 0 && programIndex < static_cast<int32> (programNames.size ()))
585 {
586 StringMap::const_iterator it = programInfos[programIndex].find (attributeId);
587 if (it != programInfos[programIndex].end ())
588 {
589 if (!it->second.isEmpty ())
590 {
591 it->second.copyTo16 (value, 0, 128);
592 return kResultTrue;
593 }
594 }
595 }
596 return kResultFalse;
597 }
598
599 //------------------------------------------------------------------------
getProgramName(int32 programIndex,String128 name)600 tresult ProgramList::getProgramName (int32 programIndex, String128 name /*out*/)
601 {
602 if (programIndex >= 0 && programIndex < static_cast<int32> (programNames.size ()))
603 {
604 programNames.at (programIndex).copyTo16 (name, 0, 128);
605 return kResultTrue;
606 }
607 return kResultFalse;
608 }
609
610 //------------------------------------------------------------------------
setProgramName(int32 programIndex,const String128 name)611 tresult ProgramList::setProgramName (int32 programIndex, const String128 name /*in*/)
612 {
613 if (programIndex >= 0 && programIndex < static_cast<int32> (programNames.size ()))
614 {
615 programNames.at (programIndex) = name;
616 if (parameter)
617 {
618 static_cast<StringListParameter*> (parameter)->replaceString (programIndex, name);
619 }
620 return kResultTrue;
621 }
622 return kResultFalse;
623 }
624
625 //------------------------------------------------------------------------
getParameter()626 Parameter* ProgramList::getParameter ()
627 {
628 if (parameter == nullptr)
629 {
630 auto* listParameter = new StringListParameter (
631 info.name, info.id, nullptr,
632 ParameterInfo::kCanAutomate | ParameterInfo::kIsList | ParameterInfo::kIsProgramChange,
633 unitId);
634 for (const auto& programName : programNames)
635 {
636 listParameter->appendString (programName);
637 }
638 parameter = listParameter;
639 }
640 return parameter;
641 }
642
643 //------------------------------------------------------------------------
644 // ProgramListWithPitchNames implementation
645 //-----------------------------------------------------------------------------
ProgramListWithPitchNames(const String128 name,ProgramListID listId,UnitID unitId)646 ProgramListWithPitchNames::ProgramListWithPitchNames (const String128 name, ProgramListID listId,
647 UnitID unitId)
648 : ProgramList (name, listId, unitId)
649 {
650 }
651
652 //-----------------------------------------------------------------------------
addProgram(const String128 name)653 int32 ProgramListWithPitchNames::addProgram (const String128 name)
654 {
655 int32 index = ProgramList::addProgram (name);
656 if (index >= 0)
657 pitchNames.emplace_back ();
658 return index;
659 }
660
661 //-----------------------------------------------------------------------------
setPitchName(int32 programIndex,int16 pitch,const String128 pitchName)662 bool ProgramListWithPitchNames::setPitchName (int32 programIndex, int16 pitch,
663 const String128 pitchName)
664 {
665 if (programIndex < 0 || programIndex >= getCount ())
666 return false;
667
668 bool nameChanged = true;
669 std::pair<PitchNameMap::iterator, bool> res =
670 pitchNames[programIndex].insert (std::make_pair (pitch, pitchName));
671 if (!res.second)
672 {
673 if (res.first->second == pitchName)
674 nameChanged = false;
675 else
676 res.first->second = pitchName;
677 }
678
679 if (nameChanged)
680 changed ();
681 return true;
682 }
683
684 //-----------------------------------------------------------------------------
removePitchName(int32 programIndex,int16 pitch)685 bool ProgramListWithPitchNames::removePitchName (int32 programIndex, int16 pitch)
686 {
687 bool result = false;
688 if (programIndex >= 0 && programIndex < getCount ())
689 {
690 result = pitchNames.at (programIndex).erase (pitch) != 0;
691 }
692 if (result)
693 changed ();
694 return result;
695 }
696
697 //-----------------------------------------------------------------------------
hasPitchNames(int32 programIndex)698 tresult ProgramListWithPitchNames::hasPitchNames (int32 programIndex)
699 {
700 if (programIndex >= 0 && programIndex < getCount ())
701 return (pitchNames.at (programIndex).empty () == true) ? kResultFalse : kResultTrue;
702 return kResultFalse;
703 }
704
705 //-----------------------------------------------------------------------------
getPitchName(int32 programIndex,int16 midiPitch,String128 name)706 tresult ProgramListWithPitchNames::getPitchName (int32 programIndex, int16 midiPitch,
707 String128 name /*out*/)
708 {
709 if (programIndex >= 0 && programIndex < getCount ())
710 {
711 PitchNameMap::const_iterator it = pitchNames[programIndex].find (midiPitch);
712 if (it != pitchNames[programIndex].end ())
713 {
714 it->second.copyTo16 (name, 0, 128);
715 return kResultTrue;
716 }
717 }
718 return kResultFalse;
719 }
720
721 //------------------------------------------------------------------------
722 } // namespace Vst
723 } // namespace Steinberg
724