ReactOS  0.4.12-dev-43-g63b00d8
audio_membuffer.cpp
Go to the documentation of this file.
1 /* PROJECT: ReactOS sndrec32
2  * LICENSE: GPL - See COPYING in the top level directory
3  * FILE: base/applications/sndrec32/audio_membuffer.cpp
4  * PURPOSE: Sound recording
5  * PROGRAMMERS: Marco Pagliaricci (irc: rendar)
6  */
7 
8 #include "stdafx.h"
9 #include "audio_membuffer.hpp"
10 
12 
13 /* Protected Functions */
14 
15 void
17 {
18  /* Some checking */
19  if (bytes == 0)
20  return;
21 
22  /* Checks previously alloc'd memory and frees it */
23  if (audio_data)
24  delete[] audio_data;
25 
26  /* Allocs new memory and zeros it */
27  audio_data = new BYTE[bytes];
28  memset(audio_data, 0, bytes * sizeof(BYTE));
29 
30  /* Sets the correct buffer size */
31  buf_size = bytes;
32  init_size = bytes;
33 }
34 
35 void
37 {
38  if (audio_data)
39  delete[] audio_data;
40 
41  buf_size = 0;
42  audio_data = 0;
43 }
44 
45 void
46 audio_membuffer::resize_mem_(unsigned int new_size)
47 {
48  if (new_size == 0)
49  return;
50 
51  /* The new_size, cannot be <= of the `bytes_received' member value of the
52  parent class `audio_receiver'. We cannot touch received audio data,
53  so we have to alloc at least bytes_received+1 bytes. But we can truncate
54  unused memory, so `new_size' can be < of `buf_size' */
55  if (new_size <= bytes_received)
56  return;
57 
58  BYTE * new_mem;
59 
60  /* Allocs new memory and zeros it */
61  new_mem = new BYTE[new_size];
62  memset(new_mem, 0, new_size * sizeof(BYTE));
63 
64  if (audio_data)
65  {
66  /* Copies received audio data, and discard unused memory */
67  memcpy(new_mem, audio_data, bytes_received);
68  /* Frees old memory */
69  delete[] audio_data;
70  /* Commit new memory */
71  audio_data = new_mem;
72  buf_size = new_size;
73  } else {
74  audio_data = new_mem;
75  buf_size = new_size;
76  }
77 
78  if (buffer_resized)
79  buffer_resized(new_size);
80 }
81 
82 void
84 {
85  /* If `buf_size' is already = to the `bytes_received' of audio data,
86  then this operation is useless; simply return */
87  if (bytes_received == buf_size)
88  return;
89 
90  if (audio_data)
91  {
92  /* Allocs a new buffer */
93  BYTE * newbuf = new BYTE[bytes_received];
94  /* Copies audio data */
96  /* Frees old memory */
97  delete[] audio_data;
98  /* Commit the new buffer */
99  audio_data = newbuf;
101 
102  /* Buffer truncation successful. Now the buffer size is exactly big
103  as much audio data was received */
104  }
105 }
106 
107 /* Public Functions */
108 
109 void
111 {
112  free_mem_();
113  bytes_received = 0;
114 }
115 
116 void
118 {
119  /* Frees memory and reset to initial state */
120  clear();
121  /* Alloc memory of size specified at the constructor */
123 }
124 
125 void
127 {
128  alloc_mem_(bytes);
129 }
130 
131 void
133 {
134  alloc_mem_(aud_info.byte_rate() * secs);
135 }
136 
137 void
139 {
140  alloc_mem_((unsigned int)((float)aud_info.byte_rate() * secs));
141 }
142 
143 void
145 {
146  resize_mem_(bytes);
147 }
148 
149 void
151 {
152  resize_mem_(aud_info.byte_rate() * secs);
153 }
154 
155 void
157 {
158  resize_mem_((unsigned int)((float)aud_info.byte_rate() * secs));
159 }
160 
161 /* Inherited Functions */
162 
163 void
164 audio_membuffer::audio_receive(unsigned char *data, unsigned int size)
165 {
166  /* If there isn't a buffer, allocs memory for it of size*2, and copies audio data arrival */
167  if ((audio_data == 0) || (buf_size == 0))
168  {
169  alloc_mem_(size * 2);
170  memcpy(audio_data, data, size);
171  return;
172  }
173 
174  /* If buffer's free memory is < of `size', we have to realloc buffer memory
175  of buf_size*2, while free memory is enough to contain `size' bytes.
176  In this case free memory is represented by `buf_size - bytes_recorded' */
177  unsigned int tot_mem = buf_size, free_mem = buf_size - bytes_received;
178  if (free_mem < size)
179  {
180  /* Calcs new buffer size */
181  /* TODO: flags for other behaviour? */
182  while (free_mem < size)
183  {
184  tot_mem *= 2;
185  free_mem = tot_mem - bytes_received;
186  }
187 
188  /* Resize buffer memory */
189  resize_mem_(tot_mem);
190  }
191 
192  /* Now we have enough free space in the buffer, so let's copy audio data arrivals */
193  memcpy(audio_data + bytes_received, data, size);
194 
195  if (audio_arrival)
197 }
198 
199 unsigned int
200 audio_membuffer::read(BYTE *out_buf, unsigned int bytes)
201 {
202  /* Some checking */
203  if (!audio_data)
204  return 0;
205 
207  return 0;
208 
209  unsigned int to_play = bytes_received - bytes_played_;
210  unsigned int to_copy = bytes > to_play ? to_play : bytes;
211 
212  /* Copies the audio data out */
213  if ((out_buf) && (to_copy) && (audio_data))
214  memcpy(out_buf, audio_data + bytes_played_, to_copy);
215 
216  /* Increments the number of total bytes played (audio data gone out from
217  the `audio_producer' object) */
218  bytes_played_ += to_copy;
219 
220  if (audio_arrival)
222 
223  /* Returns the exact size of audio data produced */
224  return to_copy;
225 }
226 
227 bool
229 {
231  return false;
232  else
233  return true;
234 }
235 
void(* audio_arrival)(unsigned int)
unsigned int bytes_received
void resize_seconds(unsigned int)
#define _AUDIO_NAMESPACE_START_
Definition: audio_def.hpp:24
void resize_mem_(unsigned int)
unsigned int buf_size
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
unsigned int byte_rate(void) const
unsigned int read(BYTE *, unsigned int)
void(* buffer_resized)(unsigned int)
void alloc_mem_(unsigned int)
GLsizeiptr size
Definition: glext.h:5919
unsigned int init_size
audio_format aud_info
void truncate_(void)
void resize_bytes(unsigned int)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
unsigned char BYTE
Definition: ntddk_ex.h:96
void alloc_bytes(unsigned int)
#define _AUDIO_NAMESPACE_END_
Definition: audio_def.hpp:25
unsigned int samples_in_bytes(unsigned int bytes) const
unsigned int bytes_played_
void free_mem_(void)
#define memset(x, y, z)
Definition: compat.h:39
void audio_receive(unsigned char *, unsigned int)
void alloc_seconds(unsigned int)