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

Annotation of /linuxsampler/trunk/src/engines/sf2/Engine.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2027 - (hide annotations) (download)
Tue Nov 3 19:27:42 2009 UTC (14 years, 5 months ago) by iliev
File size: 7861 byte(s)
* sfz engine: support for exclusive groups
* sf2 engine: support for exclusive groups
* sf2 engine: manage presets only
* sf2 engine: preset regions are now taken into account

1 iliev 2012 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5     * Copyright (C) 2003,2004 by Benno Senoner and Christian Schoenebeck *
6     * Copyright (C) 2005-2009 Christian Schoenebeck *
7     * Copyright (C) 2009 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 "Engine.h"
26     #include "EngineChannel.h"
27    
28     namespace LinuxSampler { namespace sf2 {
29     Engine::Format Engine::GetEngineFormat() { return SF2; }
30    
31     /**
32     * Reacts on supported control change commands (e.g. pitch bend wheel,
33     * modulation wheel, aftertouch).
34     *
35     * @param pEngineChannel - engine channel on which this event occured on
36     * @param itControlChangeEvent - controller, value and time stamp of the event
37     */
38     void Engine::ProcessControlChange (
39     LinuxSampler::EngineChannel* pEngineChannel,
40     Pool<Event>::Iterator& itControlChangeEvent
41     ) {
42     dmsg(4,("Engine::ContinuousController cc=%d v=%d\n", itControlChangeEvent->Param.CC.Controller, itControlChangeEvent->Param.CC.Value));
43    
44     EngineChannel* pChannel = dynamic_cast<EngineChannel*>(pEngineChannel);
45     // handle the "control triggered" MIDI rule: a control change
46     // event can trigger a new note on or note off event
47     if (pChannel->pInstrument) {
48    
49     // TODO:
50     }
51    
52     // update controller value in the engine channel's controller table
53     pChannel->ControllerTable[itControlChangeEvent->Param.CC.Controller] = itControlChangeEvent->Param.CC.Value;
54    
55     ProcessHardcodedControllers(pEngineChannel, itControlChangeEvent);
56    
57     // handle FX send controllers
58     ProcessFxSendControllers(pChannel, itControlChangeEvent);
59     }
60    
61     DiskThread* Engine::CreateDiskThread() {
62     return new DiskThread (
63     iMaxDiskStreams,
64     ((pAudioOutputDevice->MaxSamplesPerCycle() << CONFIG_MAX_PITCH) << 1) + 6, //FIXME: assuming stereo
65     &instruments
66     );
67     }
68    
69     void Engine::TriggerNewVoices (
70     LinuxSampler::EngineChannel* pEngineChannel,
71     RTList<Event>::Iterator& itNoteOnEvent,
72     bool HandleKeyGroupConflicts
73     ) {
74     EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);
75    
76     uint8_t chan = pChannel->MidiChannel();
77     int key = itNoteOnEvent->Param.Note.Key;
78     uint8_t vel = itNoteOnEvent->Param.Note.Velocity;
79     int bend = pChannel->Pitch;
80     uint8_t chanaft = pChannel->ControllerTable[128];
81     uint8_t* cc = pChannel->ControllerTable;
82    
83     std::vector< ::sf2::Region*> regs = pChannel->pInstrument->GetRegionsOnKey (
84     key, vel
85     );
86    
87     pChannel->regionsTemp.clear();
88    
89 iliev 2027 for (int i = 0; i < regs.size(); i++) {
90     // TODO: Generators in the PGEN sub-chunk are applied relative to generators in the IGEN sub-chunk in an additive manner. In
91     // other words, PGEN generators increase or decrease the value of an IGEN generator.
92     ::sf2::Instrument* sfInstr = regs[i]->pInstrument;
93 iliev 2012
94 iliev 2027 std::vector< ::sf2::Region*> subRegs = sfInstr->GetRegionsOnKey (
95 iliev 2012 key, vel
96     );
97 iliev 2027 for (int j = 0; j < subRegs.size(); j++) {
98     pChannel->regionsTemp.push_back(subRegs[j]);
99     }
100 iliev 2012 }
101    
102     for (int i = 0; i < pChannel->regionsTemp.size(); i++) {
103     ::sf2::Region* r = pChannel->regionsTemp[i];
104     //std::cout << r->GetSample()->GetName();
105     //std::cout << " loKey: " << r->loKey << " hiKey: " << r->hiKey << " minVel: " << r->minVel << " maxVel: " << r->maxVel << " Vel: " << ((int)vel) << std::endl << std::endl;
106     if (!RegionSuspended(pChannel->regionsTemp[i])) {
107     LaunchVoice(pChannel, itNoteOnEvent, i, false, true, HandleKeyGroupConflicts);
108     }
109     }
110     }
111    
112     void Engine::TriggerReleaseVoices (
113     LinuxSampler::EngineChannel* pEngineChannel,
114     RTList<Event>::Iterator& itNoteOffEvent
115     ) {
116    
117     }
118    
119     Pool<Voice>::Iterator Engine::LaunchVoice (
120     LinuxSampler::EngineChannel* pEngineChannel,
121     Pool<Event>::Iterator& itNoteOnEvent,
122     int iLayer,
123     bool ReleaseTriggerVoice,
124     bool VoiceStealing,
125     bool HandleKeyGroupConflicts
126     ) {
127     EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);
128     int key = itNoteOnEvent->Param.Note.Key;
129 iliev 2027 EngineChannel::MidiKey* pKey = &pChannel->pMIDIKeyInfo[key];
130 iliev 2012
131     Voice::type_t VoiceType = Voice::type_normal;
132    
133     Pool<Voice>::Iterator itNewVoice;
134     ::sf2::Region* pRgn = pChannel->regionsTemp[iLayer];
135    
136     // no need to process if sample is silent
137 iliev 2027 if (!pRgn->GetSample() || !pRgn->GetSample()->GetTotalFrameCount()) return Pool<Voice>::Iterator();
138 iliev 2012
139 iliev 2027 // only mark the first voice of a layered voice (group) to be in a
140     // key group, so the layered voices won't kill each other
141     int iKeyGroup = (iLayer == 0 && !ReleaseTriggerVoice) ? pRgn->exclusiveClass : 0;
142     if (HandleKeyGroupConflicts) pChannel->HandleKeyGroupConflicts(iKeyGroup, itNoteOnEvent);
143    
144 iliev 2012 // allocate a new voice for the key
145     itNewVoice = pKey->pActiveVoices->allocAppend();
146 iliev 2027 int res = InitNewVoice (
147     pChannel, pRgn, itNoteOnEvent, VoiceType, iLayer,
148     iKeyGroup, ReleaseTriggerVoice, VoiceStealing, itNewVoice
149     );
150     if (!res) return itNewVoice;
151 iliev 2012
152     // return if this is a release triggered voice and there is no
153     // releasetrigger dimension (could happen if an instrument
154     // change has occured between note on and off)
155     //if (ReleaseTriggerVoice && VoiceType != Voice::type_release_trigger) return Pool<Voice>::Iterator();
156    
157 iliev 2027 return Pool<Voice>::Iterator(); // no free voice or error
158 iliev 2012 }
159    
160     bool Engine::DiskStreamSupported() {
161     return true;
162     }
163    
164     String Engine::Description() {
165     return "SoundFont Format Engine";
166     }
167    
168     String Engine::Version() {
169 iliev 2027 String s = "$Revision: 1.2 $";
170 iliev 2012 return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
171     }
172    
173     }} // namespace LinuxSampler::sf2

  ViewVC Help
Powered by ViewVC