File: Envelope.C

package info (click to toggle)
gmod 3.1-11
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 1,352 kB
  • ctags: 809
  • sloc: cpp: 7,772; makefile: 77
file content (104 lines) | stat: -rw-r--r-- 2,256 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// -*-C++-*-
// This file is part of the gmod package
// Copyright (C) 1997 by Andrew J. Robinson

#include <sys/types.h>

#include "defines.h"
#include "Envelope.h"

void
Envelope::load(int numPoints, int sustainPoint, int loopStartPoint,
	       int loopEndPoint, int typeFlags, unsigned short fadeout,
	       int baseVal, unsigned char *data)
{
  int i, prevX, prevY;
  unsigned char *dataPtr = data;

  fadeRate = fadeout;
  baseValue_ = baseVal;

  if (!(typeFlags & 0x01))
    {
      numSegments = 0;
      return;
    }

  sustainOn = typeFlags & 0x02;
  loopOn = typeFlags & 0x04;
  numSegments = numPoints - 1;

  if (envelope != 0)
    delete [] envelope;

  envelope = new EnvelopeSegment[numSegments];
  
  if (sustainOn)
    sustainX = INTEL_SHORT(dataPtr + (sustainPoint * 4));

  if (loopOn)
    {
      loopStartX = INTEL_SHORT(dataPtr + (loopStartPoint * 4));
      loopEndX = INTEL_SHORT(dataPtr + (loopEndPoint * 4));
    }

  prevX = INTEL_SHORT(dataPtr);
  dataPtr += 2;
  prevY = INTEL_SHORT(dataPtr);
  dataPtr += 2;

  for (i = 0; i < numSegments; i++)
    {
      envelope[i].startX = prevX;
      envelope[i].startY = prevY;
      prevX = envelope[i].endX = INTEL_SHORT(dataPtr);
      dataPtr += 2;
      prevY = envelope[i].endY = INTEL_SHORT(dataPtr);
      dataPtr += 2;

      envelope[i].m = double(envelope[i].endY - envelope[i].startY) /
	double(envelope[i].endX - envelope[i].startX);
      envelope[i].b = double(envelope[i].startY) -
	double(envelope[i].m * envelope[i].startX);
    }
}

int
Envelope::getY(int &x, char inSustain, unsigned short *fade) const
{
  int y;

  if (numSegments == 0)
    y = baseValue_;
  else
    {
      if ((sustainOn) && (inSustain == MY_TRUE) && (x > sustainX))
	x = sustainX;
      
      if ((loopOn) && (x >= loopEndX))
	x = loopStartX;
      
      if (x > envelope[numSegments - 1].endX)
	x = envelope[numSegments - 1].endX;

      for (int i = 0; i < numSegments; i++)
	{
	  if ((envelope[i].startX <= x) && (envelope[i].endX >= x))
	    y = envelope[i].m * x + envelope[i].b;
	}

      x++;
    }

  if ((inSustain == MY_FALSE) && fade)
    {
      y = (y * (*fade)) / 65535;
	  
      if (fadeRate <= *fade)
	*fade -= fadeRate;
      else
	*fade = 0;
    }
  
  return (y);
}