URY playd
C++ minimalist audio player
ringbuffer.cpp
Go to the documentation of this file.
1 // This file is part of playd.
2 // playd is licensed under the MIT licence: see LICENSE.txt.
3 
9 #include <cassert>
10 
11 extern "C" {
12 #include "../contrib/pa_ringbuffer/pa_ringbuffer.h"
13 }
14 
15 #include "../errors.hpp"
16 #include "../messages.h"
17 #include "ringbuffer.hpp"
18 
19 RingBuffer::RingBuffer(int power, int size)
20 {
21  if (power <= 0) throw InternalError("ringbuffer power must be positive");
22  if (size <= 0) throw InternalError("ringbuffer element size must be positive");
23 
24  this->rb = new PaUtilRingBuffer;
25  this->buffer = new char[(1 << power) * size];
26 
27  if (PaUtil_InitializeRingBuffer(
28  this->rb, size, static_cast<ring_buffer_size_t>(1 << power),
29  this->buffer) != 0) {
31  }
32 
33  assert(this->rb != nullptr);
34  assert(this->buffer != nullptr);
35 }
36 
38 {
39  assert(this->rb != nullptr);
40  delete this->rb;
41 
42  assert(this->buffer != nullptr);
43  delete[] this->buffer;
44 }
45 
47 {
48  return CountCast(PaUtil_GetRingBufferWriteAvailable(this->rb));
49 }
50 
52 {
53  return CountCast(PaUtil_GetRingBufferReadAvailable(this->rb));
54 }
55 
56 unsigned long RingBuffer::Write(const char *start, unsigned long count)
57 {
58  if (count == 0) throw InternalError("tried to store 0 items in ringbuffer");
59  if (WriteCapacity() < count) throw InternalError("ringbuffer overflow");
60 
61  return CountCast(PaUtil_WriteRingBuffer(
62  this->rb, start, static_cast<ring_buffer_size_t>(count)));
63 }
64 
65 unsigned long RingBuffer::Read(char *start, unsigned long count)
66 {
67  if (count == 0) throw InternalError("tried to read 0 items from ringbuffer");
68  if (ReadCapacity() < count) throw InternalError("ringbuffer underflow");
69 
70  return CountCast(PaUtil_ReadRingBuffer(
71  this->rb, start, static_cast<ring_buffer_size_t>(count)));
72 }
73 
75 {
76  PaUtil_FlushRingBuffer(this->rb);
77  assert(this->ReadCapacity() == 0);
78 }
79 
80 /* static */ unsigned long RingBuffer::CountCast(ring_buffer_size_t count)
81 {
82  return static_cast<unsigned long>(count);
83 }
RingBuffer(int power, int size)
Constructs a RingBuffer.
Definition: ringbuffer.cpp:19
char * buffer
The array used by the ringbuffer.
Definition: ringbuffer.hpp:111
~RingBuffer()
Destructs a PaRingBuffer.
Definition: ringbuffer.cpp:37
PaUtilRingBuffer * rb
The internal PortAudio ringbuffer.
Definition: ringbuffer.hpp:112
unsigned long Read(char *start, unsigned long count)
Reads samples from the ring buffer into an array.
Definition: ringbuffer.cpp:65
size_t WriteCapacity() const
The current write capacity.
Definition: ringbuffer.cpp:46
The RingBuffer class template.
const std::string MSG_OUTPUT_RINGINIT
Message shown when there is an error initialising the ring buffer.
Definition: messages.h:88
An Error signifying that playd has hit an internal snag.
Definition: errors.hpp:60
size_t ReadCapacity() const
The current read capacity.
Definition: ringbuffer.cpp:51
unsigned long Write(const char *start, unsigned long count)
Writes samples from an array into the ring buffer.
Definition: ringbuffer.cpp:56
void Flush()
Empties the ring buffer.
Definition: ringbuffer.cpp:74
static unsigned long CountCast(ring_buffer_size_t count)
Converts a ring buffer size into an external size.
Definition: ringbuffer.cpp:80