comparison base/RingBuffer.h @ 928:6a94bb528e9d warnfix_no_size_t

Remove size_t's, fix compiler warnings
author Chris Cannam
date Tue, 17 Jun 2014 13:52:07 +0100
parents 1d439494604c
children 48e9f538e6e9
comparison
equal deleted inserted replaced
917:49618f39ff09 928:6a94bb528e9d
53 * samples, as one element is unavailable for administrative 53 * samples, as one element is unavailable for administrative
54 * reasons. Since the ring buffer performs best if its size is a 54 * reasons. Since the ring buffer performs best if its size is a
55 * power of two, this means n should ideally be some power of two 55 * power of two, this means n should ideally be some power of two
56 * minus one. 56 * minus one.
57 */ 57 */
58 RingBuffer(size_t n); 58 RingBuffer(int n);
59 59
60 virtual ~RingBuffer(); 60 virtual ~RingBuffer();
61 61
62 /** 62 /**
63 * Return the total capacity of the ring buffer in samples. 63 * Return the total capacity of the ring buffer in samples.
64 * (This is the argument n passed to the constructor.) 64 * (This is the argument n passed to the constructor.)
65 */ 65 */
66 size_t getSize() const; 66 int getSize() const;
67 67
68 /** 68 /**
69 * Return a new ring buffer (allocated with "new" -- caller must 69 * Return a new ring buffer (allocated with "new" -- caller must
70 * delete when no longer needed) of the given size, containing the 70 * delete when no longer needed) of the given size, containing the
71 * same data as this one as perceived by reader 0 of this buffer. 71 * same data as this one as perceived by reader 0 of this buffer.
72 * If another thread reads from or writes to this buffer during 72 * If another thread reads from or writes to this buffer during
73 * the call, the contents of the new buffer may be incomplete or 73 * the call, the contents of the new buffer may be incomplete or
74 * inconsistent. If this buffer's data will not fit in the new 74 * inconsistent. If this buffer's data will not fit in the new
75 * size, the contents are undefined. 75 * size, the contents are undefined.
76 */ 76 */
77 RingBuffer<T, N> *resized(size_t newSize) const; 77 RingBuffer<T, N> *resized(int newSize) const;
78 78
79 /** 79 /**
80 * Lock the ring buffer into physical memory. Returns true 80 * Lock the ring buffer into physical memory. Returns true
81 * for success. 81 * for success.
82 */ 82 */
90 90
91 /** 91 /**
92 * Return the amount of data available for reading by reader R, in 92 * Return the amount of data available for reading by reader R, in
93 * samples. 93 * samples.
94 */ 94 */
95 size_t getReadSpace(int R = 0) const; 95 int getReadSpace(int R = 0) const;
96 96
97 /** 97 /**
98 * Return the amount of space available for writing, in samples. 98 * Return the amount of space available for writing, in samples.
99 */ 99 */
100 size_t getWriteSpace() const; 100 int getWriteSpace() const;
101 101
102 /** 102 /**
103 * Read n samples from the buffer, for reader R. If fewer than n 103 * Read n samples from the buffer, for reader R. If fewer than n
104 * are available, the remainder will be zeroed out. Returns the 104 * are available, the remainder will be zeroed out. Returns the
105 * number of samples actually read. 105 * number of samples actually read.
106 */ 106 */
107 size_t read(T *destination, size_t n, int R = 0); 107 int read(T *destination, int n, int R = 0);
108 108
109 /** 109 /**
110 * Read n samples from the buffer, for reader R, adding them to 110 * Read n samples from the buffer, for reader R, adding them to
111 * the destination. If fewer than n are available, the remainder 111 * the destination. If fewer than n are available, the remainder
112 * will be left alone. Returns the number of samples actually 112 * will be left alone. Returns the number of samples actually
113 * read. 113 * read.
114 */ 114 */
115 size_t readAdding(T *destination, size_t n, int R = 0); 115 int readAdding(T *destination, int n, int R = 0);
116 116
117 /** 117 /**
118 * Read one sample from the buffer, for reader R. If no sample is 118 * Read one sample from the buffer, for reader R. If no sample is
119 * available, this will silently return zero. Calling this 119 * available, this will silently return zero. Calling this
120 * repeatedly is obviously slower than calling read once, but it 120 * repeatedly is obviously slower than calling read once, but it
128 * without advancing the read pointer -- i.e. a subsequent read() 128 * without advancing the read pointer -- i.e. a subsequent read()
129 * or skip() will be necessary to empty the buffer. If fewer than 129 * or skip() will be necessary to empty the buffer. If fewer than
130 * n are available, the remainder will be zeroed out. Returns the 130 * n are available, the remainder will be zeroed out. Returns the
131 * number of samples actually read. 131 * number of samples actually read.
132 */ 132 */
133 size_t peek(T *destination, size_t n, int R = 0) const; 133 int peek(T *destination, int n, int R = 0) const;
134 134
135 /** 135 /**
136 * Read one sample from the buffer, if available, without 136 * Read one sample from the buffer, if available, without
137 * advancing the read pointer -- i.e. a subsequent read() or 137 * advancing the read pointer -- i.e. a subsequent read() or
138 * skip() will be necessary to empty the buffer. Returns zero if 138 * skip() will be necessary to empty the buffer. Returns zero if
144 * Pretend to read n samples from the buffer, for reader R, 144 * Pretend to read n samples from the buffer, for reader R,
145 * without actually returning them (i.e. discard the next n 145 * without actually returning them (i.e. discard the next n
146 * samples). Returns the number of samples actually available for 146 * samples). Returns the number of samples actually available for
147 * discarding. 147 * discarding.
148 */ 148 */
149 size_t skip(size_t n, int R = 0); 149 int skip(int n, int R = 0);
150 150
151 /** 151 /**
152 * Write n samples to the buffer. If insufficient space is 152 * Write n samples to the buffer. If insufficient space is
153 * available, not all samples may actually be written. Returns 153 * available, not all samples may actually be written. Returns
154 * the number of samples actually written. 154 * the number of samples actually written.
155 */ 155 */
156 size_t write(const T *source, size_t n); 156 int write(const T *source, int n);
157 157
158 /** 158 /**
159 * Write n zero-value samples to the buffer. If insufficient 159 * Write n zero-value samples to the buffer. If insufficient
160 * space is available, not all zeros may actually be written. 160 * space is available, not all zeros may actually be written.
161 * Returns the number of zeroes actually written. 161 * Returns the number of zeroes actually written.
162 */ 162 */
163 size_t zero(size_t n); 163 int zero(int n);
164 164
165 protected: 165 protected:
166 T *m_buffer; 166 T *m_buffer;
167 bool m_mlocked; 167 bool m_mlocked;
168 size_t m_writer; 168 int m_writer;
169 size_t *m_readers; 169 int *m_readers;
170 size_t m_size; 170 int m_size;
171 size_t m_spare; 171 int m_spare;
172 172
173 private: 173 private:
174 RingBuffer(const RingBuffer &); // not provided 174 RingBuffer(const RingBuffer &); // not provided
175 RingBuffer &operator=(const RingBuffer &); // not provided 175 RingBuffer &operator=(const RingBuffer &); // not provided
176 }; 176 };
177 177
178 template <typename T, int N> 178 template <typename T, int N>
179 RingBuffer<T, N>::RingBuffer(size_t n) : 179 RingBuffer<T, N>::RingBuffer(int n) :
180 m_buffer(new T[n + 1]), 180 m_buffer(new T[n + 1]),
181 m_mlocked(false), 181 m_mlocked(false),
182 m_writer(0), 182 m_writer(0),
183 m_readers(new size_t[N]), 183 m_readers(new int[N]),
184 m_size(n + 1) 184 m_size(n + 1)
185 { 185 {
186 #ifdef DEBUG_RINGBUFFER 186 #ifdef DEBUG_RINGBUFFER
187 std::cerr << "RingBuffer<T," << N << ">[" << this << "]::RingBuffer(" << n << ")" << std::endl; 187 std::cerr << "RingBuffer<T," << N << ">[" << this << "]::RingBuffer(" << n << ")" << std::endl;
188 #endif 188 #endif
214 } 214 }
215 delete[] m_buffer; 215 delete[] m_buffer;
216 } 216 }
217 217
218 template <typename T, int N> 218 template <typename T, int N>
219 size_t 219 int
220 RingBuffer<T, N>::getSize() const 220 RingBuffer<T, N>::getSize() const
221 { 221 {
222 #ifdef DEBUG_RINGBUFFER 222 #ifdef DEBUG_RINGBUFFER
223 std::cerr << "RingBuffer<T," << N << ">[" << this << "]::getSize(): " << m_size-1 << std::endl; 223 std::cerr << "RingBuffer<T," << N << ">[" << this << "]::getSize(): " << m_size-1 << std::endl;
224 #endif 224 #endif
226 return m_size - 1; 226 return m_size - 1;
227 } 227 }
228 228
229 template <typename T, int N> 229 template <typename T, int N>
230 RingBuffer<T, N> * 230 RingBuffer<T, N> *
231 RingBuffer<T, N>::resized(size_t newSize) const 231 RingBuffer<T, N>::resized(int newSize) const
232 { 232 {
233 #ifdef DEBUG_RINGBUFFER 233 #ifdef DEBUG_RINGBUFFER
234 std::cerr << "RingBuffer<T," << N << ">[" << this << "]::resized(" << newSize << ")" << std::endl; 234 std::cerr << "RingBuffer<T," << N << ">[" << this << "]::resized(" << newSize << ")" << std::endl;
235 #endif 235 #endif
236 236
268 m_writer = 0; 268 m_writer = 0;
269 for (int i = 0; i < N; ++i) m_readers[i] = 0; 269 for (int i = 0; i < N; ++i) m_readers[i] = 0;
270 } 270 }
271 271
272 template <typename T, int N> 272 template <typename T, int N>
273 size_t 273 int
274 RingBuffer<T, N>::getReadSpace(int R) const 274 RingBuffer<T, N>::getReadSpace(int R) const
275 { 275 {
276 size_t writer = m_writer; 276 int writer = m_writer;
277 size_t reader = m_readers[R]; 277 int reader = m_readers[R];
278 size_t space = 0; 278 int space = 0;
279 279
280 if (writer > reader) space = writer - reader; 280 if (writer > reader) space = writer - reader;
281 else space = ((writer + m_size) - reader) % m_size; 281 else space = ((writer + m_size) - reader) % m_size;
282 282
283 #ifdef DEBUG_RINGBUFFER 283 #ifdef DEBUG_RINGBUFFER
286 286
287 return space; 287 return space;
288 } 288 }
289 289
290 template <typename T, int N> 290 template <typename T, int N>
291 size_t 291 int
292 RingBuffer<T, N>::getWriteSpace() const 292 RingBuffer<T, N>::getWriteSpace() const
293 { 293 {
294 size_t space = 0; 294 int space = 0;
295 for (int i = 0; i < N; ++i) { 295 for (int i = 0; i < N; ++i) {
296 size_t here = (m_readers[i] + m_size - m_writer - 1) % m_size; 296 int here = (m_readers[i] + m_size - m_writer - 1) % m_size;
297 if (i == 0 || here < space) space = here; 297 if (i == 0 || here < space) space = here;
298 } 298 }
299 299
300 #ifdef DEBUG_RINGBUFFER 300 #ifdef DEBUG_RINGBUFFER
301 size_t rs(getReadSpace()), rp(m_readers[0]); 301 int rs(getReadSpace()), rp(m_readers[0]);
302 302
303 std::cerr << "RingBuffer: write space " << space << ", read space " 303 std::cerr << "RingBuffer: write space " << space << ", read space "
304 << rs << ", total " << (space + rs) << ", m_size " << m_size << std::endl; 304 << rs << ", total " << (space + rs) << ", m_size " << m_size << std::endl;
305 std::cerr << "RingBuffer: reader " << rp << ", writer " << m_writer << std::endl; 305 std::cerr << "RingBuffer: reader " << rp << ", writer " << m_writer << std::endl;
306 #endif 306 #endif
311 311
312 return space; 312 return space;
313 } 313 }
314 314
315 template <typename T, int N> 315 template <typename T, int N>
316 size_t 316 int
317 RingBuffer<T, N>::read(T *destination, size_t n, int R) 317 RingBuffer<T, N>::read(T *destination, int n, int R)
318 { 318 {
319 #ifdef DEBUG_RINGBUFFER 319 #ifdef DEBUG_RINGBUFFER
320 std::cerr << "RingBuffer<T," << N << ">[" << this << "]::read(dest, " << n << ", " << R << ")" << std::endl; 320 std::cerr << "RingBuffer<T," << N << ">[" << this << "]::read(dest, " << n << ", " << R << ")" << std::endl;
321 #endif 321 #endif
322 322
323 size_t available = getReadSpace(R); 323 int available = getReadSpace(R);
324 if (n > available) { 324 if (n > available) {
325 #ifdef DEBUG_RINGBUFFER 325 #ifdef DEBUG_RINGBUFFER
326 std::cerr << "WARNING: Only " << available << " samples available" 326 std::cerr << "WARNING: Only " << available << " samples available"
327 << std::endl; 327 << std::endl;
328 #endif 328 #endif
329 memset(destination + available, 0, (n - available) * sizeof(T)); 329 memset(destination + available, 0, (n - available) * sizeof(T));
330 n = available; 330 n = available;
331 } 331 }
332 if (n == 0) return n; 332 if (n == 0) return n;
333 333
334 size_t here = m_size - m_readers[R]; 334 int here = m_size - m_readers[R];
335 if (here >= n) { 335 if (here >= n) {
336 memcpy(destination, m_buffer + m_readers[R], n * sizeof(T)); 336 memcpy(destination, m_buffer + m_readers[R], n * sizeof(T));
337 } else { 337 } else {
338 memcpy(destination, m_buffer + m_readers[R], here * sizeof(T)); 338 memcpy(destination, m_buffer + m_readers[R], here * sizeof(T));
339 memcpy(destination + here, m_buffer, (n - here) * sizeof(T)); 339 memcpy(destination + here, m_buffer, (n - here) * sizeof(T));
348 348
349 return n; 349 return n;
350 } 350 }
351 351
352 template <typename T, int N> 352 template <typename T, int N>
353 size_t 353 int
354 RingBuffer<T, N>::readAdding(T *destination, size_t n, int R) 354 RingBuffer<T, N>::readAdding(T *destination, int n, int R)
355 { 355 {
356 #ifdef DEBUG_RINGBUFFER 356 #ifdef DEBUG_RINGBUFFER
357 std::cerr << "RingBuffer<T," << N << ">[" << this << "]::readAdding(dest, " << n << ", " << R << ")" << std::endl; 357 std::cerr << "RingBuffer<T," << N << ">[" << this << "]::readAdding(dest, " << n << ", " << R << ")" << std::endl;
358 #endif 358 #endif
359 359
360 size_t available = getReadSpace(R); 360 int available = getReadSpace(R);
361 if (n > available) { 361 if (n > available) {
362 #ifdef DEBUG_RINGBUFFER 362 #ifdef DEBUG_RINGBUFFER
363 std::cerr << "WARNING: Only " << available << " samples available" 363 std::cerr << "WARNING: Only " << available << " samples available"
364 << std::endl; 364 << std::endl;
365 #endif 365 #endif
366 n = available; 366 n = available;
367 } 367 }
368 if (n == 0) return n; 368 if (n == 0) return n;
369 369
370 size_t here = m_size - m_readers[R]; 370 int here = m_size - m_readers[R];
371 371
372 if (here >= n) { 372 if (here >= n) {
373 for (size_t i = 0; i < n; ++i) { 373 for (int i = 0; i < n; ++i) {
374 destination[i] += (m_buffer + m_readers[R])[i]; 374 destination[i] += (m_buffer + m_readers[R])[i];
375 } 375 }
376 } else { 376 } else {
377 for (size_t i = 0; i < here; ++i) { 377 for (int i = 0; i < here; ++i) {
378 destination[i] += (m_buffer + m_readers[R])[i]; 378 destination[i] += (m_buffer + m_readers[R])[i];
379 } 379 }
380 for (size_t i = 0; i < (n - here); ++i) { 380 for (int i = 0; i < (n - here); ++i) {
381 destination[i + here] += m_buffer[i]; 381 destination[i + here] += m_buffer[i];
382 } 382 }
383 } 383 }
384 384
385 MBARRIER(); 385 MBARRIER();
409 if (++m_readers[R] == m_size) m_readers[R] = 0; 409 if (++m_readers[R] == m_size) m_readers[R] = 0;
410 return value; 410 return value;
411 } 411 }
412 412
413 template <typename T, int N> 413 template <typename T, int N>
414 size_t 414 int
415 RingBuffer<T, N>::peek(T *destination, size_t n, int R) const 415 RingBuffer<T, N>::peek(T *destination, int n, int R) const
416 { 416 {
417 #ifdef DEBUG_RINGBUFFER 417 #ifdef DEBUG_RINGBUFFER
418 std::cerr << "RingBuffer<T," << N << ">[" << this << "]::peek(dest, " << n << ", " << R << ")" << std::endl; 418 std::cerr << "RingBuffer<T," << N << ">[" << this << "]::peek(dest, " << n << ", " << R << ")" << std::endl;
419 #endif 419 #endif
420 420
421 size_t available = getReadSpace(R); 421 int available = getReadSpace(R);
422 if (n > available) { 422 if (n > available) {
423 #ifdef DEBUG_RINGBUFFER 423 #ifdef DEBUG_RINGBUFFER
424 std::cerr << "WARNING: Only " << available << " samples available" 424 std::cerr << "WARNING: Only " << available << " samples available"
425 << std::endl; 425 << std::endl;
426 #endif 426 #endif
427 memset(destination + available, 0, (n - available) * sizeof(T)); 427 memset(destination + available, 0, (n - available) * sizeof(T));
428 n = available; 428 n = available;
429 } 429 }
430 if (n == 0) return n; 430 if (n == 0) return n;
431 431
432 size_t here = m_size - m_readers[R]; 432 int here = m_size - m_readers[R];
433 if (here >= n) { 433 if (here >= n) {
434 memcpy(destination, m_buffer + m_readers[R], n * sizeof(T)); 434 memcpy(destination, m_buffer + m_readers[R], n * sizeof(T));
435 } else { 435 } else {
436 memcpy(destination, m_buffer + m_readers[R], here * sizeof(T)); 436 memcpy(destination, m_buffer + m_readers[R], here * sizeof(T));
437 memcpy(destination + here, m_buffer, (n - here) * sizeof(T)); 437 memcpy(destination + here, m_buffer, (n - here) * sizeof(T));
464 T value = m_buffer[m_readers[R]]; 464 T value = m_buffer[m_readers[R]];
465 return value; 465 return value;
466 } 466 }
467 467
468 template <typename T, int N> 468 template <typename T, int N>
469 size_t 469 int
470 RingBuffer<T, N>::skip(size_t n, int R) 470 RingBuffer<T, N>::skip(int n, int R)
471 { 471 {
472 #ifdef DEBUG_RINGBUFFER 472 #ifdef DEBUG_RINGBUFFER
473 std::cerr << "RingBuffer<T," << N << ">[" << this << "]::skip(" << n << ", " << R << ")" << std::endl; 473 std::cerr << "RingBuffer<T," << N << ">[" << this << "]::skip(" << n << ", " << R << ")" << std::endl;
474 #endif 474 #endif
475 475
476 size_t available = getReadSpace(R); 476 int available = getReadSpace(R);
477 if (n > available) { 477 if (n > available) {
478 #ifdef DEBUG_RINGBUFFER 478 #ifdef DEBUG_RINGBUFFER
479 std::cerr << "WARNING: Only " << available << " samples available" 479 std::cerr << "WARNING: Only " << available << " samples available"
480 << std::endl; 480 << std::endl;
481 #endif 481 #endif
485 m_readers[R] = (m_readers[R] + n) % m_size; 485 m_readers[R] = (m_readers[R] + n) % m_size;
486 return n; 486 return n;
487 } 487 }
488 488
489 template <typename T, int N> 489 template <typename T, int N>
490 size_t 490 int
491 RingBuffer<T, N>::write(const T *source, size_t n) 491 RingBuffer<T, N>::write(const T *source, int n)
492 { 492 {
493 #ifdef DEBUG_RINGBUFFER 493 #ifdef DEBUG_RINGBUFFER
494 std::cerr << "RingBuffer<T," << N << ">[" << this << "]::write(" << n << ")" << std::endl; 494 std::cerr << "RingBuffer<T," << N << ">[" << this << "]::write(" << n << ")" << std::endl;
495 #endif 495 #endif
496 496
497 size_t available = getWriteSpace(); 497 int available = getWriteSpace();
498 if (n > available) { 498 if (n > available) {
499 #ifdef DEBUG_RINGBUFFER 499 #ifdef DEBUG_RINGBUFFER
500 std::cerr << "WARNING: Only room for " << available << " samples" 500 std::cerr << "WARNING: Only room for " << available << " samples"
501 << std::endl; 501 << std::endl;
502 #endif 502 #endif
503 n = available; 503 n = available;
504 } 504 }
505 if (n == 0) return n; 505 if (n == 0) return n;
506 506
507 size_t here = m_size - m_writer; 507 int here = m_size - m_writer;
508 if (here >= n) { 508 if (here >= n) {
509 memcpy(m_buffer + m_writer, source, n * sizeof(T)); 509 memcpy(m_buffer + m_writer, source, n * sizeof(T));
510 } else { 510 } else {
511 memcpy(m_buffer + m_writer, source, here * sizeof(T)); 511 memcpy(m_buffer + m_writer, source, here * sizeof(T));
512 memcpy(m_buffer, source + here, (n - here) * sizeof(T)); 512 memcpy(m_buffer, source + here, (n - here) * sizeof(T));
521 521
522 return n; 522 return n;
523 } 523 }
524 524
525 template <typename T, int N> 525 template <typename T, int N>
526 size_t 526 int
527 RingBuffer<T, N>::zero(size_t n) 527 RingBuffer<T, N>::zero(int n)
528 { 528 {
529 #ifdef DEBUG_RINGBUFFER 529 #ifdef DEBUG_RINGBUFFER
530 std::cerr << "RingBuffer<T," << N << ">[" << this << "]::zero(" << n << ")" << std::endl; 530 std::cerr << "RingBuffer<T," << N << ">[" << this << "]::zero(" << n << ")" << std::endl;
531 #endif 531 #endif
532 532
533 size_t available = getWriteSpace(); 533 int available = getWriteSpace();
534 if (n > available) { 534 if (n > available) {
535 #ifdef DEBUG_RINGBUFFER 535 #ifdef DEBUG_RINGBUFFER
536 std::cerr << "WARNING: Only room for " << available << " samples" 536 std::cerr << "WARNING: Only room for " << available << " samples"
537 << std::endl; 537 << std::endl;
538 #endif 538 #endif
539 n = available; 539 n = available;
540 } 540 }
541 if (n == 0) return n; 541 if (n == 0) return n;
542 542
543 size_t here = m_size - m_writer; 543 int here = m_size - m_writer;
544 if (here >= n) { 544 if (here >= n) {
545 memset(m_buffer + m_writer, 0, n * sizeof(T)); 545 memset(m_buffer + m_writer, 0, n * sizeof(T));
546 } else { 546 } else {
547 memset(m_buffer + m_writer, 0, here * sizeof(T)); 547 memset(m_buffer + m_writer, 0, here * sizeof(T));
548 memset(m_buffer, 0, (n - here) * sizeof(T)); 548 memset(m_buffer, 0, (n - here) * sizeof(T));