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)
9 #include "audio_membuffer.hpp"
11 _AUDIO_NAMESPACE_START_
13 /* Protected Functions */
16 audio_membuffer::alloc_mem_(unsigned int bytes
)
22 /* Checks previously alloc'd memory and frees it */
26 /* Allocs new memory and zeros it */
27 audio_data
= new BYTE
[bytes
];
28 memset(audio_data
, 0, bytes
* sizeof(BYTE
));
30 /* Sets the correct buffer size */
36 audio_membuffer::free_mem_(void)
46 audio_membuffer::resize_mem_(unsigned int new_size
)
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
)
60 /* Allocs new memory and zeros it */
61 new_mem
= new BYTE
[new_size
];
62 memset(new_mem
, 0, new_size
* sizeof(BYTE
));
66 /* Copies received audio data, and discard unused memory */
67 memcpy(new_mem
, audio_data
, bytes_received
);
68 /* Frees old memory */
70 /* Commit new memory */
79 buffer_resized(new_size
);
83 audio_membuffer::truncate_(void)
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
)
92 /* Allocs a new buffer */
93 BYTE
* newbuf
= new BYTE
[bytes_received
];
94 /* Copies audio data */
95 memcpy(newbuf
, audio_data
, bytes_received
);
96 /* Frees old memory */
98 /* Commit the new buffer */
100 buf_size
= bytes_received
;
102 /* Buffer truncation successful. Now the buffer size is exactly big
103 as much audio data was received */
107 /* Public Functions */
110 audio_membuffer::clear(void)
117 audio_membuffer::reset(void)
119 /* Frees memory and reset to initial state */
121 /* Alloc memory of size specified at the constructor */
122 alloc_mem_(init_size
);
126 audio_membuffer::alloc_bytes(unsigned int bytes
)
132 audio_membuffer::alloc_seconds(unsigned int secs
)
134 alloc_mem_(aud_info
.byte_rate() * secs
);
138 audio_membuffer::alloc_seconds(float secs
)
140 alloc_mem_((unsigned int)((float)aud_info
.byte_rate() * secs
));
144 audio_membuffer::resize_bytes(unsigned int bytes
)
150 audio_membuffer::resize_seconds(unsigned int secs
)
152 resize_mem_(aud_info
.byte_rate() * secs
);
156 audio_membuffer::resize_seconds(float secs
)
158 resize_mem_((unsigned int)((float)aud_info
.byte_rate() * secs
));
161 /* Inherited Functions */
164 audio_membuffer::audio_receive(unsigned char *data
, unsigned int size
)
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))
169 alloc_mem_(size
* 2);
170 memcpy(audio_data
, data
, size
);
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
;
180 /* Calcs new buffer size */
181 /* TODO: flags for other behaviour? */
182 while (free_mem
< size
)
185 free_mem
= tot_mem
- bytes_received
;
188 /* Resize buffer memory */
189 resize_mem_(tot_mem
);
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
);
196 audio_arrival(aud_info
.samples_in_bytes(size
));
200 audio_membuffer::read(BYTE
*out_buf
, unsigned int bytes
)
206 if (bytes_played_
>= bytes_received
)
209 unsigned int to_play
= bytes_received
- bytes_played_
;
210 unsigned int to_copy
= bytes
> to_play
? to_play
: bytes
;
212 /* Copies the audio data out */
213 if ((out_buf
) && (to_copy
) && (audio_data
))
214 memcpy(out_buf
, audio_data
+ bytes_played_
, to_copy
);
216 /* Increments the number of total bytes played (audio data gone out from
217 the `audio_producer' object) */
218 bytes_played_
+= to_copy
;
221 audio_arrival(aud_info
.samples_in_bytes(to_copy
));
223 /* Returns the exact size of audio data produced */
228 audio_membuffer::finished(void)
230 if (bytes_played_
< bytes_received
)
236 _AUDIO_NAMESPACE_END_