Fix built a bit more.
[reactos.git] / reactos / base / applications / sndrec32 / audio_membuffer.cpp
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
9
10 #include "stdafx.h"
11 #include "audio_membuffer.hpp"
12
13
14
15 _AUDIO_NAMESPACE_START_
16
17
18
19
20 //////////////////////////////////////
21 /////// Protected Functions /////////
22 //////////////////////////////////////
23
24
25 void
26 audio_membuffer::alloc_mem_( unsigned int bytes )
27 {
28
29 //
30 // Some checking
31 //
32
33 if ( bytes == 0 )
34 return;
35
36
37
38
39
40 //
41 // Checks previsiously alloc'd memory
42 // and frees it.
43 //
44
45 if ( audio_data )
46 delete[] audio_data;
47
48
49
50 //
51 // Allocs new memory and zeros it.
52 //
53
54 audio_data = new BYTE[ bytes ];
55
56
57 memset( audio_data, 0, bytes * sizeof( BYTE ));
58
59
60
61 //
62 // Sets the correct buffer size
63 //
64
65 buf_size = bytes;
66
67
68 init_size = bytes;
69
70
71
72 }
73
74
75 void
76 audio_membuffer::free_mem_( void )
77 {
78
79 if ( audio_data )
80 delete[] audio_data;
81
82 buf_size = 0;
83 audio_data = 0;
84
85 }
86
87
88 void
89 audio_membuffer::resize_mem_( unsigned int new_size )
90 {
91
92
93 if ( new_size == 0 )
94 return;
95
96
97 //
98 // The new_size, cannot be <= of the
99 // `bytes_received' member value of the
100 // parent class `audio_receiver'.
101 // We cannot touch received audio data,
102 // so we have to alloc at least
103 // bytes_received+1 bytes.
104 //
105 // But we can truncate unused memory, so
106 // `new_size' can be < of `buf_size'.
107 //
108
109 if ( new_size <= bytes_received )
110 return;
111
112
113
114
115 BYTE * new_mem;
116
117
118
119 //
120 // Allocs new memory and zeros it.
121 //
122
123
124 new_mem = new BYTE[ new_size ];
125
126 memset( new_mem, 0, new_size * sizeof( BYTE ));
127
128
129
130 if ( audio_data )
131 {
132
133
134 //
135 // Copies received audio data, and discard
136 // unused memory.
137 //
138
139 memcpy( new_mem, audio_data, bytes_received );
140
141
142
143 //
144 // Frees old memory.
145 //
146
147 delete[] audio_data;
148
149
150
151
152
153 //
154 // Commit new memory.
155 //
156
157 audio_data = new_mem;
158 buf_size = new_size;
159
160
161
162
163 } else {
164
165 audio_data = new_mem;
166 buf_size = new_size;
167 }
168
169
170 if ( buffer_resized )
171 buffer_resized( new_size );
172
173 }
174
175
176
177
178 void
179 audio_membuffer::truncate_( void )
180 {
181
182 //
183 // If `buf_size' is already = to the
184 // `bytes_received' of audio data, then
185 // this operation is useless; simply return.
186 //
187
188 if ( bytes_received == buf_size )
189 return;
190
191
192
193 if ( audio_data )
194 {
195
196
197 //
198 // Allocs a new buffer.
199 //
200
201 BYTE * newbuf = new BYTE[ bytes_received ];
202
203
204
205
206 //
207 // Copies audio data.
208 //
209
210 memcpy( newbuf, audio_data, bytes_received );
211
212
213
214 //
215 // Frees old memory.
216 //
217
218 delete[] audio_data;
219
220
221
222 //
223 // Commit the new buffer.
224 //
225
226 audio_data = newbuf;
227 buf_size = bytes_received;
228
229
230
231 //
232 // Buffer truncation successfull.
233 // Now the buffer size is exactly big
234 // as much audio data was received.
235 //
236
237
238 }
239
240
241 }
242
243
244
245
246
247
248 //////////////////////////////////////
249 /////// Public Functions ///////////
250 //////////////////////////////////////
251
252
253
254
255 void
256 audio_membuffer::clear( void )
257 {
258
259 free_mem_();
260
261 bytes_received = 0;
262 }
263
264
265
266 void
267 audio_membuffer::reset( void )
268 {
269
270
271 //
272 // Frees memory and reset
273 // to initial state.
274 //
275
276 clear();
277
278
279
280 //
281 // Alloc memory of size specified
282 // at the constructor.
283 //
284
285 alloc_mem_( init_size );
286
287
288 }
289
290 void
291 audio_membuffer::alloc_bytes( unsigned int bytes )
292 {
293
294 alloc_mem_( bytes );
295
296 }
297
298
299
300
301 void
302 audio_membuffer::alloc_seconds( unsigned int secs )
303 {
304
305 alloc_mem_( aud_info.byte_rate() * secs );
306
307 }
308
309
310 void
311 audio_membuffer::alloc_seconds( float secs )
312 {
313
314 alloc_mem_(( unsigned int )(( float ) aud_info.byte_rate() * secs ));
315
316 }
317
318
319
320
321 void
322 audio_membuffer::resize_bytes( unsigned int bytes )
323 {
324
325 resize_mem_( bytes );
326
327 }
328
329
330
331 void
332 audio_membuffer::resize_seconds( unsigned int secs )
333 {
334
335 resize_mem_( aud_info.byte_rate() * secs );
336
337 }
338
339
340 void
341 audio_membuffer::resize_seconds( float secs )
342 {
343
344 resize_mem_(( unsigned int )
345 (( float )aud_info.byte_rate() * secs )
346 );
347
348 }
349
350
351
352
353
354 ///////////////////////////////////////
355 /////// Inherited Functions /////////
356 ///////////////////////////////////////
357
358
359
360
361
362
363
364 void
365 audio_membuffer::audio_receive
366 ( unsigned char * data, unsigned int size )
367 {
368
369
370
371
372 //
373 // If there isn't a buffer, allocs memory for
374 // it of size*2, and copies audio data arrival.
375 //
376
377 if (( audio_data == 0 ) || ( buf_size == 0 ))
378 {
379 alloc_mem_( size * 2 );
380
381 memcpy( audio_data, data, size );
382
383 return;
384
385 }
386
387
388
389
390
391 //
392 // If buffer's free memory is < of `size',
393 // we have to realloc buffer memory of
394 // buf_size*2, while free memory is enough
395 // to contain `size' bytes.
396 //
397 // In this case free memory is represented
398 // by `buf_size - bytes_recorded'.
399 //
400
401 unsigned int tot_mem = buf_size,
402 free_mem = buf_size - bytes_received;
403
404
405 if ( free_mem < size )
406 {
407
408 //
409 // Calcs new buffer size.
410 // TODO: flags for other behaviour?
411
412 while ( free_mem < size )
413 {
414 tot_mem *= 2;
415
416 free_mem = tot_mem - bytes_received;
417 }
418
419
420
421 //
422 // Resize buffer memory.
423 //
424
425 resize_mem_( tot_mem );
426
427 }
428
429
430 //
431 // Now we have enough free space in the
432 // buffer, so let's copy audio data arrivals.
433 //
434
435 memcpy( audio_data + bytes_received, data, size );
436
437
438
439
440 if ( audio_arrival )
441 audio_arrival( aud_info.samples_in_bytes( size ));
442
443
444
445 }
446
447
448 unsigned int
449 audio_membuffer::read( BYTE * out_buf, unsigned int bytes )
450 {
451
452
453 //
454 // Some checking
455 //
456
457 if ( !audio_data )
458 return 0;
459
460
461 if ( bytes_played_ >= bytes_received )
462 return 0;
463
464
465
466 unsigned int to_play =
467 bytes_received - bytes_played_;
468
469
470 unsigned int to_copy =
471 bytes > to_play ? to_play : bytes;
472
473
474 //
475 // Copies the audio data out.
476 //
477
478 if (( out_buf ) && ( to_copy ) && ( audio_data ))
479 memcpy( out_buf, audio_data + bytes_played_, to_copy );
480
481
482 //
483 // Increments the number of total bytes
484 // played (audio data gone out from the
485 // `audio_producer' object).
486 //
487
488 bytes_played_ += to_copy;
489
490
491 if ( audio_arrival )
492 audio_arrival( aud_info.samples_in_bytes( to_copy ));
493
494
495 //
496 // Returns the exact size of audio data
497 // produced.
498 //
499
500 return to_copy;
501 }
502
503
504 bool
505 audio_membuffer::finished( void )
506 {
507 if ( bytes_played_ < bytes_received )
508 return false;
509 else
510 return true;
511 }
512
513
514 _AUDIO_NAMESPACE_END_