1 /*
2 * $Id$
3 *
4 * Copyright (C) 2002-2003 Fhg Fokus
5 *
6 * This file is part of SEMS, a free SIP media server.
7 *
8 * SEMS is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * For a license to use the sems software under conditions
14 * other than those described here, or to purchase support for this
15 * software, please contact iptel.org by e-mail at the following addresses:
16 * info@iptel.org
17 *
18 * SEMS is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 */
27
28 #ifndef _SampleArray_cc_
29 #define _SampleArray_cc_
30
31 #include "log.h"
32 #include <string.h>
33
34 // inline bool cmp_ts(unsigned int t1, unsigned int t2)
35 // {
36 // // t1 < t2
37 // return (t1 - t2 > (unsigned int)(1<<31));
38 // }
39
operator ()(const unsigned int & l,const unsigned int & r) const40 inline bool ts_less::operator()(const unsigned int& l,
41 const unsigned int& r) const
42 {
43 return (l - r > (unsigned int)(1<<31));
44 }
45
operator ()(const unsigned long long & l,const unsigned long long & r) const46 inline bool sys_ts_less::operator()(const unsigned long long& l,
47 const unsigned long long& r) const
48 {
49 return (((l - r) & 0xFFFFFFFFFFFFLL) > (1LL<<47));
50 }
51
52 template <typename T>
SampleArray()53 SampleArray<T>::SampleArray()
54 : init(false)
55 {
56 }
57
58 template <typename T>
clear_all()59 void SampleArray<T>::clear_all()
60 {
61 memset(samples,0,sizeof(samples));
62 }
63
64 template <typename T>
clear(unsigned int start_ts,unsigned int end_ts)65 void SampleArray<T>::clear(unsigned int start_ts,unsigned int end_ts)
66 {
67 if(end_ts - start_ts >= SIZE_MIX_BUFFER){
68 clear_all();
69 return;
70 }
71
72 unsigned int start_off = start_ts & (SIZE_MIX_BUFFER-1);
73 unsigned int end_off = end_ts & (SIZE_MIX_BUFFER-1);
74
75 T* sp = samples + start_off;
76 if(start_off < end_off)
77 memset(sp,0,(end_off-start_off)*sizeof(T));
78 else {
79 memset(sp,0,(SIZE_MIX_BUFFER-start_off)*sizeof(T));
80 memset(samples,0,end_off*sizeof(T));
81 }
82 }
83
84 template <typename T>
write(unsigned int ts,T * buffer,unsigned int size)85 void SampleArray<T>::write(unsigned int ts, T* buffer, unsigned int size)
86 {
87 unsigned int off = ts & (SIZE_MIX_BUFFER-1);
88
89 T* sp = samples + off;
90 if(off+size <= SIZE_MIX_BUFFER)
91 memcpy(sp,buffer,size*sizeof(T));
92 else {
93 unsigned int s = SIZE_MIX_BUFFER-off;
94 memcpy(sp,buffer,s*sizeof(T));
95
96 buffer += s;
97 size -= s;
98 memcpy(samples,buffer,size*sizeof(T));
99 }
100 }
101
102 template <typename T>
read(unsigned int ts,T * buffer,unsigned int size)103 void SampleArray<T>::read(unsigned int ts, T* buffer, unsigned int size)
104 {
105 unsigned int off = ts & (SIZE_MIX_BUFFER-1);
106
107 T* sp = samples + off;
108 if(off+size <= SIZE_MIX_BUFFER){
109 memcpy(buffer,sp,size*sizeof(T));
110 }
111 else {
112 unsigned int s = SIZE_MIX_BUFFER - off;
113 memcpy(buffer,sp,s*sizeof(T));
114
115 buffer += s;;
116 size -= s;
117 memcpy(buffer,samples,size*sizeof(T));
118 }
119 }
120
121 template <typename T>
put(unsigned int ts,T * buffer,unsigned int size)122 void SampleArray<T>::put(unsigned int ts, T* buffer, unsigned int size)
123 {
124 //assert(size <= SIZE_MIX_BUFFER);
125
126 if(!init){
127 clear_all();
128 last_ts = ts;
129 init = true;
130 }
131
132 if(ts_less()(ts,last_ts-SIZE_MIX_BUFFER)){
133 DBG("throwing away too old packet (ts=%u; last_ts=%u).\n",ts,last_ts);
134 return;
135 }
136
137 if(ts_less()(last_ts,ts))
138 clear(last_ts,ts);
139
140 write(ts,buffer,size);
141 if(ts_less()(last_ts,ts+size))
142 last_ts = ts+size;
143 }
144
145 template <typename T>
get(unsigned int ts,T * buffer,unsigned int size)146 void SampleArray<T>::get(unsigned int ts, T* buffer, unsigned int size)
147 {
148 //assert(size <= SIZE_MIX_BUFFER);
149
150 if(!init ||
151 !ts_less()(ts,last_ts) ||
152 !ts_less()(last_ts-SIZE_MIX_BUFFER,ts+size)){
153
154 // !init ||
155 // (ts+size <= last_ts-SIZE_MIX_BUFFER) ||
156 // (ts >= last_ts)
157 memset(buffer,0,size*sizeof(T));
158 return;
159 }
160
161 // init &&
162 // (ts+size > last_ts-SIZE_MIX_BUFFER) &&
163 // (ts < last_ts)
164
165 if(ts_less()(ts,last_ts-SIZE_MIX_BUFFER)){
166
167 // ts < last_ts-SIZE_MIX_BUFFER
168 unsigned int s = last_ts-SIZE_MIX_BUFFER-ts;
169 memset(buffer,0,s*sizeof(T));
170
171 ts += s; buffer += s; size -= s;
172 read(ts,buffer,size);
173 }
174 else if(ts_less()(last_ts,ts+size)){
175
176 // ts+size > last_ts
177 unsigned int s = last_ts-ts;
178 read(ts,buffer,s);
179
180 buffer += s; size -= s;
181 memset(buffer,0,size*sizeof(T));
182 }
183 else {
184 // ts+size <= last_ts
185 read(ts,buffer,size);
186 }
187 }
188
189 #endif
190