/[svn]/linuxsampler/trunk/src/plugins/InstrumentEditor.h
ViewVC logotype

Annotation of /linuxsampler/trunk/src/plugins/InstrumentEditor.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1653 - (hide annotations) (download) (as text)
Wed Jan 30 01:51:46 2008 UTC (16 years, 2 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 16139 byte(s)
* added support for notifying instrument editors on note-on / note-off
  events (e.g. to highlight the pressed keys on the virtual keyboard
  of gigedit)
* fixed return value of recently added Thread::TestCancel() method
* be verbose on DLL load errors (on Linux)

1 schoenebeck 1374 /***************************************************************************
2     * *
3 schoenebeck 1653 * Copyright (C) 2007, 2008 Christian Schoenebeck *
4 schoenebeck 1374 * *
5     * This program is free software; you can redistribute it and/or modify *
6     * it under the terms of the GNU General Public License as published by *
7     * the Free Software Foundation; either version 2 of the License, or *
8     * (at your option) any later version. *
9     * *
10     * This program is distributed in the hope that it will be useful, *
11     * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13     * GNU General Public License for more details. *
14     * *
15     * You should have received a copy of the GNU General Public License *
16     * along with this program; if not, write to the Free Software *
17     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
18     * MA 02111-1307 USA *
19     ***************************************************************************/
20    
21     #ifndef LS_INSTRUMENT_EDITOR_H
22     #define LS_INSTRUMENT_EDITOR_H
23    
24     #include "../common/global.h"
25     #include "../common/Thread.h"
26    
27     #include <set>
28    
29     namespace LinuxSampler {
30    
31     // just symbol prototyping
32     class InstrumentEditorListener;
33    
34     /** @brief Instrument Editor Interface (external plugin)
35     *
36     * LinuxSampler allows to spawn arbitrary instrument editor applications
37     * within the sampler's own process. That way instrument editors are
38     * able to modify already loaded instruments live or on-the-fly, that is
39     * without having to load it again neither on sampler nor on editor side,
40     * which is essential for editing large instruments.
41     *
42     * Instrument editors have to implement this abstract base class, embedded
43     * into a DLL and placed into the respective sampler's library path. The
44     * sampler will load these external DLLs as plugins on startup. Whenever
45     * there's a request for editing an instrument, the sampler will try to
46     * launch a matching registered editor, by calling the respective
47     * plugin's @c Main() method.
48     */
49     class InstrumentEditor : protected Thread {
50     public:
51    
52     /////////////////////////////////////////////////////////////////
53     // abstract methods
54     // (these have to be implemented by the descendant)
55    
56     /**
57     * Entry point for the instrument editor's thread. As the
58     * instrument data structure is passed as typeless (void*)
59     * pointer, this is not type safe! The implementing instrument
60     * editor has to interpret the @a sTypeName and @a sTypeVersion
61     * arguments to determine if it's able to cast the instrument
62     * pointer to a known type and actually be able to work with it.
63     *
64     * @param pInstrument - pointer to the respective instrument object
65     * @param sTypeName - format of the instrument data structure
66     * (i.e. @c "libgig" )
67     * @param sTypeVersion - version of the instrument data structure
68     * (i.e. @c "3.0.1" ).
69     */
70     virtual int Main(void* pInstrument, String sTypeName, String sTypeVersion) = 0;
71    
72     /**
73     * The instrument editor has to return @c true in case it supports
74     * the given instrument data structure type and version, it has to
75     * return @c false otherwise. This method will be called by the
76     * sampler to determine which editor is capable to work with a
77     * certain instrument.
78     *
79     * @param sTypeName - i.e. @c "libgig"
80 schoenebeck 1425 * @param sTypeVersion - i.e. @c "3.0.1"
81 schoenebeck 1374 */
82     virtual bool IsTypeSupported(String sTypeName, String sTypeVersion) = 0;
83    
84     /**
85     * The instrument editor's name (i.e. @c "gigedit" ).
86     */
87     virtual String Name() = 0;
88    
89     /**
90     * The instrument editor's version (i.e. @c "0.0.1" ).
91     */
92     virtual String Version() = 0;
93    
94     /**
95     * Arbitrary textual description of the instrument editor
96     * (i.e. "Gigasampler and DLS format editor, GTK based").
97     */
98     virtual String Description() = 0;
99    
100    
101    
102     /////////////////////////////////////////////////////////////////
103     // normal methods
104     // (usually not to be overriden by descendant)
105    
106     /** @brief Dispatch pending sample removal event.
107     *
108     * @e SHOULD be called by the instrument editor @e before deleting
109     * samples, so the sampler can react by stopping usage of these
110     * samples to avoid a crash.
111     *
112     * After calling this method, the instrument editor @e MUST call
113     * @c NotifySamplesRemoved() after it actually deleted the samples, so
114     * the sampler can react by i.e. resuming playback of sampler engines.
115     *
116     * @param Samples - list of samples that will be deleted by the
117     * instrument editor
118     */
119     void NotifySamplesToBeRemoved(std::set<void*> Samples);
120    
121     /** @brief Dispatch completed sample removal event.
122     *
123     * Inform the sampler that the by @c NotifySamplesToBeRemoved()
124     * previously announced samples have been deleted.
125     */
126     void NotifySamplesRemoved();
127    
128     /** @brief Dispatch pending data structure modification event.
129     *
130     * @e SHOULD be called by the instrument editor @e before modifying
131     * data structures (except samples, which have their own dispatch
132     * methods) which could otherwise lead to undesired synchronisation
133     * issues and a crash. The respective data structure is passed as a
134     * typeless pointer @a pStruct , so the instrument editor additionally
135     * has to pass the name of the data structure (i.e. @c "gig::Region" ),
136     * so the sampler can cast the pointer to an appropriate type. The
137     * sampler will react by stopping usage of the respective data
138     * structure.
139     *
140     * After calling this method, the instrument editor @e MUST call
141     * @c NotifyDataStructureChanged() , so the sampler can react by
142     * resuming usage of the respective data structure for playback.
143     *
144     * @param pStruct - data structure going to be modified
145     * @param sStructType - name of the data structure (i.e. its C++
146     * struct or class name)
147     */
148     void NotifyDataStructureToBeChanged(void* pStruct, String sStructType);
149    
150     /** @brief Dispatch completed data structure modification event.
151     *
152     * Inform the sampler that the by @c NotifyDataStructureToBeChanged()
153     * previously announced data structure has been completely modified.
154     *
155     * @param pStruct - data structure that has been modified
156     * @param sStructType - name of the data structure (i.e. its C++
157     * struct or class name)
158     */
159     void NotifyDataStructureChanged(void* pStruct, String sStructType);
160    
161     /** @brief Dispatch sample reference changed event.
162     *
163     * @e SHOULD be called by the instrument editor @e after a certain data
164     * structure changed its reference / pointer to a sample, so the
165     * sampler can react by:
166     *
167     * - Caching the newly referenced sample if necessary.
168     * - Un-caching the old referenced sample if necessary.
169     *
170     * @e Note: the instrument editor additionally @e MUST embed this call
171     * into the respective @c NotifyDataStructureToBeChanged() and
172     * @c NotifyDataStructureChanged() calls for announcing the data
173     * structure whose sample reference is actually to be changed, so the
174     * sampler can react by suspending usage. For example:
175     * @code
176     * NotifyDataStructureToBeChanged(pDimReg, "gig::DimensionRegion");
177     * gig::Sample* pOldSample = pDimReg->pSample;
178     * pDimReg->pSample = pNewSample;
179     * NotifySampleReferenceChanged(pOldSample, pNewSample);
180     * NotifyDataStructureChanged(pDimReg, "gig::DimensionRegion");
181     * @endcode
182     * So calling this method alone is not safe!
183     *
184     * @param pOldSample - previous sample reference
185     * @param pNewSample - current sample reference
186     */
187     void NotifySampleReferenceChanged(void* pOldSample, void* pNewSample);
188    
189     /**
190     * Launch the instrument editor for the given instrument. The
191     * editor will be spawned in its own thread and this method will
192     * return as soon as the editor's thread actually started.
193     */
194     void Launch(void* pInstrument, String sTypeName, String sTypeVersion);
195    
196     /**
197     * Registers object that wants to be notified on events.
198     */
199     void AddListener(InstrumentEditorListener* pListener);
200    
201     /**
202     * Unregisters object that doesn't want to be notified anymore.
203     */
204     void RemoveListener(InstrumentEditorListener* pListener);
205    
206 schoenebeck 1653
207 schoenebeck 1374 /**
208 schoenebeck 1653 * Informs the instrument editor that a @e note @e on event occured
209     * (e.g. caused by a MIDI keyboard connected to the sampler).
210     * Communication acts asynchronously, that is this method call doesn't
211     * lock in any way and returns immediately. It is thus realtime safe.
212     *
213     * @e Note: this method is usually only called by the sampler.
214     *
215     * @see ActiveNotesChanged(), NoteIsActive()
216     */
217     void SendNoteOnToEditor(uint8_t Key, uint8_t Velocity);
218    
219     /**
220     * Informs the instrument editor that a @e note @e off event occured
221     * (e.g. caused by a MIDI keyboard connected to the sampler).
222     * Communication acts asynchronously, that is this method call doesn't
223     * lock in any way and returns immediately. It is thus realtime safe.
224     *
225     * @e Note: this method is usually only called by the sampler.
226     *
227     * @see ActiveNotesChanged(), NoteIsActive()
228     */
229     void SendNoteOffToEditor(uint8_t Key, uint8_t Velocity);
230    
231     /**
232     * Can be called by the instrument editor to check whether a new note
233     * on or note off MIDI event arrived to the sampler during the last
234     * call to this method. So this is a asynchronously, "polling" based
235     * communication mechanism, which works in conjunction with the
236     * NoteIsActive() method call.
237     */
238     bool NotesChanged();
239    
240     /**
241     * Can be called by the instrument editor to check whether a new note
242     * on or note off MIDI event arrived to the sampler for @a Key during
243     * the last call to this method. So this is a asynchronously,
244     * "polling" based communication mechanism, which works in
245     * conjunction with the NoteIsActive() method call.
246     */
247     bool NoteChanged(uint8_t Key);
248    
249     /**
250     * Can be called by the instrument editor to check which key / note
251     * is currently active by the sampler, e.g. to highlight the
252     * respective keys of a virtual keyboard in the instrument editor.
253     *
254     * @see NotesChanged(), NoteChanged()
255     */
256     bool NoteIsActive(uint8_t Key);
257    
258     /**
259 schoenebeck 1374 * Constructor
260     */
261     InstrumentEditor();
262    
263 schoenebeck 1653 /**
264     * Destructor
265     */
266     virtual ~InstrumentEditor();
267    
268 schoenebeck 1374 protected:
269     std::set<InstrumentEditorListener*> listeners;
270    
271     // derived abstract method from base class 'Thread'
272     virtual int Main();
273     private:
274     void* pInstrument;
275     String sTypeName;
276     String sTypeVersion;
277 schoenebeck 1653 void* pNotesChanged;
278     void* pNoteChanged;
279     void* pNoteIsActive;
280 schoenebeck 1374 };
281    
282     /** @brief Instrument Editor Notifications
283     *
284     * This abstract interface class has to be implemented by classes that
285     * want to be notified on certain events of an instrument editor. This is
286     * typically used on sampler side, but might also be used by an instrument
287     * editor to get informed about modifications another instrument editor
288     * makes.
289     */
290     class InstrumentEditorListener {
291     public:
292     /** @brief Called after the instrument editor stopped running.
293     *
294     * Automatically called after the instrument editor application stopped
295     * running. This method has to be implemented by the descendant.
296     *
297     * @param pSender - instrument editor that died
298     */
299     virtual void OnInstrumentEditorQuit(InstrumentEditor* pSender) = 0;
300    
301     /** @brief Called before samples are to be deleted.
302     *
303     * See the dispatcher method
304     * @c InstrumentEditor::NotifySamplesToBeRemoved() for details.
305     * This method has to be implemented by the descendant.
306     *
307     * @param Samples - list of samples that will be deleted by the
308     * instrument editor
309     * @param pSender - instrument editor that is going to do this
310     * modification
311     */
312     virtual void OnSamplesToBeRemoved(std::set<void*> Samples, InstrumentEditor* pSender) = 0;
313    
314     /** @brief Called after samples have been deleted.
315     *
316     * See the dispatcher method
317     * @c InstrumentEditor::NotifySamplesRemoved() for details.
318     * This method has to be implemented by the descendant.
319     *
320     * @param pSender - instrument editor that did this modification
321     */
322     virtual void OnSamplesRemoved(InstrumentEditor* pSender) = 0;
323    
324     /** @brief Called before data structure is to be modified.
325     *
326     * See the dispatcher method
327     * @c InstrumentEditor::NotifyDataStructureToBeChanged() for details.
328     * This method has to be implemented by the descendant.
329     *
330     * @param pStruct - data structure going to be modified
331     * @param sStructType - name of the data structure (i.e. its C++
332     * struct or class name)
333     * @param pSender - instrument editor that is going to do this
334     * modification
335     */
336     virtual void OnDataStructureToBeChanged(void* pStruct, String sStructType, InstrumentEditor* pSender) = 0;
337    
338     /** @brief Called after data structure has been modified.
339     *
340     * See the dispatcher method
341     * @c InstrumentEditor::NotifyDataStructureChanged() for details.
342     * This method has to be implemented by the descendant.
343     *
344     * @param pStruct - data structure that has been modified
345     * @param sStructType - name of the data structure (i.e. its C++
346     * struct or class name)
347     * @param pSender - instrument editor that did this modification
348     */
349     virtual void OnDataStructureChanged(void* pStruct, String sStructType, InstrumentEditor* pSender) = 0;
350    
351     /** @brief Called after some data structure changed its reference to a sample.
352     *
353     * @c InstrumentEditor::NotifySampleReferenceChanged() for details.
354     * This method has to be implemented by the descendant.
355     *
356     * @param pOldSample - previous sample reference
357     * @param pNewSample - current sample reference
358     * @param pSender - instrument editor that did this modification
359     */
360     virtual void OnSampleReferenceChanged(void* pOldSample, void* pNewSample, InstrumentEditor* pSender) = 0;
361     };
362    
363     } // namespace LinuxSampler
364    
365     #endif // LS_INSTRUMENT_EDITOR_H

  ViewVC Help
Powered by ViewVC