SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
audiofifo.cpp
Go to the documentation of this file.
1 // Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
3 // written by Christian Daniel //
4 // //
5 // This program is free software; you can redistribute it and/or modify //
6 // it under the terms of the GNU General Public License as published by //
7 // the Free Software Foundation as version 3 of the License, or //
8 // (at your option) any later version. //
9 // //
10 // This program is distributed in the hope that it will be useful, //
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of //
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
13 // GNU General Public License V3 for more details. //
14 // //
15 // You should have received a copy of the GNU General Public License //
16 // along with this program. If not, see <http://www.gnu.org/licenses/>. //
18 
19 #include <string.h>
20 #include <QTime>
21 #include "dsp/dsptypes.h"
22 #include "audio/audiofifo.h"
23 #include "audio/audionetsink.h"
24 
25 #define MIN(x, y) ((x) < (y) ? (x) : (y))
26 
28  m_fifo(0),
29  m_sampleSize(sizeof(AudioSample))
30 {
31  m_size = 0;
32  m_fill = 0;
33  m_head = 0;
34  m_tail = 0;
35 }
36 
38  m_fifo(0),
39  m_sampleSize(sizeof(AudioSample))
40 {
41  QMutexLocker mutexLocker(&m_mutex);
42 
43  create(numSamples);
44 }
45 
47 {
48  QMutexLocker mutexLocker(&m_mutex);
49 
50  if (m_fifo != 0)
51  {
52  delete[] m_fifo;
53  m_fifo = 0;
54  }
55 
56  m_size = 0;
57 }
58 
59 bool AudioFifo::setSize(uint32_t numSamples)
60 {
61  QMutexLocker mutexLocker(&m_mutex);
62 
63  return create(numSamples);
64 }
65 
66 uint AudioFifo::write(const quint8* data, uint32_t numSamples)
67 {
68  uint32_t total;
69  uint32_t remaining;
70  uint32_t copyLen;
71 
72  if (m_fifo == 0) {
73  return 0;
74  }
75 
76  m_mutex.lock();
77 
78  total = MIN(numSamples, m_size - m_fill);
79  remaining = total;
80 
81  while (remaining != 0)
82  {
83  if (isFull())
84  {
85  m_mutex.unlock();
86  return total - remaining; // written so far
87  }
88 
89  copyLen = MIN(remaining, m_size - m_fill);
90  copyLen = MIN(copyLen, m_size - m_tail);
91  memcpy(m_fifo + (m_tail * m_sampleSize), data, copyLen * m_sampleSize);
92  m_tail += copyLen;
93  m_tail %= m_size;
94  m_fill += copyLen;
95  data += copyLen * m_sampleSize;
96  remaining -= copyLen;
97  }
98 
99  m_mutex.unlock();
100  return total;
101 }
102 
103 uint AudioFifo::read(quint8* data, uint32_t numSamples)
104 {
105  uint32_t total;
106  uint32_t remaining;
107  uint32_t copyLen;
108 
109  if (m_fifo == 0) {
110  return 0;
111  }
112 
113  m_mutex.lock();
114 
115  total = MIN(numSamples, m_fill);
116  remaining = total;
117 
118  while (remaining != 0)
119  {
120  if (isEmpty())
121  {
122  m_mutex.unlock();
123  return total - remaining; // read so far
124  }
125 
126  copyLen = MIN(remaining, m_fill);
127  copyLen = MIN(copyLen, m_size - m_head);
128  memcpy(data, m_fifo + (m_head * m_sampleSize), copyLen * m_sampleSize);
129 
130  m_head += copyLen;
131  m_head %= m_size;
132  m_fill -= copyLen;
133  data += copyLen * m_sampleSize;
134  remaining -= copyLen;
135  }
136 
137  m_mutex.unlock();
138  return total;
139 }
140 
141 uint AudioFifo::drain(uint32_t numSamples)
142 {
143  QMutexLocker mutexLocker(&m_mutex);
144 
145  if(numSamples > m_fill)
146  {
147  numSamples = m_fill;
148  }
149 
150  m_head = (m_head + numSamples) % m_size;
151  m_fill -= numSamples;
152 
153  return numSamples;
154 }
155 
157 {
158  QMutexLocker mutexLocker(&m_mutex);
159 
160  m_fill = 0;
161  m_head = 0;
162  m_tail = 0;
163 }
164 
165 bool AudioFifo::create(uint32_t numSamples)
166 {
167  if(m_fifo != 0)
168  {
169  delete[] m_fifo;
170  m_fifo = 0;
171  }
172 
173  m_fill = 0;
174  m_head = 0;
175  m_tail = 0;
176 
177  m_fifo = new qint8[numSamples * m_sampleSize];
178  m_size = numSamples;
179 
180  return true;
181 }
QMutex m_mutex
Definition: audiofifo.h:51
uint32_t m_tail
Definition: audiofifo.h:60
void clear()
Definition: audiofifo.cpp:156
bool create(uint32_t numSamples)
Definition: audiofifo.cpp:165
uint32_t drain(uint32_t numSamples)
Definition: audiofifo.cpp:141
uint32_t m_fill
Definition: audiofifo.h:58
uint32_t m_size
Definition: audiofifo.h:57
unsigned int uint32_t
Definition: rtptypes_win.h:46
qint8 * m_fifo
Definition: audiofifo.h:53
uint32_t read(quint8 *data, uint32_t numSamples)
Definition: audiofifo.cpp:103
uint32_t m_head
Definition: audiofifo.h:59
const uint32_t m_sampleSize
Definition: audiofifo.h:55
bool isEmpty() const
Definition: audiofifo.h:46
bool setSize(uint32_t numSamples)
Definition: audiofifo.cpp:59
bool isFull() const
Definition: audiofifo.h:47
#define MIN(x, y)
Definition: audiofifo.cpp:25
uint32_t write(const quint8 *data, uint32_t numSamples)
Definition: audiofifo.cpp:66