1 /*************************************************************************** 2 * * 3 * LinuxSampler - modular, streaming capable sampler * 4 * * 5 * Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck * 6 * Copyright (C) 2005 - 2015 Christian Schoenebeck * 7 * * 8 * This library is free software; you can redistribute it and/or modify * 9 * it under the terms of the GNU General Public License as published by * 10 * the Free Software Foundation; either version 2 of the License, or * 11 * (at your option) any later version. * 12 * * 13 * This library is distributed in the hope that it will be useful, * 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 16 * GNU General Public License for more details. * 17 * * 18 * You should have received a copy of the GNU General Public License * 19 * along with this library; if not, write to the Free Software * 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * 21 * MA 02111-1307 USA * 22 ***************************************************************************/ 23 24 #ifndef __LS_INSTRUMENTMANAGER_H__ 25 #define __LS_INSTRUMENTMANAGER_H__ 26 27 #include "../common/global.h" 28 #include "../common/Exception.h" 29 30 #include <vector> 31 32 namespace LinuxSampler { 33 34 // just symbol prototyping 35 class EngineChannel; 36 class InstrumentEditor; 37 38 /** 39 * Will be thrown by InstrumentManager implementations on errors. 40 */ 41 class InstrumentManagerException : public Exception { 42 public: InstrumentManagerException(String msg)43 InstrumentManagerException(String msg) : Exception(msg) {} 44 }; 45 46 /** @brief Abstract interface class for InstrumentManagers. 47 * 48 * Sampler engines should provide an InstrumentManager for allowing 49 * detailed information retrieval and setting of its managed instruments 50 * through this general API. 51 */ 52 class InstrumentManager { 53 public: 54 /** 55 * Defines life-time of an instrument. 56 */ 57 enum mode_t { 58 ON_DEMAND = 0, ///< Instrument will be loaded when needed, freed once not needed anymore. 59 ON_DEMAND_HOLD = 1, ///< Instrument will be loaded when needed and kept even if not needed anymore. 60 PERSISTENT = 2 ///< Instrument will immediately be loaded and kept all the time. 61 }; 62 63 /** 64 * Reflects unique ID of an instrument. 65 */ 66 struct instrument_id_t { 67 String FileName; ///< File name of the instrument. 68 uint Index; ///< Index of the instrument within the file. 69 70 // TODO: we should extend operator<() so it will be able to detect that file x and file y are actually the same files, e.g. because one of them is a symlink / share the same inode 71 bool operator<(const instrument_id_t& o) const { 72 return (Index < o.Index || (Index == o.Index && FileName < o.FileName)); 73 } 74 75 bool operator==(const instrument_id_t& o) const { 76 return (Index == o.Index && FileName == o.FileName); 77 } 78 }; 79 80 /** 81 * Rather abstract informations about an instrument. 82 */ 83 struct instrument_info_t { 84 String InstrumentName; 85 String FormatVersion; 86 String Product; 87 String Artists; 88 uint8_t KeyBindings[128]; 89 uint8_t KeySwitchBindings[128]; 90 }; 91 92 /** 93 * Returns all managed instruments. 94 * 95 * This method has to be implemented by the descendant. 96 */ 97 virtual std::vector<instrument_id_t> Instruments() = 0; 98 99 /** 100 * Returns the current life-time strategy for the given 101 * instrument. 102 * 103 * This method has to be implemented by the descendant. 104 */ 105 virtual mode_t GetMode(const instrument_id_t& ID) = 0; 106 107 /** 108 * Change the current life-time strategy for the given 109 * instrument. 110 * 111 * This method has to be implemented by the descendant. 112 */ 113 virtual void SetMode(const instrument_id_t& ID, mode_t Mode) = 0; 114 115 /** 116 * Same as SetMode(), but with the difference that this method 117 * won't block. 118 */ 119 void SetModeInBackground(const instrument_id_t& ID, mode_t Mode); 120 121 /** 122 * Same as loading the given instrument directly on the given 123 * EngineChannel, but this method will not block, instead it 124 * will load the instrument in a separate thread. 125 * 126 * @param ID - the instrument to be loaded 127 * @param pEngineChannel - on which engine channel the instrument 128 * should be loaded 129 */ 130 static void LoadInstrumentInBackground(instrument_id_t ID, EngineChannel* pEngineChannel); 131 132 /** 133 * Stops the background thread that has been started by 134 * LoadInstrumentInBackground. 135 */ 136 static void StopBackgroundThread(); 137 138 /** 139 * Returns the name of the given instrument as reflected by its 140 * file. 141 * 142 * This method has to be implemented by the descendant. 143 */ 144 virtual String GetInstrumentName(instrument_id_t ID) = 0; 145 146 /** 147 * Returns a textual identifier of the data structure for the 148 * given loaded instrument, which usually reflects the name of 149 * of the library used to load the instrument (i.e. "libgig"). 150 * 151 * This method has to be implemented by the descendant. 152 */ 153 virtual String GetInstrumentDataStructureName(instrument_id_t ID) = 0; 154 155 /** 156 * Returns the version of the data structure for the given 157 * loaded instrument, which usually reflects the version of the 158 * library which was used to load the instrument (i.e. "3.1.0"). 159 * 160 * This method has to be implemented by the descendant. 161 */ 162 virtual String GetInstrumentDataStructureVersion(instrument_id_t ID) = 0; 163 164 /** 165 * Spawn an appropriate editor for the given instrument that is 166 * actually capable to handle the instrument's format and data 167 * structure. The instrument editor will be hosted in the 168 * sampler's own process to allow immediate live-editing of the 169 * instrument while playing the instrument in parallel by the 170 * sampler. 171 * 172 * For this to work, instrument editor applications have to 173 * implement the abstract interface class @c InstrumentEditor 174 * and have to generate a plugin DLL that has to be placed into 175 * the appropriate plugin directory of the sampler. 176 * 177 * This method has to be implemented by the descendant. 178 * 179 * @param pEngineChannel - engine channel for which an instrument 180 * editor shall be launched for 181 * @param ID - the instrument for which an editor should be 182 * spawned for 183 * @param pUserData - (optional) arbitrary 3rd party user data 184 * that will blindly be passed to 185 * InstrumentEditor::Main() 186 * @returns pointer to the launched editor 187 * @throws InstrumentManagerException - in case no compatible 188 * instrument editor is registered to the sampler 189 */ 190 virtual InstrumentEditor* LaunchInstrumentEditor(EngineChannel* pEngineChannel, instrument_id_t ID, void* pUserData = NULL) throw (InstrumentManagerException) = 0; 191 192 /** 193 * Returns a list of instrument IDs of the provided instrument 194 * file in case the provided file's format is supported. 195 * 196 * @throws InstrumentManagerException if the format of the 197 * provided instrument file is not supported 198 */ 199 virtual std::vector<instrument_id_t> GetInstrumentFileContent(String File) throw (InstrumentManagerException) = 0; 200 201 /** 202 * Get detailed informations about the provided instrument file. 203 * 204 * @throws InstrumentManagerException if the format of the 205 * provided instrument file is not supported 206 */ 207 virtual instrument_info_t GetInstrumentInfo(instrument_id_t ID) throw (InstrumentManagerException) = 0; 208 }; 209 210 } 211 212 #endif // __LS_INSTRUMENTMANAGER_H__ 213