Something went wrong. Try again.
Reactos
Something went wrong. Try again.
5.7 kB · 236 lines
C++
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237/* PROJECT: ReactOS sndrec32 * LICENSE: GPL - See COPYING in the top level directory * FILE: base/applications/sndrec32/audio_membuffer.cpp * PURPOSE: Sound recording * PROGRAMMERS: Marco Pagliaricci (irc: rendar) */
#include "stdafx.h"#include "audio_membuffer.hpp"
_AUDIO_NAMESPACE_START_
/* Protected Functions */
voidaudio_membuffer::alloc_mem_(unsigned int bytes){ /* Some checking */ if (bytes == 0) return;
/* Checks previously alloc'd memory and frees it */ if (audio_data) delete[] audio_data;
/* Allocs new memory and zeros it */ audio_data = new BYTE[bytes]; memset(audio_data, 0, bytes * sizeof(BYTE));
/* Sets the correct buffer size */ buf_size = bytes; init_size = bytes;}
voidaudio_membuffer::free_mem_(void){ if (audio_data) delete[] audio_data;
buf_size = 0; audio_data = 0;}
voidaudio_membuffer::resize_mem_(unsigned int new_size){ if (new_size == 0) return;
/* The new_size, cannot be <= of the `bytes_received' member value of the parent class `audio_receiver'. We cannot touch received audio data, so we have to alloc at least bytes_received+1 bytes. But we can truncate unused memory, so `new_size' can be < of `buf_size' */ if (new_size <= bytes_received) return;
BYTE * new_mem;
/* Allocs new memory and zeros it */ new_mem = new BYTE[new_size]; memset(new_mem, 0, new_size * sizeof(BYTE));
if (audio_data) { /* Copies received audio data, and discard unused memory */ memcpy(new_mem, audio_data, bytes_received); /* Frees old memory */ delete[] audio_data; /* Commit new memory */ audio_data = new_mem; buf_size = new_size; } else { audio_data = new_mem; buf_size = new_size; }
if (buffer_resized) buffer_resized(new_size);}
voidaudio_membuffer::truncate_(void){ /* If `buf_size' is already = to the `bytes_received' of audio data, then this operation is useless; simply return */ if (bytes_received == buf_size) return;
if (audio_data) { /* Allocs a new buffer */ BYTE * newbuf = new BYTE[bytes_received]; /* Copies audio data */ memcpy(newbuf, audio_data, bytes_received); /* Frees old memory */ delete[] audio_data; /* Commit the new buffer */ audio_data = newbuf; buf_size = bytes_received;
/* Buffer truncation successful. Now the buffer size is exactly big as much audio data was received */ }}
/* Public Functions */
voidaudio_membuffer::clear(void){ free_mem_(); bytes_received = 0;}
voidaudio_membuffer::reset(void){ /* Frees memory and reset to initial state */ clear(); /* Alloc memory of size specified at the constructor */ alloc_mem_(init_size);}
voidaudio_membuffer::alloc_bytes(unsigned int bytes){ alloc_mem_(bytes);}
voidaudio_membuffer::alloc_seconds(unsigned int secs){ alloc_mem_(aud_info.byte_rate() * secs);}
voidaudio_membuffer::alloc_seconds(float secs){ alloc_mem_((unsigned int)((float)aud_info.byte_rate() * secs));}
voidaudio_membuffer::resize_bytes(unsigned int bytes){ resize_mem_(bytes);}
voidaudio_membuffer::resize_seconds(unsigned int secs){ resize_mem_(aud_info.byte_rate() * secs);}
voidaudio_membuffer::resize_seconds(float secs){ resize_mem_((unsigned int)((float)aud_info.byte_rate() * secs));}
/* Inherited Functions */
voidaudio_membuffer::audio_receive(unsigned char *data, unsigned int size){ /* If there isn't a buffer, allocs memory for it of size*2, and copies audio data arrival */ if ((audio_data == 0) || (buf_size == 0)) { alloc_mem_(size * 2); memcpy(audio_data, data, size); return; }
/* If buffer's free memory is < of `size', we have to realloc buffer memory of buf_size*2, while free memory is enough to contain `size' bytes. In this case free memory is represented by `buf_size - bytes_recorded' */ unsigned int tot_mem = buf_size, free_mem = buf_size - bytes_received; if (free_mem < size) { /* Calcs new buffer size */ /* TODO: flags for other behaviour? */ while (free_mem < size) { tot_mem *= 2; free_mem = tot_mem - bytes_received; }
/* Resize buffer memory */ resize_mem_(tot_mem); }
/* Now we have enough free space in the buffer, so let's copy audio data arrivals */ memcpy(audio_data + bytes_received, data, size);
if (audio_arrival) audio_arrival(aud_info.samples_in_bytes(size));}
unsigned intaudio_membuffer::read(BYTE *out_buf, unsigned int bytes){ /* Some checking */ if (!audio_data) return 0;
if (bytes_played_ >= bytes_received) return 0;
unsigned int to_play = bytes_received - bytes_played_; unsigned int to_copy = bytes > to_play ? to_play : bytes;
/* Copies the audio data out */ if ((out_buf) && (to_copy) && (audio_data)) memcpy(out_buf, audio_data + bytes_played_, to_copy);
/* Increments the number of total bytes played (audio data gone out from the `audio_producer' object) */ bytes_played_ += to_copy;
if (audio_arrival) audio_arrival(aud_info.samples_in_bytes(to_copy));
/* Returns the exact size of audio data produced */ return to_copy;}
boolaudio_membuffer::finished(void){ if (bytes_played_ < bytes_received) return false; else return true;}
_AUDIO_NAMESPACE_END_