~ubuntu-branches/ubuntu/karmic/muse/karmic-proposed

« back to all changes in this revision

Viewing changes to synti/stklib/DLineL.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Kobras
  • Date: 2002-04-23 17:28:23 UTC
  • Revision ID: james.westby@ubuntu.com-20020423172823-w8yplzr81a759xa3
Tags: upstream-0.5.2
ImportĀ upstreamĀ versionĀ 0.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*******************************************/
 
2
/*
 
3
   Linearly Interpolating Delay Line
 
4
   Object by Perry R. Cook 1995-96.
 
5
   Added methods by Julius Smith, 2000.
 
6
 
 
7
   This one uses a delay line of maximum
 
8
   length specified on creation, and
 
9
   linearly interpolates fractional
 
10
   length.  It is designed to be more
 
11
   efficient if the delay length is not
 
12
   changed very often.
 
13
*/
 
14
/*******************************************/
 
15
 
 
16
#include "DLineL.h"
 
17
 
 
18
DLineL :: DLineL()
 
19
{
 
20
  // Default max delay length set to 2047.
 
21
  length = 2048;
 
22
  inputs = (MY_FLOAT *) malloc(length * sizeof(MY_FLOAT));
 
23
  this->clear();
 
24
  inPoint = 0;
 
25
  outPoint = length >> 1;
 
26
  currentDelay = outPoint;
 
27
}
 
28
 
 
29
DLineL :: DLineL(long max_length)
 
30
{
 
31
  length = max_length;
 
32
  inputs = (MY_FLOAT *) malloc(length * sizeof(MY_FLOAT));
 
33
  this->clear();
 
34
  inPoint = 0;
 
35
  outPoint = length >> 1;
 
36
  currentDelay = outPoint;
 
37
}
 
38
 
 
39
DLineL :: ~DLineL()
 
40
{
 
41
  free(inputs);
 
42
}
 
43
 
 
44
void DLineL :: clear()
 
45
{
 
46
  long i;
 
47
  for (i=0;i<length;i++) inputs[i] = (MY_FLOAT) 0.0;
 
48
  lastOutput = (MY_FLOAT) 0;
 
49
}
 
50
 
 
51
void DLineL :: setDelay(MY_FLOAT lag)
 
52
{
 
53
  MY_FLOAT outPointer;
 
54
 
 
55
  if (lag > length-1) {
 
56
    // delay is too big,
 
57
    printf("DLineL: Delay length too big.\n");
 
58
    printf("Setting to maximum length of %ld.\n",length-1);
 
59
    // force delay to max_length
 
60
    outPointer = inPoint + 1;
 
61
    currentDelay = length - 1;
 
62
  }
 
63
  else {
 
64
    // read chases write
 
65
    outPointer = inPoint - lag;
 
66
    currentDelay = lag;
 
67
  }
 
68
 
 
69
  while (outPointer<0)
 
70
    // modulo maximum length
 
71
    outPointer += length;
 
72
 
 
73
  // integer part
 
74
  outPoint = (long) outPointer;
 
75
  // fractional part
 
76
  alpha = outPointer - outPoint;
 
77
  omAlpha = (MY_FLOAT) 1.0 - alpha;
 
78
}
 
79
 
 
80
MY_FLOAT DLineL :: delay(void)
 
81
{
 
82
  return currentDelay;
 
83
}
 
84
 
 
85
MY_FLOAT DLineL :: energy(void)
 
86
{
 
87
  int i;
 
88
  register MY_FLOAT e = 0;
 
89
  if (inPoint>=outPoint) {
 
90
    for (i=outPoint;i<inPoint;i++) {
 
91
      register MY_FLOAT t = inputs[i];
 
92
      e += t*t;
 
93
    }
 
94
  } else {
 
95
    for (i=outPoint;i<length;i++) {
 
96
      register MY_FLOAT t = inputs[i];
 
97
      e += t*t;
 
98
    }
 
99
    for (i=0;i<inPoint;i++) {
 
100
      register MY_FLOAT t = inputs[i];
 
101
      e += t*t;
 
102
    }
 
103
  }
 
104
  return e;
 
105
}
 
106
 
 
107
long DLineL :: currentInPoint(void)
 
108
{
 
109
  return inPoint;
 
110
}
 
111
 
 
112
long DLineL :: currentOutPoint(void)
 
113
{
 
114
  return outPoint;
 
115
}
 
116
 
 
117
MY_FLOAT DLineL :: contentsAt(int n)
 
118
{
 
119
  int i = n;
 
120
  if (i<0) i=0;
 
121
  if (i>= length) i = length-1;
 
122
  if (i != n) {
 
123
    fprintf(stderr,
 
124
            "DLineL: contentsAt(%d) overflows length %ld delay line\n",
 
125
            n, length);
 
126
  }
 
127
  return inputs[i];
 
128
}
 
129
 
 
130
MY_FLOAT DLineL :: contentsAtNowMinus(int n)
 
131
{
 
132
  /* "Now" is always where inPoint points which is not yet written. */
 
133
  /* outPoint points to "now - delay".  Thus, valid values for n are 1 to delay. */
 
134
  int i = n;
 
135
  if (i<1) i=1;
 
136
  if (i>length) i = length;
 
137
  if (i != n) {
 
138
    fprintf(stderr,
 
139
            "DLineL: contentsAtNowMinus(%d) overflows length %ld delay line\n"
 
140
            "Clipped\n", n,length);
 
141
  }
 
142
  int ndx = inPoint-i;
 
143
  if (ndx < 0) { /* Check for wraparound */
 
144
    ndx += length;
 
145
    if (ndx < 0 || ndx >= length)
 
146
      fprintf(stderr,"DLineL: contentsAtNowMinus(): can't happen\n");
 
147
  }   
 
148
  return inputs[ndx];
 
149
}
 
150
 
 
151
MY_FLOAT DLineL :: tick(MY_FLOAT sample)
 
152
{
 
153
  inputs[inPoint++] = sample;
 
154
 
 
155
  // Check for end condition
 
156
  if (inPoint == length)
 
157
    inPoint -= length;
 
158
 
 
159
  // First 1/2 of interpolation
 
160
  lastOutput = inputs[outPoint++] * omAlpha;
 
161
  // Check for end condition
 
162
  if (outPoint<length) {
 
163
    // Second 1/2 of interpolation
 
164
    lastOutput += inputs[outPoint] * alpha;
 
165
  }                                          
 
166
  else { // if at end ...
 
167
    // Second 1/2 of interpolation
 
168
    lastOutput += inputs[0] * alpha;
 
169
    outPoint -= length;                             
 
170
  }
 
171
  return lastOutput;
 
172
}