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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2879 - (show annotations) (download)
Tue Apr 19 14:07:53 2016 UTC (2 years, 7 months 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 /*
2 * Copyright (c) 2014-2016 Christian Schoenebeck
3 *
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 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 VMFnResult* InstrumentScriptVMFunction_gig_set_dim_zone::exec(VMFnArgs* args) {
30 EngineChannel* pEngineChannel =
31 static_cast<EngineChannel*>(m_vm->m_event->cause.pEngineChannel);
32
33 int dim = args->arg(1)->asInt()->evalInt();
34 int zone = args->arg(2)->asInt()->evalInt();
35
36 if (args->arg(0)->exprType() == INT_EXPR) {
37 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 return successResult();
41 }
42 if (!id.isNoteID()) {
43 wrnMsg("gig_set_dim_zone(): argument 1 is not a note ID");
44 return successResult();
45 }
46
47 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 return successResult();
51 }
52
53 int note = pNote->cause.Param.Note.Key;
54
55 ::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
61 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 }
69 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
74 int bits = pRegion->pDimensionDefinitions[idx].bits;
75 int mask = 0;
76 for (int i = 0; i < bits; ++i) mask |= (1 << (baseBits + i));
77
78 pNote->Format.Gig.DimMask |= mask;
79 pNote->Format.Gig.DimBits |= (zone << baseBits) & mask;
80
81 dmsg(3,("gig_set_dim_zone(): success, mask=%d bits=%d\n", pNote->Format.Gig.DimMask, pNote->Format.Gig.DimBits));
82 } 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 const ScriptID id = ids->evalIntElement(i);
86 if (!id || !id.isNoteID()) continue;
87
88 NoteBase* pNote = pEngineChannel->pEngine->NoteByID( id.noteID() );
89 if (!pNote) continue;
90
91 int note = pNote->cause.Param.Note.Key;
92
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 pNote->Format.Gig.DimMask |= mask;
111 pNote->Format.Gig.DimBits |= (zone << baseBits) & mask;
112
113 dmsg(3,("gig_set_dim_zone(): success, mask=%d bits=%d\n", pNote->Format.Gig.DimMask, pNote->Format.Gig.DimBits));
114 }
115 }
116
117 return successResult();
118 }
119
120 }} // namespace LinuxSampler::gig

  ViewVC Help
Powered by ViewVC