CSL 5.2

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

DelayLine.cpp
Go to the documentation of this file.
1 //
2 // DLine.h -- an Interpolating Delay Line
3 // See the copyright notice and acknowledgment of authors in the file COPYRIGHT
4 //
5 // This is a typical circular buffer with one writer and multiple readers (tap instances)
6
7 #include "DelayLine.h"
8
9 using namespace csl;
10
11 // DelayLine implementation
12 DelayLine :: DelayLine(unsigned maxDelayInSamples) : UnitGenerator(), Effect() {
13 // add a little bit of wiggle room to the delay length this is necessary to make setDelayLength work
14 mMaxDelayInSamples = maxDelayInSamples;
15 mTotalDelayInSamples = maxDelayInSamples + CGestalt::maxBufferFrames();
16 mRingBuffer.mBuffer.setSize(CGestalt::numOutChannels(), mTotalDelayInSamples); // Prepare the buffer to be used for storage.
17 mRingBuffer.mBuffer.allocateMonoBuffers(); // Allocate memory for my buffer.
18 }
19
20 unsigned DelayLine::delayLength() {
21 int length = mRingBuffer.mCurrentWriteFrame - mRingBuffer.mTap.mCurrentFrame;
22 if (length < 0)
23 length += mTotalDelayInSamples;
24 return (unsigned)length;
25 }
26
27 // change the delay length and return the new value
28 unsigned DelayLine::setDelayLength(unsigned delayInSamples) {
29
30 if (delayInSamples > mMaxDelayInSamples) {
31 logMsg(kLogError, "Cannot set delay line length: asked for %d in line of length %d", delayInSamples, mMaxDelayInSamples);
32 return delayLength();
33 }
34 mRingBuffer.mTap.seekTo(delayInSamples, kPositionStart); // Cue the read head (tap) to the new position.
35 return delayLength();
36 }
37
38 // change the delay length and return the new value
39 float DelayLine::setDelayTime(float delayInMiliseconds) {
40 unsigned delayInSamples = (unsigned)(delayInMiliseconds * mFrameRate / 1000); // Converting ms to samples.
41
42 if (delayInSamples > mMaxDelayInSamples) { // If larger than the maximum size specified, keep last value and print an error.
43 logMsg(kLogError, "Cannot set delay line length: asked for %d in line of length %d", delayInSamples, mMaxDelayInSamples);
44 return (delayLength() * (float)mFrameRate / 1000); // Converting back to miliseconds.
45 }
46 mRingBuffer.mTap.seekTo(delayInSamples, kPositionStart); // Cue the read head (tap) to the new position.
47 return delayInMiliseconds; // If everything went well, return the requested value.
48 }
49
50 // The next_buffer call writes, then reads
51 void DelayLine::nextBuffer(Buffer& output) throw(Exception) {
52 getInput(output);
53 mRingBuffer.writeBuffer(output);
54 mRingBuffer.nextBuffer(output);
55 return;
56 }
57
58
59 //
60 //
61 //
62 //DLine :: DLine ( FrameStream &input, float max_delay ) : Processor(input),
63 // max_delay_time(max_delay),
64 // delay_time(0.5 * max_delay),
65 // max_delay_in_frames( (unsigned) (_sampleRate * max_delay + CGestalt::block_size() ) ),
66 // interp_type(kTruncate),
67 // start_frame(0),
68 //// end_frame(0),
69 // write_frame(0),
70 // ring_buffer(FrameStream::channels(), max_delay_in_frames)
71 //{
72 //// max_delay_in_frames = _sampleRate * max_delay;
73 // ring_buffer.allocate_mono_buffers();
74 // ring_buffer.zero_buffers();
75 //
76 //}
77 //
78 //DLine :: ~DLine() {
79 // ring_buffer.free_mono_buffers();
80 //}
81 //
82 //bool DLine :: init_delay_time( float dt ) {
83 // if (dt > max_delay_time)
84 // return false;
85 // delay_time = dt;
86 // return set_target_delay_time(dt);
87 //}
88 //
89 //bool DLine :: set_target_delay_time( float tdt ) {
90 // if (tdt > max_delay_time)
91 // return false;
92 // target_delay_time = tdt;
93 // return true;
94 //}
95 //
96 //bool DLine :: set_interp_type( InterpType it ) {
97 // interp_type = it;
98 // return true;
99 //}
100 //
101 //// Do the work
102 //
103 //status DLine :: mono_next_buffer(Buffer & inputBuffer, Buffer & outputBuffer, unsigned inBufNum, unsigned outBufNum) {
104 // unsigned temp_write_frame = write_frame;
105 // sample * rbPtr = ring_buffer._monoBuffers[outBufNum] + temp_write_frame;
106 // sample * outPtr = outputBuffer._monoBuffers[outBufNum];
107 ///*
108 // for (int i=0; i<outputBuffer._numFrames; i++){
109 // // ring_buffer._monoBuffers[outBufNum][temp_write_frame] = outputBuffer._monoBuffers[outBufNum][i];
110 // *rbPtr++ = *outPtr++
111 // if (++temp_write_frame >= ring_buffer._numFrames)
112 // temp_write_frame = 0;
113 // rbPtr = ring_buffer._monoBuffers[outBufNum];
114 // }
115 //*/
116 // sample *tempSamplePtr;
117 // outPtr = outputBuffer._monoBuffers[outBufNum];
118 // float ramp_factor = 0.0001; // ??
119 // rbPtr = ring_buffer._monoBuffers[outBufNum];
120 // for (unsigned i = 0; i < outputBuffer._numFrames; i++) {
121 // delay_time = (1.0 - ramp_factor) * delay_time + ramp_factor * target_delay_time;
122 // float r_index_and_mant = (delay_time * _sampleRate);
123 // unsigned index = (unsigned) floor(r_index_and_mant);
124 // float mantissa = r_index_and_mant - index;
125 // int read_frame = temp_write_frame - index;
126 // while (read_frame < 0)
127 // read_frame += ring_buffer._numFrames;
128 // sample lower_read_value = *(rbPtr + read_frame);
129 // tempSamplePtr = ((unsigned)(rbPtr + read_frame + 1)) % ring_buffer._numFrames;
130 // sample upper_read_value = *tempSamplePtr;
131 // if ( ++temp_write_frame >= ring_buffer._numFrames)
132 // temp_write_frame -= ring_buffer._numFrames;
133 // *outPtr++ = ((1.0 - mantissa) * lower_read_value) + (mantissa * upper_read_value);
134 // }
135 // write_frame = temp_write_frame;
136 //}
137 //
138 //// Call inherited version
139 //
140 //status DLine :: next_buffer(Buffer & inputBuffer, Buffer & outputBuffer){
141 // Processor :: pull_input( inputBuffer, outputBuffer );
142 // FrameStream :: next_buffer( inputBuffer, outputBuffer );
143 //// update_write_frame(outputBuffer._numFrames);
144 // write_frame += outputBuffer._numFrames;
145 // write_frame %= ring_buffer._numFrames;
146 //
147 //}
148 //
149 //
150 //
151 //