/[svn]/linuxsampler/trunk/src/engines/InstrumentManagerThread.cpp
ViewVC logotype

Annotation of /linuxsampler/trunk/src/engines/InstrumentManagerThread.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1895 - (hide annotations) (download)
Sun May 3 12:15:40 2009 UTC (14 years, 11 months ago) by persson
File size: 7328 byte(s)
* fixes for using large audio device buffers
* VST: added support for sample rate and buffer size changes
* VST: close editor (Fantasia) when the VST is removed
* minor fix in configure for mmsystem.h detection on MinGW
* removed warnings from gcc 4.4 and valgrind

1 schoenebeck 947 /***************************************************************************
2     * *
3 schoenebeck 1040 * Copyright (C) 2005 - 2007 Christian Schoenebeck *
4 schoenebeck 947 * *
5     * This library 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 library 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 library; if not, write to the Free Software *
17     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
18     * MA 02111-1307 USA *
19     ***************************************************************************/
20    
21     #include "InstrumentManagerThread.h"
22    
23 schoenebeck 1424 #include "../common/global_private.h"
24 iliev 1826 #include "EngineChannelFactory.h"
25 schoenebeck 1424
26 schoenebeck 947 namespace LinuxSampler {
27    
28     InstrumentManagerThread::InstrumentManagerThread() : Thread(true, false, 0, -4) {
29 iliev 1761 eventHandler.pThread = this;
30 schoenebeck 947 }
31    
32     InstrumentManagerThread::~InstrumentManagerThread() {
33     }
34    
35     /**
36     * @brief Order loading of a new instrument.
37     *
38     * The request will go into a queue waiting to be processed by the
39     * class internal task thread. This method will immediately return and
40     * the instrument will be loaded in the background.
41     *
42     * @param Filename - file name of the instrument
43     * @param uiInstrumentIndex - index of the instrument within the file
44     * @param pEngineChannel - engine channel on which the instrument should be loaded
45     */
46     void InstrumentManagerThread::StartNewLoad(String Filename, uint uiInstrumentIndex, EngineChannel* pEngineChannel) {
47 persson 1038 dmsg(1,("Scheduling '%s' (Index=%d) to be loaded in background (if not loaded yet).\n",Filename.c_str(),uiInstrumentIndex));
48 iliev 1761
49     static bool listenerRegistered = false;
50     if (!listenerRegistered) {
51     pEngineChannel->GetSampler()->AddChannelCountListener(&eventHandler);
52     listenerRegistered = true;
53     }
54    
55    
56 schoenebeck 947 // already tell the engine which instrument to load
57     pEngineChannel->PrepareLoadInstrument(Filename.c_str(), uiInstrumentIndex);
58    
59     command_t cmd;
60     cmd.type = command_t::DIRECT_LOAD;
61     cmd.pEngineChannel = pEngineChannel;
62 schoenebeck 989
63     mutex.Lock();
64     queue.push_back(cmd);
65     mutex.Unlock();
66    
67 schoenebeck 947 StartThread(); // ensure thread is running
68     conditionJobsLeft.Set(true); // wake up thread
69     }
70    
71     /**
72     * @brief Order changing the life-time strategy of an instrument.
73     *
74     * The request will go into a queue waiting to be processed by the
75     * class internal task thread. This method will immediately return and
76     * in case the instrument has to be loaded due to a mode change to
77     * PERSISTENT, it will be loaded in the background.
78     *
79     * @param pManager - InstrumentManager which manages the instrument
80     * @param ID - unique ID of the instrument
81     * @param Mode - life-time strategy to set for this instrument
82     */
83     void InstrumentManagerThread::StartSettingMode(InstrumentManager* pManager, const InstrumentManager::instrument_id_t& ID, InstrumentManager::mode_t Mode) {
84     command_t cmd;
85     cmd.type = command_t::INSTR_MODE;
86     cmd.pManager = pManager;
87     cmd.instrumentId = ID;
88     cmd.mode = Mode;
89 schoenebeck 989
90     mutex.Lock();
91     queue.push_back(cmd);
92     mutex.Unlock();
93    
94 schoenebeck 947 StartThread(); // ensure thread is running
95     conditionJobsLeft.Set(true); // wake up thread
96     }
97    
98     // Entry point for the task thread.
99     int InstrumentManagerThread::Main() {
100     while (true) {
101 nagata 1649
102     #if CONFIG_PTHREAD_TESTCANCEL
103     TestCancel();
104     #endif
105    
106 schoenebeck 989 while (!queue.empty()) {
107 schoenebeck 947 command_t cmd;
108 schoenebeck 989
109     // grab a new command from the queue
110     mutex.Lock();
111     cmd = queue.front();
112 iliev 1761 queue.pop_front();
113 schoenebeck 989 mutex.Unlock();
114    
115 schoenebeck 947 try {
116     switch (cmd.type) {
117     case command_t::DIRECT_LOAD:
118 iliev 1826 EngineChannelFactory::SetDeleteEnabled(cmd.pEngineChannel, false);
119 schoenebeck 947 cmd.pEngineChannel->LoadInstrument();
120 iliev 1826 EngineChannelFactory::SetDeleteEnabled(cmd.pEngineChannel, true);
121 schoenebeck 947 break;
122     case command_t::INSTR_MODE:
123     cmd.pManager->SetMode(cmd.instrumentId, cmd.mode);
124     break;
125     default:
126     std::cerr << "InstrumentManagerThread: unknown command - BUG!\n" << std::flush;
127     }
128 schoenebeck 1040 } catch (Exception e) {
129 schoenebeck 947 e.PrintMessage();
130 iliev 1826 if (cmd.type == command_t::DIRECT_LOAD) {
131     EngineChannelFactory::SetDeleteEnabled(cmd.pEngineChannel, true);
132     }
133 schoenebeck 1040 } catch (...) {
134     std::cerr << "InstrumentManagerThread: some exception occured, could not finish task\n" << std::flush;
135 iliev 1826 if (cmd.type == command_t::DIRECT_LOAD) {
136     EngineChannelFactory::SetDeleteEnabled(cmd.pEngineChannel, true);
137     }
138 schoenebeck 947 }
139     }
140    
141     // nothing left to do, sleep until new jobs arrive
142     conditionJobsLeft.WaitIf(false);
143     // reset flag
144     conditionJobsLeft.Set(false);
145     // unlock condition object so it can be turned again by other thread
146     conditionJobsLeft.Unlock();
147     }
148 persson 1895 return 0;
149 schoenebeck 947 }
150 persson 1895
151 iliev 1761 void InstrumentManagerThread::EventHandler::ChannelToBeRemoved(SamplerChannel* pChannel) {
152     /*
153     Removing from the queue an eventual scheduled loading of an instrument
154     to a sampler channel which is going to be removed.
155     */
156     pThread->mutex.Lock();
157     std::list<command_t>::iterator it;
158     for (it = pThread->queue.begin(); it != pThread->queue.end();){
159     if ((*it).type != command_t::DIRECT_LOAD) { ++it; continue; }
160     if ((*it).pEngineChannel == pChannel->GetEngineChannel()) {
161     it = pThread->queue.erase(it);
162     // we don't break here because the same engine channel could
163     // occur more than once in the queue, so don't make optimizations
164     } else {
165     ++it;
166     }
167     }
168     pThread->mutex.Unlock();
169     }
170 schoenebeck 947 } // namespace LinuxSampler

  ViewVC Help
Powered by ViewVC