1  /************************************************************************/
2  /*                                                                      */
3  /*                Centre for Speech Technology Research                 */
4  /*                     University of Edinburgh, UK                      */
5  /*                       Copyright (c) 1996,1997                        */
6  /*                        All Rights Reserved.                          */
7  /*                                                                      */
8  /*  Permission is hereby granted, free of charge, to use and distribute */
9  /*  this software and its documentation without restriction, including  */
10  /*  without limitation the rights to use, copy, modify, merge, publish, */
11  /*  distribute, sublicense, and/or sell copies of this work, and to     */
12  /*  permit persons to whom this work is furnished to do so, subject to  */
13  /*  the following conditions:                                           */
14  /*   1. The code must retain the above copyright notice, this list of   */
15  /*      conditions and the following disclaimer.                        */
16  /*   2. Any modifications must be clearly marked as such.               */
17  /*   3. Original authors' names are not deleted.                        */
18  /*   4. The authors' names are not used to endorse or promote products  */
19  /*      derived from this software without specific prior written       */
20  /*      permission.                                                     */
21  /*                                                                      */
22  /*  THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK       */
23  /*  DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING     */
24  /*  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT  */
25  /*  SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE    */
26  /*  FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES   */
27  /*  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN  */
28  /*  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,         */
29  /*  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF      */
30  /*  THIS SOFTWARE.                                                      */
31  /*                                                                      */
32  /*************************************************************************/
33 
34 /**@name EST_TBuffer.h
35   * Extending buffers, ie arrays which grow as needed.
36   * I got fed up of writing equivalent code all over the place.
37   *
38   * @see EST_TBuffer
39   * @author Richard Caley <rjc@cstr.ed.ac.uk>
40   * @version $Id: EST_TBuffer.h,v 1.4 2004/09/29 08:24:17 robert Exp $
41   */
42 //@{
43 #ifndef __EST_TBUFFER_H__
44 #define __EST_TBUFFER_H__
45 
46 #include "EST_bool.h"
47 
48 /// How many chunks of memory to keep around for re-use.
49 #define TBUFFER_N_OLD (10)
50 
51 /// Initial size for buffers created with no size specified.
52 #define TBUFFER_DEFAULT_SIZE 0
53 
54 /// Amount to increment buffer size by.
55 #define TBUFFER_DEFAULT_STEP 100
56 
57 /** Structure to remember old buffers for re-use.
58   * @see EST_TBuffer.h
59   */
60 struct old_tbuffer { void *mem; unsigned int size; };
61 
62 /// Memory of old buffers
63 extern struct old_tbuffer EST_old_buffers[TBUFFER_N_OLD];
64 
65 
66 /** Extending buffer class.
67   * <p>
68   * This class provides the convenience of arrays which change in size
69   * at run time rather more efficiently than the full EST_TVector class
70   * would.
71   * <p>
72   * Buffers can only be expanded and when a buffer is no longer needed
73   * (i.e. when the variable goes out of scope) the memory is not deleted,
74   * rather it is saved for re-use as a new buffer.
75   * <p>
76   * A typical use would be a buffer to hold a windowed section of a signal
77   * inside a signal processing loop where the size of the window changes from
78   * iteration to iteration.
79   *
80   * @see EST_TBuffer.h, Associated definitions.
81   * @see EST_TVector, class to use for more general uses.
82   * @see lpc_analyse, example of use.
83   */
84 
85 template<class TYPE>
86 class EST_TBuffer {
87 
88 private:
89   /// Pointer to memory.
90   TYPE *p_buffer;
91   /// Current size.
92   unsigned int p_size;
93   /// Amount to grow by (if negative it is a percentage).
94   int p_step;
95 
96 private:
97   /// Setup code.
98   void init(unsigned int size, int step);
99   /// Expand the buffer.
100   void expand_to(unsigned int req_size, bool cpy);
101   /// Expand and set some of it to a known value.
102   void expand_to(unsigned int req_size, const TYPE &set_to, int howmany);
103 
104 public:
105 
106   /** Create with size and increment.
107     * Increment can be negative for percentage growth.
108     * <p>
109     * Tries to use a buffer from EST_old_buffers[] if there is one which
110     * is suitable
111     * @see EST_old_buffers
112     */
113   EST_TBuffer(unsigned int size=TBUFFER_DEFAULT_SIZE, int step=TBUFFER_DEFAULT_STEP);
114 
115   /// Destructor. Places the memory in EST_old_buffers[] for re-use if there is room.
116   ~EST_TBuffer(void);
117 
118   /// Current available space.
length(void)119   unsigned int length(void) const {return p_size;}
120 
121   /// Set to the given value. By default sets all values.
122   void set(const TYPE &set_to, int howmany=-1);
123 
124   /**@name Methods to make sure there is enough space. */
125   //@{
126 
127   /// Extend if needed, copying existing data.
ensure(unsigned int req_size)128   void ensure(unsigned int req_size)
129     {if (req_size > p_size) expand_to(req_size, (bool)TRUE);}
130 
131   /// Make sure there is enough space, copying if requested.
ensure(unsigned int req_size,bool copy)132   void ensure(unsigned int req_size, bool copy)
133   {if (req_size > p_size) expand_to(req_size, copy,-1);}
134 
135   /// Make sure there is enough space, setting to a known value.
136   void ensure(unsigned int req_size, const TYPE &set_to, int howmany=-1)
137     {if (req_size > p_size) expand_to(req_size, set_to, howmany);}
138   //@}
139 
140   /**@name Access to the memory itself. */
141   //@{
142 
143   /// Simple access as a pointer.
b(void)144   TYPE *b(void) {return p_buffer;}
145   /// Read-only access when the EST_TBuffer is a constant
b(void)146   const TYPE *b(void) const {return p_buffer;}
147 
148   /// operator () is simple access
operator()149   const TYPE &operator() (unsigned int i) const { return p_buffer[i];}
150 
151   TYPE &operator[] (unsigned int i) { return p_buffer[i];}
152   const TYPE &operator[] (unsigned int i) const { return p_buffer[i];}
153 
154   //@}
155 };
156 
157 #endif
158 
159 //@}
160