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

Annotation of /linuxsampler/trunk/src/engines/gig/InstrumentScriptVMFunctions.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: 4574 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 schoenebeck 2600 /*
2 schoenebeck 2879 * Copyright (c) 2014-2016 Christian Schoenebeck
3 schoenebeck 2600 *
4     * http://www.linuxsampler.org
5     *
6     * This file is part of LinuxSampler and released under the same terms.
7     * See README file for details.
8     */
9    
10     #include "InstrumentScriptVMFunctions.h"
11     #include "InstrumentScriptVM.h"
12     #include "EngineChannel.h"
13    
14     namespace LinuxSampler { namespace gig {
15    
16     /////////////////////////////////////////////////////////////////////////
17     // Function:
18     // gig_set_dim_zone(event_id, dimension, zone)
19    
20     InstrumentScriptVMFunction_gig_set_dim_zone::InstrumentScriptVMFunction_gig_set_dim_zone(InstrumentScriptVM* parent)
21     : m_vm(parent)
22     {
23     }
24    
25 schoenebeck 2630 bool InstrumentScriptVMFunction_gig_set_dim_zone::acceptsArgType(int iArg, ExprType_t type) const {
26     return type == INT_EXPR || type == INT_ARR_EXPR;
27     }
28    
29 schoenebeck 2600 VMFnResult* InstrumentScriptVMFunction_gig_set_dim_zone::exec(VMFnArgs* args) {
30 schoenebeck 2630 EngineChannel* pEngineChannel =
31     static_cast<EngineChannel*>(m_vm->m_event->cause.pEngineChannel);
32    
33 schoenebeck 2600 int dim = args->arg(1)->asInt()->evalInt();
34     int zone = args->arg(2)->asInt()->evalInt();
35    
36 schoenebeck 2630 if (args->arg(0)->exprType() == INT_EXPR) {
37 schoenebeck 2879 const ScriptID id = args->arg(0)->asInt()->evalInt();
38     if (!id) {
39     wrnMsg("gig_set_dim_zone(): note ID for argument 1 may not be zero");
40 schoenebeck 2630 return successResult();
41     }
42 schoenebeck 2879 if (!id.isNoteID()) {
43     wrnMsg("gig_set_dim_zone(): argument 1 is not a note ID");
44     return successResult();
45     }
46 schoenebeck 2600
47 schoenebeck 2879 NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() );
48     if (!pNote) {
49     dmsg(2,("gig_set_dim_zone(): no active note with ID %d\n", int(id)));
50 schoenebeck 2630 return successResult();
51     }
52 schoenebeck 2611
53 schoenebeck 2879 int note = pNote->cause.Param.Note.Key;
54 schoenebeck 2611
55 schoenebeck 2630 ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(note);
56     if (!pRegion) {
57     dmsg(2,("gig_set_dim_zone(): no region for key %d\n", note));
58     return successResult();
59     }
60 schoenebeck 2600
61 schoenebeck 2630 int idx = -1, baseBits = 0;
62     for (int i = 0; i < pRegion->Dimensions; ++i) {
63     if (pRegion->pDimensionDefinitions[i].dimension == dim) {
64     idx = i;
65     break;
66     }
67     baseBits += pRegion->pDimensionDefinitions[i].bits;
68 schoenebeck 2600 }
69 schoenebeck 2630 if (idx < 0) {
70     dmsg(2,("gig_set_dim_zone(): no such gig dimension %d\n", dim));
71     return successResult(); // no such dimension found
72     }
73 schoenebeck 2600
74 schoenebeck 2630 int bits = pRegion->pDimensionDefinitions[idx].bits;
75     int mask = 0;
76     for (int i = 0; i < bits; ++i) mask |= (1 << (baseBits + i));
77 schoenebeck 2600
78 schoenebeck 2879 pNote->Format.Gig.DimMask |= mask;
79     pNote->Format.Gig.DimBits |= (zone << baseBits) & mask;
80 schoenebeck 2600
81 schoenebeck 2879 dmsg(3,("gig_set_dim_zone(): success, mask=%d bits=%d\n", pNote->Format.Gig.DimMask, pNote->Format.Gig.DimBits));
82 schoenebeck 2630 } else if (args->arg(0)->exprType() == INT_ARR_EXPR) {
83     VMIntArrayExpr* ids = args->arg(0)->asIntArray();
84     for (int i = 0; i < ids->arraySize(); ++i) {
85 schoenebeck 2879 const ScriptID id = ids->evalIntElement(i);
86     if (!id || !id.isNoteID()) continue;
87 schoenebeck 2611
88 schoenebeck 2879 NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() );
89     if (!pNote) continue;
90 schoenebeck 2630
91 schoenebeck 2879 int note = pNote->cause.Param.Note.Key;
92 schoenebeck 2630
93     ::gig::Region* pRegion = pEngineChannel->pInstrument->GetRegion(note);
94     if (!pRegion) continue;
95    
96     int idx = -1, baseBits = 0;
97     for (int i = 0; i < pRegion->Dimensions; ++i) {
98     if (pRegion->pDimensionDefinitions[i].dimension == dim) {
99     idx = i;
100     break;
101     }
102     baseBits += pRegion->pDimensionDefinitions[i].bits;
103     }
104     if (idx < 0) continue;
105    
106     int bits = pRegion->pDimensionDefinitions[idx].bits;
107     int mask = 0;
108     for (int i = 0; i < bits; ++i) mask |= (1 << (baseBits + i));
109    
110 schoenebeck 2879 pNote->Format.Gig.DimMask |= mask;
111     pNote->Format.Gig.DimBits |= (zone << baseBits) & mask;
112 schoenebeck 2630
113 schoenebeck 2879 dmsg(3,("gig_set_dim_zone(): success, mask=%d bits=%d\n", pNote->Format.Gig.DimMask, pNote->Format.Gig.DimBits));
114 schoenebeck 2630 }
115     }
116    
117 schoenebeck 2600 return successResult();
118     }
119    
120     }} // namespace LinuxSampler::gig

  ViewVC Help
Powered by ViewVC