1 #ifndef UTILITY_H
2 #define UTILITY_H
3 
4 
5 #ifdef _MSC_VER
6 #pragma warning(disable : 4786)
7 #endif
8 
9 
10 #include <map>
11 #include <string>
12 #include <utility>
13 #include <cstdlib>
14 #include "audiere.h"
15 #include "types.h"
16 
17 
18 #if defined(_MSC_VER) && _MSC_VER <= 1200 && !defined(_STLPORT_VERSION)
19 
20   // std::min and std::max are broken in VC++ 6, so define our own.
21   // Unfortunately, this means we must include utility.h to use
22   // std::min and std::max
23   namespace std {
24 
25     #ifdef min
26       #undef min
27     #endif
28 
29     #ifdef max
30       #undef max
31     #endif
32 
33     template<typename T>
min(T a,T b)34     inline T min(T a, T b) {
35       return (a < b ? a : b);
36     }
37 
38     template<typename T>
max(T a,T b)39     inline T max(T a, T b) {
40       return (a > b ? a : b);
41     }
42   }
43 
44 #else
45 
46   #include <algorithm>
47 
48 #endif
49 
50 
51 namespace audiere {
52 
53 
54   template<typename T>
clamp(T min,T x,T max)55   T clamp(T min, T x, T max) {
56     return std::max(std::min(x, max), min);
57   }
58 
59 
60   class ParameterList {
61   public:
62     ParameterList(const char* parameters);
63     std::string getValue(const std::string& key, const std::string& defValue) const;
64     bool getBoolean(const std::string& key, bool def) const;
65     int getInt(const std::string& key, int def) const;
66 
67   private:
68     std::map<std::string, std::string> m_values;
69   };
70 
71   int strcmp_case(const char* a, const char* b);
72 
73 
GetFrameSize(SampleSource * source)74   inline int GetFrameSize(SampleSource* source) {
75     int channel_count, sample_rate;
76     SampleFormat sample_format;
77     source->getFormat(channel_count, sample_rate, sample_format);
78     return GetSampleSize(sample_format) * channel_count;
79   }
80 
GetFrameSize(const SampleSourcePtr & source)81   inline int GetFrameSize(const SampleSourcePtr& source) {
82     return GetFrameSize(source.get());
83   }
84 
85 
read16_le(const u8 * b)86   inline u16 read16_le(const u8* b) {
87     return b[0] + (b[1] << 8);
88   }
89 
read16_be(const u8 * b)90   inline u16 read16_be(const u8* b) {
91     return (b[0] << 8) + b[1];
92   }
93 
read32_le(const u8 * b)94   inline u32 read32_le(const u8* b) {
95     return read16_le(b) + (read16_le(b + 2) << 16);
96   }
97 
read32_be(const u8 * b)98   inline u32 read32_be(const u8* b) {
99     return (read16_be(b) << 16) + read16_be(b + 2);
100   }
101 
102   /// Converts an 80-bit IEEE 754 floating point number to a u32.
readLD_be(const u8 * b)103   inline u32 readLD_be(const u8* b) {
104     u32 mantissa = read32_be(b + 2);
105     u8 exp = 30 - b[1];
106     u32 last = 0;
107     while (exp--) {
108       last = mantissa;
109       mantissa >>= 1;
110     }
111     if (last & 0x1) {
112       mantissa++;
113     }
114     return mantissa;
115   }
116 
117 
GetFileLength(File * file)118   inline int GetFileLength(File* file) {
119     int pos = file->tell();
120     file->seek(0, File::END);
121     int length = file->tell();
122     file->seek(pos, File::BEGIN);
123     return length;
124   }
125 
126 
OpenBufferStream(void * samples,int sample_count,int channel_count,int sample_rate,SampleFormat sample_format)127   inline SampleSource* OpenBufferStream(
128     void* samples, int sample_count,
129     int channel_count, int sample_rate, SampleFormat sample_format)
130   {
131     return CreateSampleBuffer(
132       samples, sample_count,
133       channel_count, sample_rate, sample_format)->openStream();
134   }
135 
136 
137   class QueueBuffer {
138   public:
QueueBuffer()139     QueueBuffer() {
140       m_capacity = 256;
141       m_size = 0;
142 
143       m_buffer = (u8*)malloc(m_capacity);
144     }
145 
~QueueBuffer()146     ~QueueBuffer() {
147       m_buffer = (u8*)realloc(m_buffer, 0);
148     }
149 
getSize()150     int getSize() {
151       return m_size;
152     }
153 
write(const void * buffer,int size)154     void write(const void* buffer, int size) {
155       bool need_realloc = false;
156       while (size + m_size > m_capacity) {
157         m_capacity *= 2;
158         need_realloc = true;
159       }
160 
161       if (need_realloc) {
162         m_buffer = (u8*)realloc(m_buffer, m_capacity);
163       }
164 
165       memcpy(m_buffer + m_size, buffer, size);
166       m_size += size;
167     }
168 
read(void * buffer,int size)169     int read(void* buffer, int size) {
170       int to_read = std::min(size, m_size);
171       memcpy(buffer, m_buffer, to_read);
172       memmove(m_buffer, m_buffer + to_read, m_size - to_read);
173       m_size -= to_read;
174       return to_read;
175     }
176 
clear()177     void clear() {
178       m_size = 0;
179     }
180 
181   private:
182     u8* m_buffer;
183     int m_capacity;
184     int m_size;
185 
186     // private and unimplemented to prevent their use
187     QueueBuffer(const QueueBuffer&);
188     QueueBuffer& operator=(const QueueBuffer&);
189   };
190 
191 
192   class SizedBuffer {
193   public:
SizedBuffer()194     SizedBuffer() {
195       m_capacity = 256;
196       m_buffer = malloc(m_capacity);
197     }
198 
~SizedBuffer()199     ~SizedBuffer() {
200       m_buffer = realloc(m_buffer, 0);
201     }
202 
ensureSize(int size)203     void ensureSize(int size) {
204       bool need_realloc = false;
205       while (m_capacity < size) {
206         m_capacity *= 2;
207         need_realloc = true;
208       }
209       if (need_realloc) {
210         m_buffer = realloc(m_buffer, m_capacity);
211       }
212     }
213 
get()214     void* get() {
215       return m_buffer;
216     }
217 
218   private:
219     void* m_buffer;
220     int m_capacity;
221 
222     // private and unimplemented to prevent their use
223     SizedBuffer(const SizedBuffer&);
224     SizedBuffer& operator=(const SizedBuffer&);
225   };
226 
227 }
228 
229 
230 #endif
231