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

Contents of /linuxsampler/trunk/src/engines/gig/EngineChannel.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2611 - (show annotations) (download)
Mon Jun 9 19:20:37 2014 UTC (9 years, 10 months ago) by schoenebeck
File size: 8108 byte(s)
* Fixed crash when loading an instrument script.
* Fixed "init" script handler only to be executed once:
  when the script was loaded.
* Fixed aftertouch script event which always had value zero
  and controller number was set to aftertouch value instead.
* gig Engine: Fixed handling of "smartmidi" dimension, which
  was recognized as "unknown" dimension.
* Fixed script function gig_set_dim_zone(): was accessing
  wrong event.
* ls_instr_script command line tool: is now not limited to
  core language scripts, but can now also parse sampler format
  dependent instrument scripts, with the respective specific
  built-in script variables and functions.
* ScriptVM: Fixed runtime behavior of "and" and "or" binary
  script expressions, which also evaluated the right hand side
  of the expression even if the left hand side already failed
  the overall expression semantic to become true.
* Bumped version (1.0.0.svn46).

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2003,2004 by Benno Senoner and Christian Schoenebeck *
6 * Copyright (C) 2005-2008 Christian Schoenebeck *
7 * Copyright (C) 2009-2012 Christian Schoenebeck and Grigor Iliev *
8 * *
9 * This program is free software; you can redistribute it and/or modify *
10 * it under the terms of the GNU General Public License as published by *
11 * the Free Software Foundation; either version 2 of the License, or *
12 * (at your option) any later version. *
13 * *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
18 * *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program; if not, write to the Free Software *
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
22 * MA 02111-1307 USA *
23 ***************************************************************************/
24
25 #include "EngineChannel.h"
26 #include "Engine.h"
27
28 namespace LinuxSampler { namespace gig {
29 EngineChannel::EngineChannel() {
30
31 }
32
33 EngineChannel::~EngineChannel() {
34 DisconnectAudioOutputDevice();
35 // In case the channel was removed before the instrument was
36 // fully loaded, try to give back instrument again (see bug #113)
37 InstrumentChangeCmd< ::gig::DimensionRegion, ::gig::Instrument>& cmd = ChangeInstrument(NULL);
38 if (cmd.pInstrument) {
39 Engine::instruments.HandBack(cmd.pInstrument, this);
40 }
41 ///////
42 }
43
44 AbstractEngine::Format EngineChannel::GetEngineFormat() { return AbstractEngine::GIG; }
45
46 /** This method is not thread safe! */
47 void EngineChannel::ResetInternal() {
48 CurrentKeyDimension = 0;
49 EngineChannelBase<Voice, ::gig::DimensionRegion, ::gig::Instrument>::ResetInternal();
50 }
51
52 /**
53 * Will be called by the MIDIIn Thread to signal that a program
54 * change should be performed. As a program change isn't
55 * real-time safe, the actual change is performed by the disk
56 * thread.
57 *
58 * @param Program - MIDI program change number
59 */
60 void EngineChannel::SendProgramChange(uint8_t Program) {
61 SetMidiProgram(Program);
62 Engine* engine = dynamic_cast<Engine*>(pEngine);
63 if(engine == NULL) return;
64
65 if(engine->GetDiskThread()) {
66 uint32_t merged = (GetMidiBankMsb() << 16) | (GetMidiBankLsb() << 8) | Program;
67 engine->GetDiskThread()->OrderProgramChange(merged, this);
68 } else {
69 // TODO:
70 }
71 }
72
73 /**
74 * Load an instrument from a .gig file. PrepareLoadInstrument() has to
75 * be called first to provide the information which instrument to load.
76 * This method will then actually start to load the instrument and block
77 * the calling thread until loading was completed.
78 *
79 * @see PrepareLoadInstrument()
80 */
81 void EngineChannel::LoadInstrument() {
82 InstrumentResourceManager* pInstrumentManager = dynamic_cast<InstrumentResourceManager*>(pEngine->GetInstrumentManager());
83
84 // make sure we don't trigger any new notes with an old
85 // instrument
86 InstrumentChangeCmd< ::gig::DimensionRegion, ::gig::Instrument>& cmd = ChangeInstrument(0);
87 if (cmd.pInstrument) {
88 // give old instrument back to instrument manager, but
89 // keep the dimension regions and samples that are in use
90 pInstrumentManager->HandBackInstrument(cmd.pInstrument, this, cmd.pRegionsInUse);
91 }
92 cmd.pRegionsInUse->clear();
93
94 // delete all key groups
95 DeleteGroupEventLists();
96
97 // request gig instrument from instrument manager
98 ::gig::Instrument* newInstrument;
99 try {
100 InstrumentManager::instrument_id_t instrid;
101 instrid.FileName = InstrumentFile;
102 instrid.Index = InstrumentIdx;
103
104 newInstrument = pInstrumentManager->Borrow(instrid, this);
105 if (!newInstrument) {
106 throw InstrumentManagerException("resource was not created");
107 }
108
109 if (newInstrument->ScriptSlotCount() > 1) {
110 std::cerr << "WARNING: Executing more than one real-time instrument script slot is not implemented yet!\n";
111 }
112 ::gig::Script* script = newInstrument->GetScriptOfSlot(0);
113 if (script) {
114 String sourceCode = script->GetScriptAsText();
115 LoadInstrumentScript(sourceCode);
116 }
117 }
118 catch (RIFF::Exception e) {
119 InstrumentStat = -2;
120 StatusChanged(true);
121 String msg = "gig::Engine error: Failed to load instrument, cause: " + e.Message;
122 throw Exception(msg);
123 }
124 catch (InstrumentManagerException e) {
125 InstrumentStat = -3;
126 StatusChanged(true);
127 String msg = "gig::Engine error: Failed to load instrument, cause: " + e.Message();
128 throw Exception(msg);
129 }
130 catch (...) {
131 InstrumentStat = -4;
132 StatusChanged(true);
133 throw Exception("gig::Engine error: Failed to load instrument, cause: Unknown exception while trying to parse gig file.");
134 }
135
136 RoundRobinIndex = 0;
137 for (int i = 0 ; i < 128 ; i++) pMIDIKeyInfo[i].pRoundRobinIndex = NULL;
138
139 // rebuild ActiveKeyGroups map with key groups of current
140 // instrument and set the round robin pointers to use one
141 // counter for each region
142 int region = 0;
143 for (::gig::Region* pRegion = newInstrument->GetFirstRegion(); pRegion; pRegion = newInstrument->GetNextRegion()) {
144 AddGroup(pRegion->KeyGroup);
145
146 RoundRobinIndexes[region] = 0;
147 for (int iKey = pRegion->KeyRange.low; iKey <= pRegion->KeyRange.high; iKey++) {
148 pMIDIKeyInfo[iKey].pRoundRobinIndex = &RoundRobinIndexes[region];
149 }
150 region++;
151 }
152
153 InstrumentIdxName = newInstrument->pInfo->Name;
154 InstrumentStat = 100;
155
156 ChangeInstrument(newInstrument);
157
158 StatusChanged(true);
159 }
160
161 void EngineChannel::ProcessKeySwitchChange(int key) {
162 // Change key dimension value if key is in keyswitching area
163 {
164 if (key >= pInstrument->DimensionKeyRange.low && key <= pInstrument->DimensionKeyRange.high)
165 CurrentKeyDimension = float(key - pInstrument->DimensionKeyRange.low) /
166 (pInstrument->DimensionKeyRange.high - pInstrument->DimensionKeyRange.low + 1);
167 }
168 }
169
170 String EngineChannel::InstrumentFileName() {
171 return EngineChannelBase<Voice, ::gig::DimensionRegion, ::gig::Instrument>::InstrumentFileName();
172 }
173
174 String EngineChannel::InstrumentFileName(int index) {
175 if (index == 0) return InstrumentFileName();
176 if (!pInstrument || !pInstrument->GetParent()) return "";
177 DLS::File* pMainFile = dynamic_cast<DLS::File*>(pInstrument->GetParent());
178 if (!pMainFile) return "";
179 RIFF::File* pExtensionFile = pMainFile->GetExtensionFile(index);
180 return (pExtensionFile) ? pExtensionFile->GetFileName() : "";
181 }
182
183 }} // namespace LinuxSampler::gig

  ViewVC Help
Powered by ViewVC