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)
11 #include "audio_membuffer.hpp"
15 _AUDIO_NAMESPACE_START_
20 //////////////////////////////////////
21 /////// Protected Functions /////////
22 //////////////////////////////////////
26 audio_membuffer::alloc_mem_( unsigned int bytes
)
41 // Checks previsiously alloc'd memory
51 // Allocs new memory and zeros it.
54 audio_data
= new BYTE
[ bytes
];
57 memset( audio_data
, 0, bytes
* sizeof( BYTE
));
62 // Sets the correct buffer size
76 audio_membuffer::free_mem_( void )
89 audio_membuffer::resize_mem_( unsigned int new_size
)
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.
105 // But we can truncate unused memory, so
106 // `new_size' can be < of `buf_size'.
109 if ( new_size
<= bytes_received
)
120 // Allocs new memory and zeros it.
124 new_mem
= new BYTE
[ new_size
];
126 memset( new_mem
, 0, new_size
* sizeof( BYTE
));
135 // Copies received audio data, and discard
139 memcpy( new_mem
, audio_data
, bytes_received
);
154 // Commit new memory.
157 audio_data
= new_mem
;
165 audio_data
= new_mem
;
170 if ( buffer_resized
)
171 buffer_resized( new_size
);
179 audio_membuffer::truncate_( void )
183 // If `buf_size' is already = to the
184 // `bytes_received' of audio data, then
185 // this operation is useless; simply return.
188 if ( bytes_received
== buf_size
)
198 // Allocs a new buffer.
201 BYTE
* newbuf
= new BYTE
[ bytes_received
];
207 // Copies audio data.
210 memcpy( newbuf
, audio_data
, bytes_received
);
223 // Commit the new buffer.
227 buf_size
= bytes_received
;
232 // Buffer truncation successfull.
233 // Now the buffer size is exactly big
234 // as much audio data was received.
248 //////////////////////////////////////
249 /////// Public Functions ///////////
250 //////////////////////////////////////
256 audio_membuffer::clear( void )
267 audio_membuffer::reset( void )
272 // Frees memory and reset
281 // Alloc memory of size specified
282 // at the constructor.
285 alloc_mem_( init_size
);
291 audio_membuffer::alloc_bytes( unsigned int bytes
)
302 audio_membuffer::alloc_seconds( unsigned int secs
)
305 alloc_mem_( aud_info
.byte_rate() * secs
);
311 audio_membuffer::alloc_seconds( float secs
)
314 alloc_mem_(( unsigned int )(( float ) aud_info
.byte_rate() * secs
));
322 audio_membuffer::resize_bytes( unsigned int bytes
)
325 resize_mem_( bytes
);
332 audio_membuffer::resize_seconds( unsigned int secs
)
335 resize_mem_( aud_info
.byte_rate() * secs
);
341 audio_membuffer::resize_seconds( float secs
)
344 resize_mem_(( unsigned int )
345 (( float )aud_info
.byte_rate() * secs
)
354 ///////////////////////////////////////
355 /////// Inherited Functions /////////
356 ///////////////////////////////////////
365 audio_membuffer::audio_receive
366 ( unsigned char * data
, unsigned int size
)
373 // If there isn't a buffer, allocs memory for
374 // it of size*2, and copies audio data arrival.
377 if (( audio_data
== 0 ) || ( buf_size
== 0 ))
379 alloc_mem_( size
* 2 );
381 memcpy( audio_data
, data
, size
);
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.
397 // In this case free memory is represented
398 // by `buf_size - bytes_recorded'.
401 unsigned int tot_mem
= buf_size
,
402 free_mem
= buf_size
- bytes_received
;
405 if ( free_mem
< size
)
409 // Calcs new buffer size.
410 // TODO: flags for other behaviour?
412 while ( free_mem
< size
)
416 free_mem
= tot_mem
- bytes_received
;
422 // Resize buffer memory.
425 resize_mem_( tot_mem
);
431 // Now we have enough free space in the
432 // buffer, so let's copy audio data arrivals.
435 memcpy( audio_data
+ bytes_received
, data
, size
);
441 audio_arrival( aud_info
.samples_in_bytes( size
));
449 audio_membuffer::read( BYTE
* out_buf
, unsigned int bytes
)
461 if ( bytes_played_
>= bytes_received
)
466 unsigned int to_play
=
467 bytes_received
- bytes_played_
;
470 unsigned int to_copy
=
471 bytes
> to_play
? to_play
: bytes
;
475 // Copies the audio data out.
478 if (( out_buf
) && ( to_copy
) && ( audio_data
))
479 memcpy( out_buf
, audio_data
+ bytes_played_
, to_copy
);
483 // Increments the number of total bytes
484 // played (audio data gone out from the
485 // `audio_producer' object).
488 bytes_played_
+= to_copy
;
492 audio_arrival( aud_info
.samples_in_bytes( to_copy
));
496 // Returns the exact size of audio data
505 audio_membuffer::finished( void )
507 if ( bytes_played_
< bytes_received
)
514 _AUDIO_NAMESPACE_END_