/[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 2879 - (hide annotations) (download)
Tue Apr 19 14:07:53 2016 UTC (8 years ago) by schoenebeck
File size: 8340 byte(s)
* All engines: Active voices are now internally grouped to "Note" objects,
  instead of being directly assigned to a keyboard key. This allows more
  fine graded processing of voices, which is i.e. required for certain
  instrument script features.
* Built-in script function "play_note()": Added support for passing
  special value -1 for "duration-us" argument, which will cause the
  triggered note to be released once the original note was released.
* Bumped version (2.0.0.svn3).

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 persson 2114 * Copyright (C) 2009-2010 Grigor Iliev *
8 iliev 2012 * *
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 persson 2101 // TODO:
50 iliev 2012 }
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 schoenebeck 2559 void Engine::ProcessChannelPressure(LinuxSampler::EngineChannel* pEngineChannel, Pool<Event>::Iterator& itChannelPressureEvent) {
62     // if required: engine global aftertouch handling (apart from the per voice handling)
63     }
64    
65     void Engine::ProcessPolyphonicKeyPressure(LinuxSampler::EngineChannel* pEngineChannel, Pool<Event>::Iterator& itNotePressureEvent) {
66     // if required: engine global aftertouch handling (apart from the per voice handling)
67     }
68    
69 iliev 2012 DiskThread* Engine::CreateDiskThread() {
70     return new DiskThread (
71     iMaxDiskStreams,
72     ((pAudioOutputDevice->MaxSamplesPerCycle() << CONFIG_MAX_PITCH) << 1) + 6, //FIXME: assuming stereo
73     &instruments
74     );
75     }
76    
77     void Engine::TriggerNewVoices (
78     LinuxSampler::EngineChannel* pEngineChannel,
79     RTList<Event>::Iterator& itNoteOnEvent,
80     bool HandleKeyGroupConflicts
81     ) {
82     EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);
83    
84     uint8_t chan = pChannel->MidiChannel();
85     int key = itNoteOnEvent->Param.Note.Key;
86     uint8_t vel = itNoteOnEvent->Param.Note.Velocity;
87     int bend = pChannel->Pitch;
88     uint8_t chanaft = pChannel->ControllerTable[128];
89     uint8_t* cc = pChannel->ControllerTable;
90    
91 schoenebeck 2879 NoteIterator itNote = GetNotePool()->fromID(itNoteOnEvent->Param.Note.ID);
92     if (!itNote) {
93     dmsg(1,("sf2::Engine: No Note object for triggering new voices!\n"));
94     return;
95     }
96    
97 persson 2101 int layer = 0;
98     ::sf2::Query query(*pChannel->pInstrument);
99     query.key = key;
100     query.vel = vel;
101     while (::sf2::Region* region = query.next()) {
102 iliev 2027 // TODO: Generators in the PGEN sub-chunk are applied relative to generators in the IGEN sub-chunk in an additive manner. In
103     // other words, PGEN generators increase or decrease the value of an IGEN generator.
104 persson 2101 ::sf2::Query subQuery(*region->pInstrument);
105     subQuery.key = key;
106     subQuery.vel = vel;
107     while (::sf2::Region* r = subQuery.next()) {
108     //std::cout << r->GetSample()->GetName();
109     //std::cout << " loKey: " << r->loKey << " hiKey: " << r->hiKey << " minVel: " << r->minVel << " maxVel: " << r->maxVel << " Vel: " << ((int)vel) << std::endl << std::endl;
110     if (!RegionSuspended(r)) {
111     itNoteOnEvent->Param.Note.pRegion = r;
112 schoenebeck 2879 VoiceIterator itNewVoice =
113     LaunchVoice(pChannel, itNoteOnEvent, layer, false, true, HandleKeyGroupConflicts);
114     if (itNewVoice)
115     itNewVoice.moveToEndOf(itNote->pActiveVoices);
116 persson 2101 }
117     layer++;
118 iliev 2027 }
119 iliev 2012 }
120     }
121    
122     void Engine::TriggerReleaseVoices (
123     LinuxSampler::EngineChannel* pEngineChannel,
124     RTList<Event>::Iterator& itNoteOffEvent
125     ) {
126 persson 2101
127 iliev 2012 }
128    
129     Pool<Voice>::Iterator Engine::LaunchVoice (
130     LinuxSampler::EngineChannel* pEngineChannel,
131     Pool<Event>::Iterator& itNoteOnEvent,
132     int iLayer,
133     bool ReleaseTriggerVoice,
134     bool VoiceStealing,
135     bool HandleKeyGroupConflicts
136     ) {
137     EngineChannel* pChannel = static_cast<EngineChannel*>(pEngineChannel);
138     int key = itNoteOnEvent->Param.Note.Key;
139 schoenebeck 2879 //EngineChannel::MidiKey* pKey = &pChannel->pMIDIKeyInfo[key];
140 iliev 2012
141     Voice::type_t VoiceType = Voice::type_normal;
142    
143     Pool<Voice>::Iterator itNewVoice;
144 persson 2101 ::sf2::Region* pRgn = static_cast< ::sf2::Region*>(itNoteOnEvent->Param.Note.pRegion);
145 iliev 2012
146     // no need to process if sample is silent
147 iliev 2027 if (!pRgn->GetSample() || !pRgn->GetSample()->GetTotalFrameCount()) return Pool<Voice>::Iterator();
148 iliev 2012
149 persson 2114 int iKeyGroup = pRgn->exclusiveClass;
150 iliev 2027 if (HandleKeyGroupConflicts) pChannel->HandleKeyGroupConflicts(iKeyGroup, itNoteOnEvent);
151    
152 iliev 2012 // allocate a new voice for the key
153 schoenebeck 2879 itNewVoice = GetVoicePool()->allocAppend();
154 iliev 2027 int res = InitNewVoice (
155     pChannel, pRgn, itNoteOnEvent, VoiceType, iLayer,
156     iKeyGroup, ReleaseTriggerVoice, VoiceStealing, itNewVoice
157     );
158     if (!res) return itNewVoice;
159 iliev 2012
160     // return if this is a release triggered voice and there is no
161     // releasetrigger dimension (could happen if an instrument
162     // change has occured between note on and off)
163     //if (ReleaseTriggerVoice && VoiceType != Voice::type_release_trigger) return Pool<Voice>::Iterator();
164    
165 iliev 2027 return Pool<Voice>::Iterator(); // no free voice or error
166 iliev 2012 }
167    
168     bool Engine::DiskStreamSupported() {
169     return true;
170     }
171    
172     String Engine::Description() {
173     return "SoundFont Format Engine";
174     }
175    
176     String Engine::Version() {
177 schoenebeck 2494 String s = "$Revision$";
178 iliev 2012 return s.substr(11, s.size() - 13); // cut dollar signs, spaces and CVS macro keyword
179     }
180    
181     }} // namespace LinuxSampler::sf2

Properties

Name Value
svn:keywords Revision

  ViewVC Help
Powered by ViewVC