/[svn]/linuxsampler/trunk/src/drivers/Plugin.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/drivers/Plugin.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1895 - (show annotations) (download)
Sun May 3 12:15:40 2009 UTC (10 years, 1 month ago) by persson
File size: 8596 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 /***************************************************************************
2 * *
3 * Copyright (C) 2008 - 2009 Andreas Persson *
4 * *
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., 51 Franklin St, Fifth Floor, Boston, *
18 * MA 02110-1301 USA *
19 ***************************************************************************/
20
21 #include <sstream>
22
23 #include "Plugin.h"
24 #include "audio/AudioOutputDeviceFactory.h"
25 #include "midi/MidiInputDeviceFactory.h"
26
27 namespace LinuxSampler {
28
29 // *************** PluginGlobal ***************
30 // *
31
32 PluginGlobal::PluginGlobal() :
33 RefCount(0) {
34 // we need to remove the ASIO driver, otherwise the lscp info
35 // methods will lock up the audio device
36 AudioOutputDeviceFactory::Unregister("ASIO");
37
38 REGISTER_AUDIO_OUTPUT_DRIVER(AudioOutputDevicePlugin);
39 REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDevicePlugin, ParameterActive);
40 REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDevicePlugin, ParameterSampleRate);
41 REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDevicePlugin, ParameterChannels);
42 REGISTER_AUDIO_OUTPUT_DRIVER_PARAMETER(AudioOutputDevicePlugin, ParameterFragmentSize);
43
44 REGISTER_MIDI_INPUT_DRIVER(MidiInputDevicePlugin);
45 REGISTER_MIDI_INPUT_DRIVER_PARAMETER(MidiInputDevicePlugin, ParameterActive);
46 REGISTER_MIDI_INPUT_DRIVER_PARAMETER(MidiInputDevicePlugin, ParameterPorts);
47
48 pSampler = new Sampler;
49
50 // using LOOPBACK instead of ANY to prevent windows firewall
51 // warnings
52 pLSCPServer = new LSCPServer(pSampler, htonl(INADDR_LOOPBACK),
53 htons(LSCP_PORT));
54 pLSCPServer->StartThread();
55 pLSCPServer->WaitUntilInitialized();
56
57 pEventThread = new EventThread(pSampler);
58 pEventThread->StartThread();
59 }
60
61
62 PluginGlobal::~PluginGlobal() {
63 pEventThread->StopThread();
64 pLSCPServer->StopThread();
65 pLSCPServer->RemoveListeners();
66
67 delete pEventThread;
68 delete pSampler;
69 delete pLSCPServer;
70 }
71
72
73 // *************** EventThread ***************
74 // *
75
76
77 EventThread::EventThread(Sampler* pSampler) :
78 Thread(false, false, 0, 0),
79 pSampler(pSampler) {
80 }
81
82 int EventThread::Main() {
83 for (;;) {
84 sleep(1);
85 pSampler->fireStatistics();
86 }
87 return 0;
88 }
89
90
91 // *************** Plugin ***************
92 // *
93
94 PluginGlobal* Plugin::global = 0;
95
96 Plugin::Plugin(bool bDoPreInit) :
97 pAudioDevice(0),
98 pMidiDevice(0) {
99 bPreInitDone = false;
100 if (bDoPreInit) PreInit();
101 }
102
103 void Plugin::PreInit() {
104 if (bPreInitDone) return;
105
106 bPreInitDone = true;
107 if (!global) {
108 global = new PluginGlobal;
109 }
110 global->RefCount++;
111 }
112
113 void Plugin::Init(int SampleRate, int FragmentSize, int Channels) {
114 if (pAudioDevice && SampleRate == pAudioDevice->SampleRate() &&
115 FragmentSize == pAudioDevice->MaxSamplesPerCycle()) {
116 return; // nothing has changed
117 }
118
119 String oldState;
120 if (pAudioDevice) {
121 oldState = GetState();
122 RemoveChannels();
123 global->pSampler->DestroyAudioOutputDevice(pAudioDevice);
124 }
125 std::map<String, String> params;
126 params["SAMPLERATE"] = ToString(SampleRate);
127 params["FRAGMENTSIZE"] = ToString(FragmentSize);
128 if (Channels > 0) params["CHANNELS"] = ToString(Channels);
129 pAudioDevice = dynamic_cast<AudioOutputDevicePlugin*>(
130 global->pSampler->CreateAudioOutputDevice(AudioOutputDevicePlugin::Name(), params));
131
132 if (!pMidiDevice) {
133 pMidiDevice = dynamic_cast<MidiInputDevicePlugin*>(
134 global->pSampler->CreateMidiInputDevice(MidiInputDevicePlugin::Name(),
135 std::map<String,String>()));
136 }
137
138 if (!oldState.empty()) {
139 SetState(oldState);
140 }
141 }
142
143 Plugin::~Plugin() {
144 RemoveChannels();
145 if (pAudioDevice) global->pSampler->DestroyAudioOutputDevice(pAudioDevice);
146 if (pMidiDevice) global->pSampler->DestroyMidiInputDevice(pMidiDevice);
147 if (bPreInitDone) {
148 if (--global->RefCount == 0) {
149 delete global;
150 global = 0;
151 }
152 }
153 }
154
155 void Plugin::InitState() {
156 SamplerChannel* channel = global->pSampler->AddSamplerChannel();
157 channel->SetEngineType("gig");
158 channel->SetAudioOutputDevice(pAudioDevice);
159 channel->SetMidiInputDevice(pMidiDevice);
160 channel->SetMidiInputChannel(midi_chan_1);
161 }
162
163
164 String Plugin::GetState() {
165 std::stringstream s;
166
167 s << GLOBAL_VOLUME << '\n';
168 std::map<uint, SamplerChannel*> channels = global->pSampler->GetSamplerChannels();
169 for (std::map<uint, SamplerChannel*>::iterator iter = channels.begin() ;
170 iter != channels.end() ; iter++) {
171 SamplerChannel* channel = iter->second;
172 if (channel->GetAudioOutputDevice() == pAudioDevice) {
173 EngineChannel* engine_channel = channel->GetEngineChannel();
174 String filename = engine_channel->InstrumentFileName();
175 s << channel->GetMidiInputChannel() << ' ' <<
176 engine_channel->Volume() << ' ' <<
177 filename << '\n' <<
178 engine_channel->InstrumentIndex() << ' ' <<
179 engine_channel->GetSolo() << ' ' <<
180 (engine_channel->GetMute() == 1) << '\n';
181 }
182 }
183 return s.str();
184 }
185
186 void Plugin::RemoveChannels() {
187 if(global == NULL) return;
188
189 std::map<uint, SamplerChannel*> channels = global->pSampler->GetSamplerChannels();
190
191 for (std::map<uint, SamplerChannel*>::iterator iter = channels.begin() ;
192 iter != channels.end() ; iter++) {
193 if (iter->second->GetAudioOutputDevice() == pAudioDevice) {
194 global->pSampler->RemoveSamplerChannel(iter->second);
195 }
196 }
197 }
198
199 bool Plugin::SetState(String State) {
200 RemoveChannels();
201
202 std::stringstream s(State);
203 s >> GLOBAL_VOLUME;
204
205 int midiChannel;
206 float volume;
207 while (s >> midiChannel >> volume) {
208 s.ignore();
209 String filename;
210 std::getline(s, filename);
211 int index;
212 bool solo;
213 bool mute;
214 s >> index >> solo >> mute;
215
216 SamplerChannel* channel = global->pSampler->AddSamplerChannel();
217 channel->SetEngineType("gig");
218 channel->SetAudioOutputDevice(pAudioDevice);
219 channel->SetMidiInputDevice(pMidiDevice);
220 channel->SetMidiInputChannel(midi_chan_t(midiChannel));
221
222 EngineChannel* engine_channel = channel->GetEngineChannel();
223 engine_channel->Volume(volume);
224 if (!filename.empty() && index != -1) {
225 InstrumentManager::instrument_id_t id;
226 id.FileName = filename;
227 id.Index = index;
228 InstrumentManager::LoadInstrumentInBackground(id, engine_channel);
229 }
230 if (solo) engine_channel->SetSolo(solo);
231 if (mute) engine_channel->SetMute(1);
232 }
233
234 return true;
235 }
236 }

  ViewVC Help
Powered by ViewVC