File: RingBuffer.h

package info (click to toggle)
camstream 0.27%2Bdfsg-4
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 12,368 kB
  • ctags: 5,393
  • sloc: cpp: 17,031; sh: 8,154; asm: 455; ansic: 440; makefile: 343
file content (140 lines) | stat: -rw-r--r-- 3,595 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/*  audiodevs: Abstraction layer for audio hardware & samples
    Copyright (C) 2003-2004 Nemosoft Unv.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    For questions, remarks, patches, etc. for this program, the author can be
    reached at camstream@smcc.demon.nl.
*/

#ifndef RINGBUFFER_HPP
#define RINGBUFFER_HPP

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <qlist.h>
#include <qobject.h>
#include <qthread.h>

#include "AudioSample.h"

// Forward declarations
class CRingBufferWriter;
class CRingBufferReader;

class CRingBuffer: public QObject
{
friend class CRingBufferWriter;
friend class CRingBufferReader;
   Q_OBJECT
private:
   QMutex Head; 		///< The head-pointer lock
   QMutex Lists;		///< For manipulating the lists

   QList<CRingBufferWriter> Writers;
   QList<CRingBufferReader> Readers;

   unsigned int BufferSpace, BufferHead, MaxLength;
   void *Buffer;

   /* Statistical data */
   long BytesWritten;	///< Total amount of bytes put in buffer
   int Overflows;	///< Number of times our buffer got full

   /* Called by Writers */
   void AttachWriter(CRingBufferWriter *s);
   void DetachWriter(CRingBufferWriter *s);
   int AddToBuffer(void *data, int len, bool must_fit);
   int SpaceLeft();
   int SpaceUsed();

   /* Called by Readers */
   void AttachReader(CRingBufferReader *r);
   void DetachReader(CRingBufferReader *r);

   /* Called by both Readers and Writers */
   void Flush();

public:
   CRingBuffer(unsigned int buffer_space);
   ~CRingBuffer();

   unsigned int GetBufferLength();

signals:
   void ReaderAttached();
   void ReaderDetached();
   void WriterAttached();
   void WriterDetached();

   void BufferFlushed();
};


class CRingBufferWriter
{
private:
   CRingBuffer *pRing;

   CRingBufferWriter(const CRingBufferWriter &) {}; // copies are impossible

public:
   CRingBufferWriter(CRingBuffer *ring);
   ~CRingBufferWriter();

   int WriteToBuffer(void *, int len, bool must_fit = false) const;
   int SpaceLeft() const;
   int SpaceUsed() const;

   void Flush() const;
};


class CRingBufferReader: public QObject
{
friend class CRingBuffer;
   Q_OBJECT
private:
   CRingBuffer *pRing;
   QMutex Lock;
   QWaitCondition DataReady;
   unsigned int BufferTail, MyBufferLength;
   unsigned int LowWaterMark, HighWaterMark;

   CRingBufferReader(const CRingBufferReader &r) {}; // copies are impossible

public:
   CRingBufferReader(CRingBuffer *ring);
   ~CRingBufferReader();

   int SpaceUsed() const;
   int ReadFromBufferTail(void *, unsigned int len);
   int ReadFromBufferHead(void *, unsigned int len, bool clear = false, unsigned long time = ULONG_MAX);

   virtual bool event(QEvent *e); // overloaded

   void SetLowWaterMark(unsigned int);
   unsigned int GetLowWaterMark() const;
   void SetHighWaterMark(unsigned int);
   unsigned int GetHighWaterMark() const;

signals:
   void DataArrived(int bytes);
   void BufferFlushed();
};

#endif