1 /****************************************************************************
3 * Copyright (C) 2014, Andrew Ward <afward@gmail.com> *
5 * See COPYING for license terms (Ms-PL). *
7 ***************************************************************************/
9 using System.Collections.Generic;
22 internal RingBuffer(int size)
24 _buffer = new float[size];
29 internal void EnsureSize(int size)
31 // because _end == _start signifies no data, and _end is always 1 more than the data we have, we must make the buffer {channels} entries bigger than requested
36 var temp = new float[size];
37 Array.Copy(_buffer, _start, temp, 0, _bufLen - _start);
40 Array.Copy(_buffer, 0, temp, _bufLen - _start, _end);
51 internal int Channels;
53 internal void CopyTo(float[] buffer, int index, int count)
55 if (index < 0 || index + count > buffer.Length) throw new ArgumentOutOfRangeException("index");
60 // this is used to pull data out of the buffer, so we'll update the start position too...
61 var len = (_end - start + _bufLen) % _bufLen;
62 if (count > len) throw new ArgumentOutOfRangeException("count");
64 var cnt = Math.Min(count, _bufLen - start);
65 Buffer.BlockCopy(_buffer, start * sizeof(float), buffer, index * sizeof(float), cnt * sizeof(float));
69 Buffer.BlockCopy(_buffer, 0, buffer, (index + cnt) * sizeof(float), (count - cnt) * sizeof(float));
73 internal void RemoveItems(int count)
75 var cnt = (count + _start) % _bufLen;
78 if (cnt > _end || cnt < _start) throw new ArgumentOutOfRangeException();
83 if (cnt < _start && cnt > _end) throw new ArgumentOutOfRangeException();
98 var temp = _end - _start;
99 if (temp < 0) temp += _bufLen;
104 internal void Write(int channel, int index, int start, int switchPoint, int end, float[] pcm, float[] window)
106 // this is the index of the first sample to merge
107 var idx = (index + start) * Channels + channel + _start;
108 while (idx >= _bufLen)
113 // blech... gotta fix the first packet's pointers
120 // go through and do the overlap
121 for (; idx < _bufLen && start < switchPoint; idx += Channels, ++start)
123 _buffer[idx] += pcm[start] * window[start];
128 for (; start < switchPoint; idx += Channels, ++start)
130 _buffer[idx] += pcm[start] * window[start];
134 // go through and write the rest
135 for (; idx < _bufLen && start < end; idx += Channels, ++start)
137 _buffer[idx] = pcm[start] * window[start];
142 for (; start < end; idx += Channels, ++start)
144 _buffer[idx] = pcm[start] * window[start];
148 // finally, make sure the buffer end is set correctly