indent
git-svn-id: http://svn.openzap.org/svn/openzap/trunk@205 a93c3328-9c30-0410-af19-c9cd2b2d52af
This commit is contained in:
parent
f59addad71
commit
dce12e0eaa
|
@ -36,47 +36,47 @@
|
||||||
|
|
||||||
/* Copied from the CCITT G.711 specification */
|
/* Copied from the CCITT G.711 specification */
|
||||||
static const uint8_t ulaw_to_alaw_table[256] =
|
static const uint8_t ulaw_to_alaw_table[256] =
|
||||||
{
|
{
|
||||||
42, 43, 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, 38, 39, 36, 37,
|
42, 43, 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, 38, 39, 36, 37,
|
||||||
58, 59, 56, 57, 62, 63, 60, 61, 50, 51, 48, 49, 54, 55, 52, 53,
|
58, 59, 56, 57, 62, 63, 60, 61, 50, 51, 48, 49, 54, 55, 52, 53,
|
||||||
10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6, 7, 4, 26,
|
10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6, 7, 4, 26,
|
||||||
27, 24, 25, 30, 31, 28, 29, 18, 19, 16, 17, 22, 23, 20, 21, 106,
|
27, 24, 25, 30, 31, 28, 29, 18, 19, 16, 17, 22, 23, 20, 21, 106,
|
||||||
104, 105, 110, 111, 108, 109, 98, 99, 96, 97, 102, 103, 100, 101, 122, 120,
|
104, 105, 110, 111, 108, 109, 98, 99, 96, 97, 102, 103, 100, 101, 122, 120,
|
||||||
126, 127, 124, 125, 114, 115, 112, 113, 118, 119, 116, 117, 75, 73, 79, 77,
|
126, 127, 124, 125, 114, 115, 112, 113, 118, 119, 116, 117, 75, 73, 79, 77,
|
||||||
66, 67, 64, 65, 70, 71, 68, 69, 90, 91, 88, 89, 94, 95, 92, 93,
|
66, 67, 64, 65, 70, 71, 68, 69, 90, 91, 88, 89, 94, 95, 92, 93,
|
||||||
82, 82, 83, 83, 80, 80, 81, 81, 86, 86, 87, 87, 84, 84, 85, 85,
|
82, 82, 83, 83, 80, 80, 81, 81, 86, 86, 87, 87, 84, 84, 85, 85,
|
||||||
170, 171, 168, 169, 174, 175, 172, 173, 162, 163, 160, 161, 166, 167, 164, 165,
|
170, 171, 168, 169, 174, 175, 172, 173, 162, 163, 160, 161, 166, 167, 164, 165,
|
||||||
186, 187, 184, 185, 190, 191, 188, 189, 178, 179, 176, 177, 182, 183, 180, 181,
|
186, 187, 184, 185, 190, 191, 188, 189, 178, 179, 176, 177, 182, 183, 180, 181,
|
||||||
138, 139, 136, 137, 142, 143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 154,
|
138, 139, 136, 137, 142, 143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 154,
|
||||||
155, 152, 153, 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149, 234,
|
155, 152, 153, 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149, 234,
|
||||||
232, 233, 238, 239, 236, 237, 226, 227, 224, 225, 230, 231, 228, 229, 250, 248,
|
232, 233, 238, 239, 236, 237, 226, 227, 224, 225, 230, 231, 228, 229, 250, 248,
|
||||||
254, 255, 252, 253, 242, 243, 240, 241, 246, 247, 244, 245, 203, 201, 207, 205,
|
254, 255, 252, 253, 242, 243, 240, 241, 246, 247, 244, 245, 203, 201, 207, 205,
|
||||||
194, 195, 192, 193, 198, 199, 196, 197, 218, 219, 216, 217, 222, 223, 220, 221,
|
194, 195, 192, 193, 198, 199, 196, 197, 218, 219, 216, 217, 222, 223, 220, 221,
|
||||||
210, 210, 211, 211, 208, 208, 209, 209, 214, 214, 215, 215, 212, 212, 213, 213
|
210, 210, 211, 211, 208, 208, 209, 209, 214, 214, 215, 215, 212, 212, 213, 213
|
||||||
};
|
};
|
||||||
|
|
||||||
/* These transcoding tables are copied from the CCITT G.711 specification. To achieve
|
/* These transcoding tables are copied from the CCITT G.711 specification. To achieve
|
||||||
optimal results, do not change them. */
|
optimal results, do not change them. */
|
||||||
|
|
||||||
static const uint8_t alaw_to_ulaw_table[256] =
|
static const uint8_t alaw_to_ulaw_table[256] =
|
||||||
{
|
{
|
||||||
42, 43, 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, 38, 39, 36, 37,
|
42, 43, 40, 41, 46, 47, 44, 45, 34, 35, 32, 33, 38, 39, 36, 37,
|
||||||
57, 58, 55, 56, 61, 62, 59, 60, 49, 50, 47, 48, 53, 54, 51, 52,
|
57, 58, 55, 56, 61, 62, 59, 60, 49, 50, 47, 48, 53, 54, 51, 52,
|
||||||
10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6, 7, 4, 5,
|
10, 11, 8, 9, 14, 15, 12, 13, 2, 3, 0, 1, 6, 7, 4, 5,
|
||||||
26, 27, 24, 25, 30, 31, 28, 29, 18, 19, 16, 17, 22, 23, 20, 21,
|
26, 27, 24, 25, 30, 31, 28, 29, 18, 19, 16, 17, 22, 23, 20, 21,
|
||||||
98, 99, 96, 97, 102, 103, 100, 101, 93, 93, 92, 92, 95, 95, 94, 94,
|
98, 99, 96, 97, 102, 103, 100, 101, 93, 93, 92, 92, 95, 95, 94, 94,
|
||||||
116, 118, 112, 114, 124, 126, 120, 122, 106, 107, 104, 105, 110, 111, 108, 109,
|
116, 118, 112, 114, 124, 126, 120, 122, 106, 107, 104, 105, 110, 111, 108, 109,
|
||||||
72, 73, 70, 71, 76, 77, 74, 75, 64, 65, 63, 63, 68, 69, 66, 67,
|
72, 73, 70, 71, 76, 77, 74, 75, 64, 65, 63, 63, 68, 69, 66, 67,
|
||||||
86, 87, 84, 85, 90, 91, 88, 89, 79, 79, 78, 78, 82, 83, 80, 81,
|
86, 87, 84, 85, 90, 91, 88, 89, 79, 79, 78, 78, 82, 83, 80, 81,
|
||||||
170, 171, 168, 169, 174, 175, 172, 173, 162, 163, 160, 161, 166, 167, 164, 165,
|
170, 171, 168, 169, 174, 175, 172, 173, 162, 163, 160, 161, 166, 167, 164, 165,
|
||||||
185, 186, 183, 184, 189, 190, 187, 188, 177, 178, 175, 176, 181, 182, 179, 180,
|
185, 186, 183, 184, 189, 190, 187, 188, 177, 178, 175, 176, 181, 182, 179, 180,
|
||||||
138, 139, 136, 137, 142, 143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 133,
|
138, 139, 136, 137, 142, 143, 140, 141, 130, 131, 128, 129, 134, 135, 132, 133,
|
||||||
154, 155, 152, 153, 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149,
|
154, 155, 152, 153, 158, 159, 156, 157, 146, 147, 144, 145, 150, 151, 148, 149,
|
||||||
226, 227, 224, 225, 230, 231, 228, 229, 221, 221, 220, 220, 223, 223, 222, 222,
|
226, 227, 224, 225, 230, 231, 228, 229, 221, 221, 220, 220, 223, 223, 222, 222,
|
||||||
244, 246, 240, 242, 252, 254, 248, 250, 234, 235, 232, 233, 238, 239, 236, 237,
|
244, 246, 240, 242, 252, 254, 248, 250, 234, 235, 232, 233, 238, 239, 236, 237,
|
||||||
200, 201, 198, 199, 204, 205, 202, 203, 192, 193, 191, 191, 196, 197, 194, 195,
|
200, 201, 198, 199, 204, 205, 202, 203, 192, 193, 191, 191, 196, 197, 194, 195,
|
||||||
214, 215, 212, 213, 218, 219, 216, 217, 207, 207, 206, 206, 210, 211, 208, 209
|
214, 215, 212, 213, 218, 219, 216, 217, 207, 207, 206, 206, 210, 211, 208, 209
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t alaw_to_ulaw(uint8_t alaw)
|
uint8_t alaw_to_ulaw(uint8_t alaw)
|
||||||
{
|
{
|
||||||
|
@ -90,3 +90,15 @@ uint8_t ulaw_to_alaw(uint8_t ulaw)
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
/*- End of file ------------------------------------------------------------*/
|
/*- End of file ------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
|
@ -8,18 +8,18 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Credit for primes table: Aaron Krowne
|
Credit for primes table: Aaron Krowne
|
||||||
http://br.endernet.org/~akrowne/
|
http://br.endernet.org/~akrowne/
|
||||||
http://planetmath.org/encyclopedia/GoodHashTablePrimes.html
|
http://planetmath.org/encyclopedia/GoodHashTablePrimes.html
|
||||||
*/
|
*/
|
||||||
static const unsigned int primes[] = {
|
static const unsigned int primes[] = {
|
||||||
53, 97, 193, 389,
|
53, 97, 193, 389,
|
||||||
769, 1543, 3079, 6151,
|
769, 1543, 3079, 6151,
|
||||||
12289, 24593, 49157, 98317,
|
12289, 24593, 49157, 98317,
|
||||||
196613, 393241, 786433, 1572869,
|
196613, 393241, 786433, 1572869,
|
||||||
3145739, 6291469, 12582917, 25165843,
|
3145739, 6291469, 12582917, 25165843,
|
||||||
50331653, 100663319, 201326611, 402653189,
|
50331653, 100663319, 201326611, 402653189,
|
||||||
805306457, 1610612741
|
805306457, 1610612741
|
||||||
};
|
};
|
||||||
const unsigned int prime_table_length = sizeof(primes)/sizeof(primes[0]);
|
const unsigned int prime_table_length = sizeof(primes)/sizeof(primes[0]);
|
||||||
const float max_load_factor = 0.65f;
|
const float max_load_factor = 0.65f;
|
||||||
|
@ -81,45 +81,45 @@ hashtable_expand(struct hashtable *h)
|
||||||
|
|
||||||
newtable = (struct entry **)malloc(sizeof(struct entry*) * newsize);
|
newtable = (struct entry **)malloc(sizeof(struct entry*) * newsize);
|
||||||
if (NULL != newtable)
|
if (NULL != newtable)
|
||||||
{
|
{
|
||||||
memset(newtable, 0, newsize * sizeof(struct entry *));
|
memset(newtable, 0, newsize * sizeof(struct entry *));
|
||||||
/* This algorithm is not 'stable'. ie. it reverses the list
|
/* This algorithm is not 'stable'. ie. it reverses the list
|
||||||
* when it transfers entries between the tables */
|
* when it transfers entries between the tables */
|
||||||
for (i = 0; i < h->tablelength; i++) {
|
for (i = 0; i < h->tablelength; i++) {
|
||||||
while (NULL != (e = h->table[i])) {
|
while (NULL != (e = h->table[i])) {
|
||||||
h->table[i] = e->next;
|
h->table[i] = e->next;
|
||||||
index = indexFor(newsize,e->h);
|
index = indexFor(newsize,e->h);
|
||||||
e->next = newtable[index];
|
e->next = newtable[index];
|
||||||
newtable[index] = e;
|
newtable[index] = e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(h->table);
|
free(h->table);
|
||||||
h->table = newtable;
|
h->table = newtable;
|
||||||
}
|
}
|
||||||
/* Plan B: realloc instead */
|
/* Plan B: realloc instead */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
newtable = (struct entry **)
|
newtable = (struct entry **)
|
||||||
realloc(h->table, newsize * sizeof(struct entry *));
|
realloc(h->table, newsize * sizeof(struct entry *));
|
||||||
if (NULL == newtable) { (h->primeindex)--; return 0; }
|
if (NULL == newtable) { (h->primeindex)--; return 0; }
|
||||||
h->table = newtable;
|
h->table = newtable;
|
||||||
memset(newtable[h->tablelength], 0, newsize - h->tablelength);
|
memset(newtable[h->tablelength], 0, newsize - h->tablelength);
|
||||||
for (i = 0; i < h->tablelength; i++) {
|
for (i = 0; i < h->tablelength; i++) {
|
||||||
for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {
|
for (pE = &(newtable[i]), e = *pE; e != NULL; e = *pE) {
|
||||||
index = indexFor(newsize,e->h);
|
index = indexFor(newsize,e->h);
|
||||||
if (index == i)
|
if (index == i)
|
||||||
{
|
{
|
||||||
pE = &(e->next);
|
pE = &(e->next);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*pE = e->next;
|
*pE = e->next;
|
||||||
e->next = newtable[index];
|
e->next = newtable[index];
|
||||||
newtable[index] = e;
|
newtable[index] = e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
h->tablelength = newsize;
|
h->tablelength = newsize;
|
||||||
h->loadlimit = (unsigned int) ceil(newsize * max_load_factor);
|
h->loadlimit = (unsigned int) ceil(newsize * max_load_factor);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -140,13 +140,13 @@ hashtable_insert(struct hashtable *h, void *k, void *v)
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
struct entry *e;
|
struct entry *e;
|
||||||
if (++(h->entrycount) > h->loadlimit)
|
if (++(h->entrycount) > h->loadlimit)
|
||||||
{
|
{
|
||||||
/* Ignore the return value. If expand fails, we should
|
/* Ignore the return value. If expand fails, we should
|
||||||
* still try cramming just this value into the existing table
|
* still try cramming just this value into the existing table
|
||||||
* -- we may not have memory for a larger table, but one more
|
* -- we may not have memory for a larger table, but one more
|
||||||
* element may be ok. Next time we insert, we'll try expanding again.*/
|
* element may be ok. Next time we insert, we'll try expanding again.*/
|
||||||
hashtable_expand(h);
|
hashtable_expand(h);
|
||||||
}
|
}
|
||||||
e = (struct entry *)malloc(sizeof(struct entry));
|
e = (struct entry *)malloc(sizeof(struct entry));
|
||||||
if (NULL == e) { --(h->entrycount); return 0; } /*oom*/
|
if (NULL == e) { --(h->entrycount); return 0; } /*oom*/
|
||||||
e->h = hash(h,k);
|
e->h = hash(h,k);
|
||||||
|
@ -168,11 +168,11 @@ hashtable_search(struct hashtable *h, void *k)
|
||||||
index = indexFor(h->tablelength,hashvalue);
|
index = indexFor(h->tablelength,hashvalue);
|
||||||
e = h->table[index];
|
e = h->table[index];
|
||||||
while (NULL != e)
|
while (NULL != e)
|
||||||
{
|
{
|
||||||
/* Check hash value to short circuit heavier comparison */
|
/* Check hash value to short circuit heavier comparison */
|
||||||
if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v;
|
if ((hashvalue == e->h) && (h->eqfn(k, e->k))) return e->v;
|
||||||
e = e->next;
|
e = e->next;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,20 +193,20 @@ hashtable_remove(struct hashtable *h, void *k)
|
||||||
pE = &(h->table[index]);
|
pE = &(h->table[index]);
|
||||||
e = *pE;
|
e = *pE;
|
||||||
while (NULL != e)
|
while (NULL != e)
|
||||||
{
|
{
|
||||||
/* Check hash value to short circuit heavier comparison */
|
/* Check hash value to short circuit heavier comparison */
|
||||||
if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
|
if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
|
||||||
{
|
{
|
||||||
*pE = e->next;
|
*pE = e->next;
|
||||||
h->entrycount--;
|
h->entrycount--;
|
||||||
v = e->v;
|
v = e->v;
|
||||||
freekey(e->k);
|
freekey(e->k);
|
||||||
free(e);
|
free(e);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
pE = &(e->next);
|
pE = &(e->next);
|
||||||
e = e->next;
|
e = e->next;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,4 +261,16 @@ hashtable_destroy(struct hashtable *h, int free_keys, int free_values)
|
||||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
|
@ -23,14 +23,14 @@ hashtable_iterator(struct hashtable *h)
|
||||||
if (0 == h->entrycount) return itr;
|
if (0 == h->entrycount) return itr;
|
||||||
|
|
||||||
for (i = 0; i < tablelength; i++)
|
for (i = 0; i < tablelength; i++)
|
||||||
{
|
{
|
||||||
if (NULL != h->table[i])
|
if (NULL != h->table[i])
|
||||||
{
|
{
|
||||||
itr->e = h->table[i];
|
itr->e = h->table[i];
|
||||||
itr->index = i;
|
itr->index = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return itr;
|
return itr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,28 +48,28 @@ hashtable_iterator_advance(struct hashtable_itr *itr)
|
||||||
|
|
||||||
next = itr->e->next;
|
next = itr->e->next;
|
||||||
if (NULL != next)
|
if (NULL != next)
|
||||||
{
|
{
|
||||||
itr->parent = itr->e;
|
itr->parent = itr->e;
|
||||||
itr->e = next;
|
itr->e = next;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
tablelength = itr->h->tablelength;
|
tablelength = itr->h->tablelength;
|
||||||
itr->parent = NULL;
|
itr->parent = NULL;
|
||||||
if (tablelength <= (j = ++(itr->index)))
|
if (tablelength <= (j = ++(itr->index)))
|
||||||
{
|
{
|
||||||
itr->e = NULL;
|
itr->e = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
table = itr->h->table;
|
table = itr->h->table;
|
||||||
while (NULL == (next = table[j]))
|
while (NULL == (next = table[j]))
|
||||||
{
|
{
|
||||||
if (++j >= tablelength)
|
if (++j >= tablelength)
|
||||||
{
|
{
|
||||||
itr->index = tablelength;
|
itr->index = tablelength;
|
||||||
itr->e = NULL;
|
itr->e = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
itr->index = j;
|
itr->index = j;
|
||||||
itr->e = next;
|
itr->e = next;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -91,10 +91,10 @@ hashtable_iterator_remove(struct hashtable_itr *itr)
|
||||||
|
|
||||||
/* Do the removal */
|
/* Do the removal */
|
||||||
if (NULL == (itr->parent))
|
if (NULL == (itr->parent))
|
||||||
{
|
{
|
||||||
/* element is head of a chain */
|
/* element is head of a chain */
|
||||||
itr->h->table[itr->index] = itr->e->next;
|
itr->h->table[itr->index] = itr->e->next;
|
||||||
} else {
|
} else {
|
||||||
/* element is mid-chain */
|
/* element is mid-chain */
|
||||||
itr->parent->next = itr->e->next;
|
itr->parent->next = itr->e->next;
|
||||||
}
|
}
|
||||||
|
@ -125,19 +125,19 @@ hashtable_iterator_search(struct hashtable_itr *itr,
|
||||||
e = h->table[index];
|
e = h->table[index];
|
||||||
parent = NULL;
|
parent = NULL;
|
||||||
while (NULL != e)
|
while (NULL != e)
|
||||||
{
|
{
|
||||||
/* Check hash value to short circuit heavier comparison */
|
/* Check hash value to short circuit heavier comparison */
|
||||||
if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
|
if ((hashvalue == e->h) && (h->eqfn(k, e->k)))
|
||||||
{
|
{
|
||||||
itr->index = index;
|
itr->index = index;
|
||||||
itr->e = e;
|
itr->e = e;
|
||||||
itr->parent = parent;
|
itr->parent = parent;
|
||||||
itr->h = h;
|
itr->h = h;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
parent = e;
|
parent = e;
|
||||||
e = e->next;
|
e = e->next;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,4 +173,16 @@ hashtable_iterator_search(struct hashtable_itr *itr,
|
||||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
|
@ -18,25 +18,25 @@
|
||||||
/*! \file */
|
/*! \file */
|
||||||
|
|
||||||
/*! \page g711_page A-law and mu-law handling
|
/*! \page g711_page A-law and mu-law handling
|
||||||
Lookup tables for A-law and u-law look attractive, until you consider the impact
|
Lookup tables for A-law and u-law look attractive, until you consider the impact
|
||||||
on the CPU cache. If it causes a substantial area of your processor cache to get
|
on the CPU cache. If it causes a substantial area of your processor cache to get
|
||||||
hit too often, cache sloshing will severely slow things down. The main reason
|
hit too often, cache sloshing will severely slow things down. The main reason
|
||||||
these routines are slow in C, is the lack of direct access to the CPU's "find
|
these routines are slow in C, is the lack of direct access to the CPU's "find
|
||||||
the first 1" instruction. A little in-line assembler fixes that, and the
|
the first 1" instruction. A little in-line assembler fixes that, and the
|
||||||
conversion routines can be faster than lookup tables, in most real world usage.
|
conversion routines can be faster than lookup tables, in most real world usage.
|
||||||
A "find the first 1" instruction is available on most modern CPUs, and is a
|
A "find the first 1" instruction is available on most modern CPUs, and is a
|
||||||
much underused feature.
|
much underused feature.
|
||||||
|
|
||||||
If an assembly language method of bit searching is not available, these routines
|
If an assembly language method of bit searching is not available, these routines
|
||||||
revert to a method that can be a little slow, so the cache thrashing might not
|
revert to a method that can be a little slow, so the cache thrashing might not
|
||||||
seem so bad :(
|
seem so bad :(
|
||||||
|
|
||||||
Feel free to submit patches to add fast "find the first 1" support for your own
|
Feel free to submit patches to add fast "find the first 1" support for your own
|
||||||
favourite processor.
|
favourite processor.
|
||||||
|
|
||||||
Look up tables are used for transcoding between A-law and u-law, since it is
|
Look up tables are used for transcoding between A-law and u-law, since it is
|
||||||
difficult to achieve the precise transcoding procedure laid down in the G.711
|
difficult to achieve the precise transcoding procedure laid down in the G.711
|
||||||
specification by other means.
|
specification by other means.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(_G711_H_)
|
#if !defined(_G711_H_)
|
||||||
|
@ -50,331 +50,331 @@ extern "C" {
|
||||||
#ifndef __inline__
|
#ifndef __inline__
|
||||||
#define __inline__ __inline
|
#define __inline__ __inline
|
||||||
#endif
|
#endif
|
||||||
typedef unsigned __int8 uint8_t;
|
typedef unsigned __int8 uint8_t;
|
||||||
typedef __int16 int16_t;
|
typedef __int16 int16_t;
|
||||||
typedef __int32 int32_t;
|
typedef __int32 int32_t;
|
||||||
typedef unsigned __int16 uint16_t;
|
typedef unsigned __int16 uint16_t;
|
||||||
#else
|
#else
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__i386__)
|
#if defined(__i386__)
|
||||||
/*! \brief Find the bit position of the highest set bit in a word
|
/*! \brief Find the bit position of the highest set bit in a word
|
||||||
\param bits The word to be searched
|
\param bits The word to be searched
|
||||||
\return The bit number of the highest set bit, or -1 if the word is zero. */
|
\return The bit number of the highest set bit, or -1 if the word is zero. */
|
||||||
static __inline__ int top_bit(unsigned int bits)
|
static __inline__ int top_bit(unsigned int bits)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
__asm__ __volatile__(" movl $-1,%%edx;\n"
|
__asm__ __volatile__(" movl $-1,%%edx;\n"
|
||||||
" bsrl %%eax,%%edx;\n"
|
" bsrl %%eax,%%edx;\n"
|
||||||
: "=d" (res)
|
: "=d" (res)
|
||||||
: "a" (bits));
|
: "a" (bits));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
/*! \brief Find the bit position of the lowest set bit in a word
|
/*! \brief Find the bit position of the lowest set bit in a word
|
||||||
\param bits The word to be searched
|
\param bits The word to be searched
|
||||||
\return The bit number of the lowest set bit, or -1 if the word is zero. */
|
\return The bit number of the lowest set bit, or -1 if the word is zero. */
|
||||||
static __inline__ int bottom_bit(unsigned int bits)
|
static __inline__ int bottom_bit(unsigned int bits)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
__asm__ __volatile__(" movl $-1,%%edx;\n"
|
__asm__ __volatile__(" movl $-1,%%edx;\n"
|
||||||
" bsfl %%eax,%%edx;\n"
|
" bsfl %%eax,%%edx;\n"
|
||||||
: "=d" (res)
|
: "=d" (res)
|
||||||
: "a" (bits));
|
: "a" (bits));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
#elif defined(__x86_64__)
|
#elif defined(__x86_64__)
|
||||||
static __inline__ int top_bit(unsigned int bits)
|
static __inline__ int top_bit(unsigned int bits)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
__asm__ __volatile__(" movq $-1,%%rdx;\n"
|
__asm__ __volatile__(" movq $-1,%%rdx;\n"
|
||||||
" bsrq %%rax,%%rdx;\n"
|
" bsrq %%rax,%%rdx;\n"
|
||||||
: "=d" (res)
|
: "=d" (res)
|
||||||
: "a" (bits));
|
: "a" (bits));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
static __inline__ int bottom_bit(unsigned int bits)
|
static __inline__ int bottom_bit(unsigned int bits)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
__asm__ __volatile__(" movq $-1,%%rdx;\n"
|
__asm__ __volatile__(" movq $-1,%%rdx;\n"
|
||||||
" bsfq %%rax,%%rdx;\n"
|
" bsfq %%rax,%%rdx;\n"
|
||||||
: "=d" (res)
|
: "=d" (res)
|
||||||
: "a" (bits));
|
: "a" (bits));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
#else
|
#else
|
||||||
static __inline__ int top_bit(unsigned int bits)
|
static __inline__ int top_bit(unsigned int bits)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (bits == 0)
|
if (bits == 0)
|
||||||
return -1;
|
return -1;
|
||||||
i = 0;
|
i = 0;
|
||||||
if (bits & 0xFFFF0000)
|
if (bits & 0xFFFF0000)
|
||||||
{
|
{
|
||||||
bits &= 0xFFFF0000;
|
bits &= 0xFFFF0000;
|
||||||
i += 16;
|
i += 16;
|
||||||
}
|
}
|
||||||
if (bits & 0xFF00FF00)
|
if (bits & 0xFF00FF00)
|
||||||
{
|
{
|
||||||
bits &= 0xFF00FF00;
|
bits &= 0xFF00FF00;
|
||||||
i += 8;
|
i += 8;
|
||||||
}
|
}
|
||||||
if (bits & 0xF0F0F0F0)
|
if (bits & 0xF0F0F0F0)
|
||||||
{
|
{
|
||||||
bits &= 0xF0F0F0F0;
|
bits &= 0xF0F0F0F0;
|
||||||
i += 4;
|
i += 4;
|
||||||
}
|
}
|
||||||
if (bits & 0xCCCCCCCC)
|
if (bits & 0xCCCCCCCC)
|
||||||
{
|
{
|
||||||
bits &= 0xCCCCCCCC;
|
bits &= 0xCCCCCCCC;
|
||||||
i += 2;
|
i += 2;
|
||||||
}
|
}
|
||||||
if (bits & 0xAAAAAAAA)
|
if (bits & 0xAAAAAAAA)
|
||||||
{
|
{
|
||||||
bits &= 0xAAAAAAAA;
|
bits &= 0xAAAAAAAA;
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
static __inline__ int bottom_bit(unsigned int bits)
|
static __inline__ int bottom_bit(unsigned int bits)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (bits == 0)
|
if (bits == 0)
|
||||||
return -1;
|
return -1;
|
||||||
i = 32;
|
i = 32;
|
||||||
if (bits & 0x0000FFFF)
|
if (bits & 0x0000FFFF)
|
||||||
{
|
{
|
||||||
bits &= 0x0000FFFF;
|
bits &= 0x0000FFFF;
|
||||||
i -= 16;
|
i -= 16;
|
||||||
}
|
}
|
||||||
if (bits & 0x00FF00FF)
|
if (bits & 0x00FF00FF)
|
||||||
{
|
{
|
||||||
bits &= 0x00FF00FF;
|
bits &= 0x00FF00FF;
|
||||||
i -= 8;
|
i -= 8;
|
||||||
}
|
}
|
||||||
if (bits & 0x0F0F0F0F)
|
if (bits & 0x0F0F0F0F)
|
||||||
{
|
{
|
||||||
bits &= 0x0F0F0F0F;
|
bits &= 0x0F0F0F0F;
|
||||||
i -= 4;
|
i -= 4;
|
||||||
}
|
}
|
||||||
if (bits & 0x33333333)
|
if (bits & 0x33333333)
|
||||||
{
|
{
|
||||||
bits &= 0x33333333;
|
bits &= 0x33333333;
|
||||||
i -= 2;
|
i -= 2;
|
||||||
}
|
}
|
||||||
if (bits & 0x55555555)
|
if (bits & 0x55555555)
|
||||||
{
|
{
|
||||||
bits &= 0x55555555;
|
bits &= 0x55555555;
|
||||||
i -= 1;
|
i -= 1;
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* N.B. It is tempting to use look-up tables for A-law and u-law conversion.
|
/* N.B. It is tempting to use look-up tables for A-law and u-law conversion.
|
||||||
* However, you should consider the cache footprint.
|
* However, you should consider the cache footprint.
|
||||||
*
|
*
|
||||||
* A 64K byte table for linear to x-law and a 512 byte table for x-law to
|
* A 64K byte table for linear to x-law and a 512 byte table for x-law to
|
||||||
* linear sound like peanuts these days, and shouldn't an array lookup be
|
* linear sound like peanuts these days, and shouldn't an array lookup be
|
||||||
* real fast? No! When the cache sloshes as badly as this one will, a tight
|
* real fast? No! When the cache sloshes as badly as this one will, a tight
|
||||||
* calculation may be better. The messiest part is normally finding the
|
* calculation may be better. The messiest part is normally finding the
|
||||||
* segment, but a little inline assembly can fix that on an i386, x86_64 and
|
* segment, but a little inline assembly can fix that on an i386, x86_64 and
|
||||||
* many other modern processors.
|
* many other modern processors.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mu-law is basically as follows:
|
* Mu-law is basically as follows:
|
||||||
*
|
*
|
||||||
* Biased Linear Input Code Compressed Code
|
* Biased Linear Input Code Compressed Code
|
||||||
* ------------------------ ---------------
|
* ------------------------ ---------------
|
||||||
* 00000001wxyza 000wxyz
|
* 00000001wxyza 000wxyz
|
||||||
* 0000001wxyzab 001wxyz
|
* 0000001wxyzab 001wxyz
|
||||||
* 000001wxyzabc 010wxyz
|
* 000001wxyzabc 010wxyz
|
||||||
* 00001wxyzabcd 011wxyz
|
* 00001wxyzabcd 011wxyz
|
||||||
* 0001wxyzabcde 100wxyz
|
* 0001wxyzabcde 100wxyz
|
||||||
* 001wxyzabcdef 101wxyz
|
* 001wxyzabcdef 101wxyz
|
||||||
* 01wxyzabcdefg 110wxyz
|
* 01wxyzabcdefg 110wxyz
|
||||||
* 1wxyzabcdefgh 111wxyz
|
* 1wxyzabcdefgh 111wxyz
|
||||||
*
|
*
|
||||||
* Each biased linear code has a leading 1 which identifies the segment
|
* Each biased linear code has a leading 1 which identifies the segment
|
||||||
* number. The value of the segment number is equal to 7 minus the number
|
* number. The value of the segment number is equal to 7 minus the number
|
||||||
* of leading 0's. The quantization interval is directly available as the
|
* of leading 0's. The quantization interval is directly available as the
|
||||||
* four bits wxyz. * The trailing bits (a - h) are ignored.
|
* four bits wxyz. * The trailing bits (a - h) are ignored.
|
||||||
*
|
*
|
||||||
* Ordinarily the complement of the resulting code word is used for
|
* Ordinarily the complement of the resulting code word is used for
|
||||||
* transmission, and so the code word is complemented before it is returned.
|
* transmission, and so the code word is complemented before it is returned.
|
||||||
*
|
*
|
||||||
* For further information see John C. Bellamy's Digital Telephony, 1982,
|
* For further information see John C. Bellamy's Digital Telephony, 1982,
|
||||||
* John Wiley & Sons, pps 98-111 and 472-476.
|
* John Wiley & Sons, pps 98-111 and 472-476.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*#define ULAW_ZEROTRAP*/ /* turn on the trap as per the MIL-STD */
|
/*#define ULAW_ZEROTRAP*/ /* turn on the trap as per the MIL-STD */
|
||||||
#define ULAW_BIAS 0x84 /* Bias for linear code. */
|
#define ULAW_BIAS 0x84 /* Bias for linear code. */
|
||||||
|
|
||||||
/*! \brief Encode a linear sample to u-law
|
/*! \brief Encode a linear sample to u-law
|
||||||
\param linear The sample to encode.
|
\param linear The sample to encode.
|
||||||
\return The u-law value.
|
\return The u-law value.
|
||||||
*/
|
*/
|
||||||
static __inline__ uint8_t linear_to_ulaw(int linear)
|
static __inline__ uint8_t linear_to_ulaw(int linear)
|
||||||
{
|
{
|
||||||
uint8_t u_val;
|
uint8_t u_val;
|
||||||
int mask;
|
int mask;
|
||||||
int seg;
|
int seg;
|
||||||
|
|
||||||
/* Get the sign and the magnitude of the value. */
|
/* Get the sign and the magnitude of the value. */
|
||||||
if (linear < 0)
|
if (linear < 0)
|
||||||
{
|
{
|
||||||
linear = ULAW_BIAS - linear;
|
linear = ULAW_BIAS - linear;
|
||||||
mask = 0x7F;
|
mask = 0x7F;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
linear = ULAW_BIAS + linear;
|
linear = ULAW_BIAS + linear;
|
||||||
mask = 0xFF;
|
mask = 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
seg = top_bit(linear | 0xFF) - 7;
|
seg = top_bit(linear | 0xFF) - 7;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Combine the sign, segment, quantization bits,
|
* Combine the sign, segment, quantization bits,
|
||||||
* and complement the code word.
|
* and complement the code word.
|
||||||
*/
|
*/
|
||||||
if (seg >= 8)
|
if (seg >= 8)
|
||||||
u_val = (uint8_t) (0x7F ^ mask);
|
u_val = (uint8_t) (0x7F ^ mask);
|
||||||
else
|
else
|
||||||
u_val = (uint8_t) (((seg << 4) | ((linear >> (seg + 3)) & 0xF)) ^ mask);
|
u_val = (uint8_t) (((seg << 4) | ((linear >> (seg + 3)) & 0xF)) ^ mask);
|
||||||
#ifdef ULAW_ZEROTRAP
|
#ifdef ULAW_ZEROTRAP
|
||||||
/* Optional ITU trap */
|
/* Optional ITU trap */
|
||||||
if (u_val == 0)
|
if (u_val == 0)
|
||||||
u_val = 0x02;
|
u_val = 0x02;
|
||||||
#endif
|
#endif
|
||||||
return u_val;
|
return u_val;
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
/*! \brief Decode an u-law sample to a linear value.
|
/*! \brief Decode an u-law sample to a linear value.
|
||||||
\param ulaw The u-law sample to decode.
|
\param ulaw The u-law sample to decode.
|
||||||
\return The linear value.
|
\return The linear value.
|
||||||
*/
|
*/
|
||||||
static __inline__ int16_t ulaw_to_linear(uint8_t ulaw)
|
static __inline__ int16_t ulaw_to_linear(uint8_t ulaw)
|
||||||
{
|
{
|
||||||
int t;
|
int t;
|
||||||
|
|
||||||
/* Complement to obtain normal u-law value. */
|
/* Complement to obtain normal u-law value. */
|
||||||
ulaw = ~ulaw;
|
ulaw = ~ulaw;
|
||||||
/*
|
/*
|
||||||
* Extract and bias the quantization bits. Then
|
* Extract and bias the quantization bits. Then
|
||||||
* shift up by the segment number and subtract out the bias.
|
* shift up by the segment number and subtract out the bias.
|
||||||
*/
|
*/
|
||||||
t = (((ulaw & 0x0F) << 3) + ULAW_BIAS) << (((int) ulaw & 0x70) >> 4);
|
t = (((ulaw & 0x0F) << 3) + ULAW_BIAS) << (((int) ulaw & 0x70) >> 4);
|
||||||
return (int16_t) ((ulaw & 0x80) ? (ULAW_BIAS - t) : (t - ULAW_BIAS));
|
return (int16_t) ((ulaw & 0x80) ? (ULAW_BIAS - t) : (t - ULAW_BIAS));
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A-law is basically as follows:
|
* A-law is basically as follows:
|
||||||
*
|
*
|
||||||
* Linear Input Code Compressed Code
|
* Linear Input Code Compressed Code
|
||||||
* ----------------- ---------------
|
* ----------------- ---------------
|
||||||
* 0000000wxyza 000wxyz
|
* 0000000wxyza 000wxyz
|
||||||
* 0000001wxyza 001wxyz
|
* 0000001wxyza 001wxyz
|
||||||
* 000001wxyzab 010wxyz
|
* 000001wxyzab 010wxyz
|
||||||
* 00001wxyzabc 011wxyz
|
* 00001wxyzabc 011wxyz
|
||||||
* 0001wxyzabcd 100wxyz
|
* 0001wxyzabcd 100wxyz
|
||||||
* 001wxyzabcde 101wxyz
|
* 001wxyzabcde 101wxyz
|
||||||
* 01wxyzabcdef 110wxyz
|
* 01wxyzabcdef 110wxyz
|
||||||
* 1wxyzabcdefg 111wxyz
|
* 1wxyzabcdefg 111wxyz
|
||||||
*
|
*
|
||||||
* For further information see John C. Bellamy's Digital Telephony, 1982,
|
* For further information see John C. Bellamy's Digital Telephony, 1982,
|
||||||
* John Wiley & Sons, pps 98-111 and 472-476.
|
* John Wiley & Sons, pps 98-111 and 472-476.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define ALAW_AMI_MASK 0x55
|
#define ALAW_AMI_MASK 0x55
|
||||||
|
|
||||||
/*! \brief Encode a linear sample to A-law
|
/*! \brief Encode a linear sample to A-law
|
||||||
\param linear The sample to encode.
|
\param linear The sample to encode.
|
||||||
\return The A-law value.
|
\return The A-law value.
|
||||||
*/
|
*/
|
||||||
static __inline__ uint8_t linear_to_alaw(int linear)
|
static __inline__ uint8_t linear_to_alaw(int linear)
|
||||||
{
|
{
|
||||||
int mask;
|
int mask;
|
||||||
int seg;
|
int seg;
|
||||||
|
|
||||||
if (linear >= 0)
|
if (linear >= 0)
|
||||||
{
|
{
|
||||||
/* Sign (bit 7) bit = 1 */
|
/* Sign (bit 7) bit = 1 */
|
||||||
mask = ALAW_AMI_MASK | 0x80;
|
mask = ALAW_AMI_MASK | 0x80;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Sign (bit 7) bit = 0 */
|
/* Sign (bit 7) bit = 0 */
|
||||||
mask = ALAW_AMI_MASK;
|
mask = ALAW_AMI_MASK;
|
||||||
linear = -linear - 8;
|
linear = -linear - 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert the scaled magnitude to segment number. */
|
/* Convert the scaled magnitude to segment number. */
|
||||||
seg = top_bit(linear | 0xFF) - 7;
|
seg = top_bit(linear | 0xFF) - 7;
|
||||||
if (seg >= 8)
|
if (seg >= 8)
|
||||||
{
|
{
|
||||||
if (linear >= 0)
|
if (linear >= 0)
|
||||||
{
|
{
|
||||||
/* Out of range. Return maximum value. */
|
/* Out of range. Return maximum value. */
|
||||||
return (uint8_t) (0x7F ^ mask);
|
return (uint8_t) (0x7F ^ mask);
|
||||||
}
|
}
|
||||||
/* We must be just a tiny step below zero */
|
/* We must be just a tiny step below zero */
|
||||||
return (uint8_t) (0x00 ^ mask);
|
return (uint8_t) (0x00 ^ mask);
|
||||||
}
|
}
|
||||||
/* Combine the sign, segment, and quantization bits. */
|
/* Combine the sign, segment, and quantization bits. */
|
||||||
return (uint8_t) (((seg << 4) | ((linear >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^ mask);
|
return (uint8_t) (((seg << 4) | ((linear >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^ mask);
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
/*! \brief Decode an A-law sample to a linear value.
|
/*! \brief Decode an A-law sample to a linear value.
|
||||||
\param alaw The A-law sample to decode.
|
\param alaw The A-law sample to decode.
|
||||||
\return The linear value.
|
\return The linear value.
|
||||||
*/
|
*/
|
||||||
static __inline__ int16_t alaw_to_linear(uint8_t alaw)
|
static __inline__ int16_t alaw_to_linear(uint8_t alaw)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int seg;
|
int seg;
|
||||||
|
|
||||||
alaw ^= ALAW_AMI_MASK;
|
alaw ^= ALAW_AMI_MASK;
|
||||||
i = ((alaw & 0x0F) << 4);
|
i = ((alaw & 0x0F) << 4);
|
||||||
seg = (((int) alaw & 0x70) >> 4);
|
seg = (((int) alaw & 0x70) >> 4);
|
||||||
if (seg)
|
if (seg)
|
||||||
i = (i + 0x108) << (seg - 1);
|
i = (i + 0x108) << (seg - 1);
|
||||||
else
|
else
|
||||||
i += 8;
|
i += 8;
|
||||||
return (int16_t) ((alaw & 0x80) ? i : -i);
|
return (int16_t) ((alaw & 0x80) ? i : -i);
|
||||||
}
|
}
|
||||||
/*- End of function --------------------------------------------------------*/
|
/*- End of function --------------------------------------------------------*/
|
||||||
|
|
||||||
/*! \brief Transcode from A-law to u-law, using the procedure defined in G.711.
|
/*! \brief Transcode from A-law to u-law, using the procedure defined in G.711.
|
||||||
\param alaw The A-law sample to transcode.
|
\param alaw The A-law sample to transcode.
|
||||||
\return The best matching u-law value.
|
\return The best matching u-law value.
|
||||||
*/
|
*/
|
||||||
uint8_t alaw_to_ulaw(uint8_t alaw);
|
uint8_t alaw_to_ulaw(uint8_t alaw);
|
||||||
|
|
||||||
/*! \brief Transcode from u-law to A-law, using the procedure defined in G.711.
|
/*! \brief Transcode from u-law to A-law, using the procedure defined in G.711.
|
||||||
\param alaw The u-law sample to transcode.
|
\param alaw The u-law sample to transcode.
|
||||||
\return The best matching A-law value.
|
\return The best matching A-law value.
|
||||||
*/
|
*/
|
||||||
uint8_t ulaw_to_alaw(uint8_t ulaw);
|
uint8_t ulaw_to_alaw(uint8_t ulaw);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -382,3 +382,14 @@ uint8_t ulaw_to_alaw(uint8_t ulaw);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
/*- End of file ------------------------------------------------------------*/
|
/*- End of file ------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
|
@ -103,11 +103,11 @@ create_hashtable(unsigned int minsize,
|
||||||
int
|
int
|
||||||
hashtable_insert(struct hashtable *h, void *k, void *v);
|
hashtable_insert(struct hashtable *h, void *k, void *v);
|
||||||
|
|
||||||
#define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
|
#define DEFINE_HASHTABLE_INSERT(fnname, keytype, valuetype) \
|
||||||
int fnname (struct hashtable *h, keytype *k, valuetype *v) \
|
int fnname (struct hashtable *h, keytype *k, valuetype *v) \
|
||||||
{ \
|
{ \
|
||||||
return hashtable_insert(h,k,v); \
|
return hashtable_insert(h,k,v); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* hashtable_search
|
* hashtable_search
|
||||||
|
@ -122,10 +122,10 @@ void *
|
||||||
hashtable_search(struct hashtable *h, void *k);
|
hashtable_search(struct hashtable *h, void *k);
|
||||||
|
|
||||||
#define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
|
#define DEFINE_HASHTABLE_SEARCH(fnname, keytype, valuetype) \
|
||||||
valuetype * fnname (struct hashtable *h, keytype *k) \
|
valuetype * fnname (struct hashtable *h, keytype *k) \
|
||||||
{ \
|
{ \
|
||||||
return (valuetype *) (hashtable_search(h,k)); \
|
return (valuetype *) (hashtable_search(h,k)); \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* hashtable_remove
|
* hashtable_remove
|
||||||
|
@ -140,10 +140,10 @@ void * /* returns value */
|
||||||
hashtable_remove(struct hashtable *h, void *k);
|
hashtable_remove(struct hashtable *h, void *k);
|
||||||
|
|
||||||
#define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
|
#define DEFINE_HASHTABLE_REMOVE(fnname, keytype, valuetype) \
|
||||||
valuetype * fnname (struct hashtable *h, keytype *k) \
|
valuetype * fnname (struct hashtable *h, keytype *k) \
|
||||||
{ \
|
{ \
|
||||||
return (valuetype *) (hashtable_remove(h,k)); \
|
return (valuetype *) (hashtable_remove(h,k)); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
|
@ -201,4 +201,15 @@ hashtable_destroy(struct hashtable *h, int free_keys, int free_values);
|
||||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
|
@ -62,17 +62,17 @@ hashtable_iterator_remove(struct hashtable_itr *itr);
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* search - overwrite the supplied iterator, to point to the entry
|
/* search - overwrite the supplied iterator, to point to the entry
|
||||||
* matching the supplied key.
|
* matching the supplied key.
|
||||||
h points to the hashtable to be searched.
|
h points to the hashtable to be searched.
|
||||||
* returns zero if not found. */
|
* returns zero if not found. */
|
||||||
int
|
int
|
||||||
hashtable_iterator_search(struct hashtable_itr *itr,
|
hashtable_iterator_search(struct hashtable_itr *itr,
|
||||||
struct hashtable *h, void *k);
|
struct hashtable *h, void *k);
|
||||||
|
|
||||||
#define DEFINE_HASHTABLE_ITERATOR_SEARCH(fnname, keytype) \
|
#define DEFINE_HASHTABLE_ITERATOR_SEARCH(fnname, keytype) \
|
||||||
int fnname (struct hashtable_itr *i, struct hashtable *h, keytype *k) \
|
int fnname (struct hashtable_itr *i, struct hashtable *h, keytype *k) \
|
||||||
{ \
|
{ \
|
||||||
return (hashtable_iterator_search(i,h,k)); \
|
return (hashtable_iterator_search(i,h,k)); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -109,4 +109,16 @@ int fnname (struct hashtable_itr *i, struct hashtable *h, keytype *k) \
|
||||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
|
@ -37,10 +37,10 @@ indexFor(unsigned int tablelength, unsigned int hashvalue) {
|
||||||
|
|
||||||
/* Only works if tablelength == 2^N */
|
/* Only works if tablelength == 2^N */
|
||||||
/*static inline unsigned int
|
/*static inline unsigned int
|
||||||
indexFor(unsigned int tablelength, unsigned int hashvalue)
|
indexFor(unsigned int tablelength, unsigned int hashvalue)
|
||||||
{
|
{
|
||||||
return (hashvalue & (tablelength - 1u));
|
return (hashvalue & (tablelength - 1u));
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -83,4 +83,14 @@ indexFor(unsigned int tablelength, unsigned int hashvalue)
|
||||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
|
@ -78,27 +78,27 @@ extern "C" {
|
||||||
#define TELETONE_MAX_TONES 6
|
#define TELETONE_MAX_TONES 6
|
||||||
#define TELETONE_TONE_RANGE 127
|
#define TELETONE_TONE_RANGE 127
|
||||||
|
|
||||||
typedef double teletone_process_t;
|
typedef double teletone_process_t;
|
||||||
|
|
||||||
/*! \file libteletone.h
|
/*! \file libteletone.h
|
||||||
\brief Top level include file
|
\brief Top level include file
|
||||||
|
|
||||||
This file should be included by applications using the library
|
This file should be included by applications using the library
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*! \brief An abstraction to store a tone mapping */
|
/*! \brief An abstraction to store a tone mapping */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/*! An array of tone frequencies */
|
/*! An array of tone frequencies */
|
||||||
teletone_process_t freqs[TELETONE_MAX_TONES];
|
teletone_process_t freqs[TELETONE_MAX_TONES];
|
||||||
} teletone_tone_map_t;
|
} teletone_tone_map_t;
|
||||||
|
|
||||||
#if !defined(M_PI)
|
#if !defined(M_PI)
|
||||||
/* C99 systems may not define M_PI */
|
/* C99 systems may not define M_PI */
|
||||||
#define M_PI 3.14159265358979323846264338327
|
#define M_PI 3.14159265358979323846264338327
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
typedef __int16 int16_t;
|
typedef __int16 int16_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <libteletone_generate.h>
|
#include <libteletone_generate.h>
|
||||||
|
|
|
@ -98,11 +98,11 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
#include <libteletone.h>
|
#include <libteletone.h>
|
||||||
|
|
||||||
/*! \file libteletone_detect.h
|
/*! \file libteletone_detect.h
|
||||||
\brief Tone Detection Routines
|
\brief Tone Detection Routines
|
||||||
|
|
||||||
This module is responsible for tone detection specifics
|
This module is responsible for tone detection specifics
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef FALSE
|
#ifndef FALSE
|
||||||
#define FALSE 0
|
#define FALSE 0
|
||||||
|
@ -111,17 +111,17 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Basic DTMF specs:
|
/* Basic DTMF specs:
|
||||||
*
|
*
|
||||||
* Minimum tone on = 40ms
|
* Minimum tone on = 40ms
|
||||||
* Minimum tone off = 50ms
|
* Minimum tone off = 50ms
|
||||||
* Maximum digit rate = 10 per second
|
* Maximum digit rate = 10 per second
|
||||||
* Normal twist <= 8dB accepted
|
* Normal twist <= 8dB accepted
|
||||||
* Reverse twist <= 4dB accepted
|
* Reverse twist <= 4dB accepted
|
||||||
* S/N >= 15dB will detect OK
|
* S/N >= 15dB will detect OK
|
||||||
* Attenuation <= 26dB will detect OK
|
* Attenuation <= 26dB will detect OK
|
||||||
* Frequency tolerance +- 1.5% will detect, +-3.5% will reject
|
* Frequency tolerance +- 1.5% will detect, +-3.5% will reject
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define DTMF_THRESHOLD 8.0e7
|
#define DTMF_THRESHOLD 8.0e7
|
||||||
#define DTMF_NORMAL_TWIST 6.3 /* 8dB */
|
#define DTMF_NORMAL_TWIST 6.3 /* 8dB */
|
||||||
|
@ -134,131 +134,131 @@ extern "C" {
|
||||||
#define BLOCK_LEN 102
|
#define BLOCK_LEN 102
|
||||||
#define M_TWO_PI 2.0*M_PI
|
#define M_TWO_PI 2.0*M_PI
|
||||||
|
|
||||||
/*! \brief A continer for the elements of a Goertzel Algorithm (The names are from his formula) */
|
/*! \brief A continer for the elements of a Goertzel Algorithm (The names are from his formula) */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
teletone_process_t v2;
|
teletone_process_t v2;
|
||||||
teletone_process_t v3;
|
teletone_process_t v3;
|
||||||
teletone_process_t fac;
|
teletone_process_t fac;
|
||||||
} teletone_goertzel_state_t;
|
} teletone_goertzel_state_t;
|
||||||
|
|
||||||
/*! \brief A container for a DTMF detection state.*/
|
/*! \brief A container for a DTMF detection state.*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int hit1;
|
int hit1;
|
||||||
int hit2;
|
int hit2;
|
||||||
int hit3;
|
int hit3;
|
||||||
int hit4;
|
int hit4;
|
||||||
int mhit;
|
int mhit;
|
||||||
|
|
||||||
teletone_goertzel_state_t row_out[GRID_FACTOR];
|
teletone_goertzel_state_t row_out[GRID_FACTOR];
|
||||||
teletone_goertzel_state_t col_out[GRID_FACTOR];
|
teletone_goertzel_state_t col_out[GRID_FACTOR];
|
||||||
teletone_goertzel_state_t row_out2nd[GRID_FACTOR];
|
teletone_goertzel_state_t row_out2nd[GRID_FACTOR];
|
||||||
teletone_goertzel_state_t col_out2nd[GRID_FACTOR];
|
teletone_goertzel_state_t col_out2nd[GRID_FACTOR];
|
||||||
teletone_process_t energy;
|
teletone_process_t energy;
|
||||||
|
|
||||||
int current_sample;
|
int current_sample;
|
||||||
char digits[TELETONE_MAX_DTMF_DIGITS + 1];
|
char digits[TELETONE_MAX_DTMF_DIGITS + 1];
|
||||||
int current_digits;
|
int current_digits;
|
||||||
int detected_digits;
|
int detected_digits;
|
||||||
int lost_digits;
|
int lost_digits;
|
||||||
int digit_hits[16];
|
int digit_hits[16];
|
||||||
} teletone_dtmf_detect_state_t;
|
} teletone_dtmf_detect_state_t;
|
||||||
|
|
||||||
/*! \brief An abstraction to store the coefficient of a tone frequency */
|
/*! \brief An abstraction to store the coefficient of a tone frequency */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
teletone_process_t fac;
|
teletone_process_t fac;
|
||||||
} teletone_detection_descriptor_t;
|
} teletone_detection_descriptor_t;
|
||||||
|
|
||||||
/*! \brief A container for a single multi-tone detection
|
/*! \brief A container for a single multi-tone detection
|
||||||
TELETONE_MAX_TONES dictates the maximum simultaneous tones that can be present
|
TELETONE_MAX_TONES dictates the maximum simultaneous tones that can be present
|
||||||
in a multi-tone representation.
|
in a multi-tone representation.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int sample_rate;
|
int sample_rate;
|
||||||
|
|
||||||
teletone_detection_descriptor_t tdd[TELETONE_MAX_TONES];
|
teletone_detection_descriptor_t tdd[TELETONE_MAX_TONES];
|
||||||
teletone_goertzel_state_t gs[TELETONE_MAX_TONES];
|
teletone_goertzel_state_t gs[TELETONE_MAX_TONES];
|
||||||
teletone_goertzel_state_t gs2[TELETONE_MAX_TONES];
|
teletone_goertzel_state_t gs2[TELETONE_MAX_TONES];
|
||||||
int tone_count;
|
int tone_count;
|
||||||
|
|
||||||
teletone_process_t energy;
|
teletone_process_t energy;
|
||||||
int current_sample;
|
int current_sample;
|
||||||
|
|
||||||
int min_samples;
|
int min_samples;
|
||||||
int total_samples;
|
int total_samples;
|
||||||
|
|
||||||
int positives;
|
int positives;
|
||||||
int negatives;
|
int negatives;
|
||||||
int hits;
|
int hits;
|
||||||
|
|
||||||
int positive_factor;
|
int positive_factor;
|
||||||
int negative_factor;
|
int negative_factor;
|
||||||
int hit_factor;
|
int hit_factor;
|
||||||
|
|
||||||
} teletone_multi_tone_t;
|
} teletone_multi_tone_t;
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Initilize a multi-frequency tone detector
|
\brief Initilize a multi-frequency tone detector
|
||||||
\param mt the multi-frequency tone descriptor
|
\param mt the multi-frequency tone descriptor
|
||||||
\param map a representation of the multi-frequency tone
|
\param map a representation of the multi-frequency tone
|
||||||
*/
|
*/
|
||||||
void teletone_multi_tone_init(teletone_multi_tone_t *mt, teletone_tone_map_t *map);
|
void teletone_multi_tone_init(teletone_multi_tone_t *mt, teletone_tone_map_t *map);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Check a sample buffer for the presence of the mulit-frequency tone described by mt
|
\brief Check a sample buffer for the presence of the mulit-frequency tone described by mt
|
||||||
\param mt the multi-frequency tone descriptor
|
\param mt the multi-frequency tone descriptor
|
||||||
\param sample_buffer an array aof 16 bit signed linear samples
|
\param sample_buffer an array aof 16 bit signed linear samples
|
||||||
\param samples the number of samples present in sample_buffer
|
\param samples the number of samples present in sample_buffer
|
||||||
\return true when the tone was detected or false when it is not
|
\return true when the tone was detected or false when it is not
|
||||||
*/
|
*/
|
||||||
int teletone_multi_tone_detect (teletone_multi_tone_t *mt,
|
int teletone_multi_tone_detect (teletone_multi_tone_t *mt,
|
||||||
int16_t sample_buffer[],
|
int16_t sample_buffer[],
|
||||||
int samples);
|
int samples);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Initilize a DTMF detection state object
|
\brief Initilize a DTMF detection state object
|
||||||
\param dtmf_detect_state the DTMF detection state to initilize
|
\param dtmf_detect_state the DTMF detection state to initilize
|
||||||
\param sample_rate the desired sample rate
|
\param sample_rate the desired sample rate
|
||||||
*/
|
*/
|
||||||
void teletone_dtmf_detect_init (teletone_dtmf_detect_state_t *dtmf_detect_state, int sample_rate);
|
void teletone_dtmf_detect_init (teletone_dtmf_detect_state_t *dtmf_detect_state, int sample_rate);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Check a sample buffer for the presence of DTMF digits
|
\brief Check a sample buffer for the presence of DTMF digits
|
||||||
\param dtmf_detect_state the detection state object to check
|
\param dtmf_detect_state the detection state object to check
|
||||||
\param sample_buffer an array aof 16 bit signed linear samples
|
\param sample_buffer an array aof 16 bit signed linear samples
|
||||||
\param samples the number of samples present in sample_buffer
|
\param samples the number of samples present in sample_buffer
|
||||||
\return true when DTMF was detected or false when it is not
|
\return true when DTMF was detected or false when it is not
|
||||||
*/
|
*/
|
||||||
int teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
int teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||||
int16_t sample_buffer[],
|
|
||||||
int samples);
|
|
||||||
/*!
|
|
||||||
\brief retrieve any collected digits into a string buffer
|
|
||||||
\param dtmf_detect_state the detection state object to check
|
|
||||||
\param buf the string buffer to write to
|
|
||||||
\param max the maximum length of buf
|
|
||||||
\return the number of characters written to buf
|
|
||||||
*/
|
|
||||||
int teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
|
||||||
char *buf,
|
|
||||||
int max);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\brief Step through the Goertzel Algorithm for each sample in a buffer
|
|
||||||
\param goertzel_state the goertzel state to step the samples through
|
|
||||||
\param sample_buffer an array aof 16 bit signed linear samples
|
|
||||||
\param samples the number of samples present in sample_buffer
|
|
||||||
*/
|
|
||||||
void teletone_goertzel_update(teletone_goertzel_state_t *goertzel_state,
|
|
||||||
int16_t sample_buffer[],
|
int16_t sample_buffer[],
|
||||||
int samples);
|
int samples);
|
||||||
|
/*!
|
||||||
|
\brief retrieve any collected digits into a string buffer
|
||||||
|
\param dtmf_detect_state the detection state object to check
|
||||||
|
\param buf the string buffer to write to
|
||||||
|
\param max the maximum length of buf
|
||||||
|
\return the number of characters written to buf
|
||||||
|
*/
|
||||||
|
int teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||||
|
char *buf,
|
||||||
|
int max);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Compute the result of the last applied step of the Goertzel Algorithm
|
\brief Step through the Goertzel Algorithm for each sample in a buffer
|
||||||
\param goertzel_state the goertzel state to retrieve from
|
\param goertzel_state the goertzel state to step the samples through
|
||||||
\return the computed value for consideration in furthur audio tests
|
\param sample_buffer an array aof 16 bit signed linear samples
|
||||||
*/
|
\param samples the number of samples present in sample_buffer
|
||||||
teletone_process_t teletone_goertzel_result (teletone_goertzel_state_t *goertzel_state);
|
*/
|
||||||
|
void teletone_goertzel_update(teletone_goertzel_state_t *goertzel_state,
|
||||||
|
int16_t sample_buffer[],
|
||||||
|
int samples);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Compute the result of the last applied step of the Goertzel Algorithm
|
||||||
|
\param goertzel_state the goertzel state to retrieve from
|
||||||
|
\return the computed value for consideration in furthur audio tests
|
||||||
|
*/
|
||||||
|
teletone_process_t teletone_goertzel_result (teletone_goertzel_state_t *goertzel_state);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -89,113 +89,113 @@ extern "C" {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*! \file libteletone_generate.h
|
/*! \file libteletone_generate.h
|
||||||
\brief Tone Generation Routines
|
\brief Tone Generation Routines
|
||||||
|
|
||||||
This module is responsible for tone generation specifics
|
This module is responsible for tone generation specifics
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef int16_t teletone_audio_t;
|
typedef int16_t teletone_audio_t;
|
||||||
struct teletone_generation_session;
|
struct teletone_generation_session;
|
||||||
typedef int (*tone_handler)(struct teletone_generation_session *ts, teletone_tone_map_t *map);
|
typedef int (*tone_handler)(struct teletone_generation_session *ts, teletone_tone_map_t *map);
|
||||||
|
|
||||||
/*! \brief An abstraction to store a tone generation session */
|
/*! \brief An abstraction to store a tone generation session */
|
||||||
struct teletone_generation_session {
|
struct teletone_generation_session {
|
||||||
/*! An array of tone mappings to character mappings */
|
/*! An array of tone mappings to character mappings */
|
||||||
teletone_tone_map_t TONES[TELETONE_TONE_RANGE];
|
teletone_tone_map_t TONES[TELETONE_TONE_RANGE];
|
||||||
/*! The number of channels the output audio should be in */
|
/*! The number of channels the output audio should be in */
|
||||||
int channels;
|
int channels;
|
||||||
/*! The Rate in hz of the output audio */
|
/*! The Rate in hz of the output audio */
|
||||||
int rate;
|
int rate;
|
||||||
/*! The duration (in samples) of the output audio */
|
/*! The duration (in samples) of the output audio */
|
||||||
int duration;
|
int duration;
|
||||||
/*! The duration of silence to append after the initial audio is generated */
|
/*! The duration of silence to append after the initial audio is generated */
|
||||||
int wait;
|
int wait;
|
||||||
/*! The duration (in samples) of the output audio (takes prescedence over actual duration value) */
|
/*! The duration (in samples) of the output audio (takes prescedence over actual duration value) */
|
||||||
int tmp_duration;
|
int tmp_duration;
|
||||||
/*! The duration of silence to append after the initial audio is generated (takes prescedence over actual wait value)*/
|
/*! The duration of silence to append after the initial audio is generated (takes prescedence over actual wait value)*/
|
||||||
int tmp_wait;
|
int tmp_wait;
|
||||||
/*! Number of loops to repeat a single instruction*/
|
/*! Number of loops to repeat a single instruction*/
|
||||||
int loops;
|
int loops;
|
||||||
/*! Number of loops to repeat the entire set of instructions*/
|
/*! Number of loops to repeat the entire set of instructions*/
|
||||||
int LOOPS;
|
int LOOPS;
|
||||||
/*! Number to mutiply total samples by to determine when to begin ascent or decent e.g. 0=beginning 4=(last 25%) */
|
/*! Number to mutiply total samples by to determine when to begin ascent or decent e.g. 0=beginning 4=(last 25%) */
|
||||||
int decay_factor;
|
int decay_factor;
|
||||||
/*! Direction to perform volume increase/decrease 1/-1*/
|
/*! Direction to perform volume increase/decrease 1/-1*/
|
||||||
int decay_direction;
|
int decay_direction;
|
||||||
/*! Number of samples between increase/decrease of volume */
|
/*! Number of samples between increase/decrease of volume */
|
||||||
int decay_step;
|
int decay_step;
|
||||||
/*! Volume factor of the tone */
|
/*! Volume factor of the tone */
|
||||||
int volume;
|
int volume;
|
||||||
/*! Debug on/off */
|
/*! Debug on/off */
|
||||||
int debug;
|
int debug;
|
||||||
/*! FILE stream to write debug data to */
|
/*! FILE stream to write debug data to */
|
||||||
FILE *debug_stream;
|
FILE *debug_stream;
|
||||||
/*! Extra user data to attach to the session*/
|
/*! Extra user data to attach to the session*/
|
||||||
void *user_data;
|
void *user_data;
|
||||||
/*! Buffer for storing sample data (dynamic) */
|
/*! Buffer for storing sample data (dynamic) */
|
||||||
teletone_audio_t *buffer;
|
teletone_audio_t *buffer;
|
||||||
/*! Size of the buffer */
|
/*! Size of the buffer */
|
||||||
int datalen;
|
int datalen;
|
||||||
/*! In-Use size of the buffer */
|
/*! In-Use size of the buffer */
|
||||||
int samples;
|
int samples;
|
||||||
/*! Callback function called during generation */
|
/*! Callback function called during generation */
|
||||||
int dynamic;
|
int dynamic;
|
||||||
tone_handler handler;
|
tone_handler handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct teletone_generation_session teletone_generation_session_t;
|
typedef struct teletone_generation_session teletone_generation_session_t;
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Assign a set of tones to a tone_session indexed by a paticular index/character
|
\brief Assign a set of tones to a tone_session indexed by a paticular index/character
|
||||||
\param ts the tone generation session
|
\param ts the tone generation session
|
||||||
\param index the index to map the tone to
|
\param index the index to map the tone to
|
||||||
\param ... up to TELETONE_MAX_TONES frequencies terminated by 0.0
|
\param ... up to TELETONE_MAX_TONES frequencies terminated by 0.0
|
||||||
\return 0
|
\return 0
|
||||||
*/
|
*/
|
||||||
int teletone_set_tone(teletone_generation_session_t *ts, int index, ...);
|
int teletone_set_tone(teletone_generation_session_t *ts, int index, ...);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Assign a set of tones to a single tone map
|
\brief Assign a set of tones to a single tone map
|
||||||
\param map the map to assign the tones to
|
\param map the map to assign the tones to
|
||||||
\param ... up to TELETONE_MAX_TONES frequencies terminated by 0.0
|
\param ... up to TELETONE_MAX_TONES frequencies terminated by 0.0
|
||||||
\return 0
|
\return 0
|
||||||
*/
|
*/
|
||||||
int teletone_set_map(teletone_tone_map_t *map, ...);
|
int teletone_set_map(teletone_tone_map_t *map, ...);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Initilize a tone generation session
|
\brief Initilize a tone generation session
|
||||||
\param ts the tone generation session to initilize
|
\param ts the tone generation session to initilize
|
||||||
\param buflen the size of the buffer(in samples) to dynamically allocate
|
\param buflen the size of the buffer(in samples) to dynamically allocate
|
||||||
\param handler a callback function to execute when a tone generation instruction is complete
|
\param handler a callback function to execute when a tone generation instruction is complete
|
||||||
\param user_data optional user data to send
|
\param user_data optional user data to send
|
||||||
\return 0
|
\return 0
|
||||||
*/
|
*/
|
||||||
int teletone_init_session(teletone_generation_session_t *ts, int buflen, tone_handler handler, void *user_data);
|
int teletone_init_session(teletone_generation_session_t *ts, int buflen, tone_handler handler, void *user_data);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Free the buffer allocated by a tone generation session
|
\brief Free the buffer allocated by a tone generation session
|
||||||
\param ts the tone generation session to destroy
|
\param ts the tone generation session to destroy
|
||||||
\return 0
|
\return 0
|
||||||
*/
|
*/
|
||||||
int teletone_destroy_session(teletone_generation_session_t *ts);
|
int teletone_destroy_session(teletone_generation_session_t *ts);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Execute a single tone generation instruction
|
\brief Execute a single tone generation instruction
|
||||||
\param ts the tone generation session to consult for parameters
|
\param ts the tone generation session to consult for parameters
|
||||||
\param map the tone mapping to use for the frequencies
|
\param map the tone mapping to use for the frequencies
|
||||||
\return 0
|
\return 0
|
||||||
*/
|
*/
|
||||||
int teletone_mux_tones(teletone_generation_session_t *ts, teletone_tone_map_t *map);
|
int teletone_mux_tones(teletone_generation_session_t *ts, teletone_tone_map_t *map);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Execute a tone generation script and call callbacks after each instruction
|
\brief Execute a tone generation script and call callbacks after each instruction
|
||||||
\param ts the tone generation session to execute on
|
\param ts the tone generation session to execute on
|
||||||
\param cmd the script to execute
|
\param cmd the script to execute
|
||||||
\return 0
|
\return 0
|
||||||
*/
|
*/
|
||||||
int teletone_run(teletone_generation_session_t *ts, char *cmd);
|
int teletone_run(teletone_generation_session_t *ts, char *cmd);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,8 +189,8 @@
|
||||||
|
|
||||||
#define zap_clear_flag_locked(obj, flag) assert(obj->mutex != NULL); zap_mutex_lock(obj->mutex); (obj)->flags &= ~(flag); zap_mutex_unlock(obj->mutex);
|
#define zap_clear_flag_locked(obj, flag) assert(obj->mutex != NULL); zap_mutex_lock(obj->mutex); (obj)->flags &= ~(flag); zap_mutex_unlock(obj->mutex);
|
||||||
|
|
||||||
#define zap_set_state_locked(obj, s) assert(obj->mutex != NULL); zap_mutex_lock(obj->mutex);\
|
#define zap_set_state_locked(obj, s) assert(obj->mutex != NULL); zap_mutex_lock(obj->mutex); \
|
||||||
zap_log(ZAP_LOG_DEBUG, "Changing state from %s to %s\n", zap_channel_state2str(obj->state), zap_channel_state2str(s));\
|
zap_log(ZAP_LOG_DEBUG, "Changing state from %s to %s\n", zap_channel_state2str(obj->state), zap_channel_state2str(s)); \
|
||||||
zap_channel_set_state(obj, s);
|
zap_channel_set_state(obj, s);
|
||||||
|
|
||||||
|
|
||||||
|
@ -235,6 +235,8 @@ struct zap_caller_data {
|
||||||
struct zap_channel {
|
struct zap_channel {
|
||||||
uint32_t span_id;
|
uint32_t span_id;
|
||||||
uint32_t chan_id;
|
uint32_t chan_id;
|
||||||
|
uint32_t physical_span_id;
|
||||||
|
uint32_t physical_chan_id;
|
||||||
zap_chan_type_t type;
|
zap_chan_type_t type;
|
||||||
zap_socket_t sockfd;
|
zap_socket_t sockfd;
|
||||||
zap_channel_flag_t flags;
|
zap_channel_flag_t flags;
|
||||||
|
@ -264,10 +266,10 @@ struct zap_channel {
|
||||||
uint8_t needed_tones[ZAP_TONEMAP_INVALID];
|
uint8_t needed_tones[ZAP_TONEMAP_INVALID];
|
||||||
uint8_t detected_tones[ZAP_TONEMAP_INVALID];
|
uint8_t detected_tones[ZAP_TONEMAP_INVALID];
|
||||||
zap_tonemap_t last_detected_tone;
|
zap_tonemap_t last_detected_tone;
|
||||||
|
|
||||||
uint32_t token_count;
|
uint32_t token_count;
|
||||||
char chan_name[128];
|
char chan_name[128];
|
||||||
char chan_number[32];
|
char chan_number[32];
|
||||||
|
zap_filehandle_t fds[2];
|
||||||
struct zap_caller_data caller_data;
|
struct zap_caller_data caller_data;
|
||||||
struct zap_span *span;
|
struct zap_span *span;
|
||||||
struct zap_io_interface *zio;
|
struct zap_io_interface *zio;
|
||||||
|
@ -384,3 +386,14 @@ ZIO_CODEC_FUNCTION(zio_alaw2ulaw);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
|
@ -43,10 +43,10 @@ struct iphdr {
|
||||||
|
|
||||||
#if defined(__LITTLE_ENDIAN_BITFIELD)
|
#if defined(__LITTLE_ENDIAN_BITFIELD)
|
||||||
unsigned ihl:4,
|
unsigned ihl:4,
|
||||||
version:4;
|
version:4;
|
||||||
#elif defined (__BIG_ENDIAN_BITFIELD)
|
#elif defined (__BIG_ENDIAN_BITFIELD)
|
||||||
unsigned version:4,
|
unsigned version:4,
|
||||||
ihl:4;
|
ihl:4;
|
||||||
#else
|
#else
|
||||||
# error "unknown byteorder!"
|
# error "unknown byteorder!"
|
||||||
#endif
|
#endif
|
||||||
|
@ -108,15 +108,15 @@ static __inline__ int tdmv_api_ioctl(sng_fd_t fd, wanpipe_tdm_api_t *tdm_api_cmd
|
||||||
memcpy( wan_udp.wan_udphdr_data, (void*)tdm_api_cmd, sizeof(wanpipe_tdm_api_cmd_t));
|
memcpy( wan_udp.wan_udphdr_data, (void*)tdm_api_cmd, sizeof(wanpipe_tdm_api_cmd_t));
|
||||||
|
|
||||||
if (DeviceIoControl(
|
if (DeviceIoControl(
|
||||||
fd,
|
fd,
|
||||||
IoctlManagementCommand,
|
IoctlManagementCommand,
|
||||||
(LPVOID)&wan_udp,
|
(LPVOID)&wan_udp,
|
||||||
sizeof(wan_udp_hdr_t),
|
sizeof(wan_udp_hdr_t),
|
||||||
(LPVOID)&wan_udp,
|
(LPVOID)&wan_udp,
|
||||||
sizeof(wan_udp_hdr_t),
|
sizeof(wan_udp_hdr_t),
|
||||||
(LPDWORD)(&ln),
|
(LPDWORD)(&ln),
|
||||||
(LPOVERLAPPED)NULL
|
(LPOVERLAPPED)NULL
|
||||||
) == FALSE){
|
) == FALSE){
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,15 +176,15 @@ static __inline__ sng_fd_t tdmv_api_open_span_chan(int span, int chan)
|
||||||
wan_udp.wan_udphdr_data_len = 0;
|
wan_udp.wan_udphdr_data_len = 0;
|
||||||
|
|
||||||
DeviceIoControl(
|
DeviceIoControl(
|
||||||
fd,
|
fd,
|
||||||
IoctlManagementCommand,
|
IoctlManagementCommand,
|
||||||
(LPVOID)&wan_udp,
|
(LPVOID)&wan_udp,
|
||||||
sizeof(wan_udp_hdr_t),
|
sizeof(wan_udp_hdr_t),
|
||||||
(LPVOID)&wan_udp,
|
(LPVOID)&wan_udp,
|
||||||
sizeof(wan_udp_hdr_t),
|
sizeof(wan_udp_hdr_t),
|
||||||
(LPDWORD)(&ln),
|
(LPDWORD)(&ln),
|
||||||
(LPOVERLAPPED)NULL
|
(LPOVERLAPPED)NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
if ((wan_udp.wan_udphdr_return_code) || (*(int*)&wan_udp.wan_udphdr_data[0] != 1)){
|
if ((wan_udp.wan_udphdr_return_code) || (*(int*)&wan_udp.wan_udphdr_data[0] != 1)){
|
||||||
/* somone already has this channel, or somthing else is not right. */
|
/* somone already has this channel, or somthing else is not right. */
|
||||||
|
@ -230,21 +230,21 @@ static __inline__ int tdmv_api_wait_socket(sng_fd_t fd, int timeout, int *flags)
|
||||||
api_poll.timeout = timeout;
|
api_poll.timeout = timeout;
|
||||||
|
|
||||||
if (!DeviceIoControl(
|
if (!DeviceIoControl(
|
||||||
fd,
|
fd,
|
||||||
IoctlApiPoll,
|
IoctlApiPoll,
|
||||||
(LPVOID)NULL,
|
(LPVOID)NULL,
|
||||||
0L,
|
0L,
|
||||||
(LPVOID)&api_poll,
|
(LPVOID)&api_poll,
|
||||||
sizeof(API_POLL_STRUCT),
|
sizeof(API_POLL_STRUCT),
|
||||||
(LPDWORD)(&ln),
|
(LPDWORD)(&ln),
|
||||||
(LPOVERLAPPED)NULL)) {
|
(LPOVERLAPPED)NULL)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*flags = 0;
|
*flags = 0;
|
||||||
|
|
||||||
switch(api_poll.operation_status)
|
switch(api_poll.operation_status)
|
||||||
{
|
{
|
||||||
case SANG_STATUS_RX_DATA_AVAILABLE:
|
case SANG_STATUS_RX_DATA_AVAILABLE:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -253,7 +253,7 @@ static __inline__ int tdmv_api_wait_socket(sng_fd_t fd, int timeout, int *flags)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (api_poll.poll_events_bitmap == 0){
|
if (api_poll.poll_events_bitmap == 0){
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -309,15 +309,15 @@ static __inline__ int tdmv_api_readmsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrlen
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!DeviceIoControl(
|
if (!DeviceIoControl(
|
||||||
fd,
|
fd,
|
||||||
IoctlReadCommand,
|
IoctlReadCommand,
|
||||||
(LPVOID)NULL,
|
(LPVOID)NULL,
|
||||||
0L,
|
0L,
|
||||||
(LPVOID)&rx_data,
|
(LPVOID)&rx_data,
|
||||||
sizeof(RX_DATA_STRUCT),
|
sizeof(RX_DATA_STRUCT),
|
||||||
(LPDWORD)(&ln),
|
(LPDWORD)(&ln),
|
||||||
(LPOVERLAPPED)NULL
|
(LPOVERLAPPED)NULL
|
||||||
)){
|
)){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,18 +327,18 @@ static __inline__ int tdmv_api_readmsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrlen
|
||||||
user_buf->wp_tdm_api_event_type = pri->operation_status;
|
user_buf->wp_tdm_api_event_type = pri->operation_status;
|
||||||
|
|
||||||
switch(pri->operation_status)
|
switch(pri->operation_status)
|
||||||
{
|
{
|
||||||
case SANG_STATUS_RX_DATA_AVAILABLE:
|
case SANG_STATUS_RX_DATA_AVAILABLE:
|
||||||
if (pri->data_length > datalen){
|
if (pri->data_length > datalen){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
memcpy(databuf, rx_data.data, pri->data_length);
|
||||||
|
rx_len = pri->data_length;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
memcpy(databuf, rx_data.data, pri->data_length);
|
|
||||||
rx_len = pri->data_length;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
|
@ -386,15 +386,15 @@ static __inline__ int tdmv_api_writemsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrle
|
||||||
memcpy(local_tx_data.data, databuf, pri->data_length);
|
memcpy(local_tx_data.data, databuf, pri->data_length);
|
||||||
|
|
||||||
if (!DeviceIoControl(
|
if (!DeviceIoControl(
|
||||||
fd,
|
fd,
|
||||||
IoctlWriteCommand,
|
IoctlWriteCommand,
|
||||||
(LPVOID)&local_tx_data,
|
(LPVOID)&local_tx_data,
|
||||||
(ULONG)sizeof(TX_DATA_STRUCT),
|
(ULONG)sizeof(TX_DATA_STRUCT),
|
||||||
(LPVOID)&local_tx_data,
|
(LPVOID)&local_tx_data,
|
||||||
sizeof(TX_DATA_STRUCT),
|
sizeof(TX_DATA_STRUCT),
|
||||||
(LPDWORD)(&ln),
|
(LPDWORD)(&ln),
|
||||||
(LPOVERLAPPED)NULL
|
(LPOVERLAPPED)NULL
|
||||||
)){
|
)){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -425,3 +425,15 @@ static __inline__ int tdmv_api_writemsg_tdm(sng_fd_t fd, void *hdrbuf, int hdrle
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* _SANGOMA_TDM_API_H */
|
#endif /* _SANGOMA_TDM_API_H */
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
|
@ -46,3 +46,14 @@ zap_status_t zap_analog_start(zap_span_t *span);
|
||||||
zap_status_t zap_analog_configure_span(zap_span_t *span, char *tonemap, uint32_t digit_timeout, uint32_t max_dialstr, zio_signal_cb_t sig_cb);
|
zap_status_t zap_analog_configure_span(zap_span_t *span, char *tonemap, uint32_t digit_timeout, uint32_t max_dialstr, zio_signal_cb_t sig_cb);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
|
@ -47,3 +47,15 @@ zap_status_t zap_isdn_init(void);
|
||||||
zap_status_t zap_isdn_configure_span(zap_span_t *span, Q921NetUser_t mode, Q931Dialect_t dialect, zio_signal_cb_t sig_cb);
|
zap_status_t zap_isdn_configure_span(zap_span_t *span, Q921NetUser_t mode, Q931Dialect_t dialect, zio_signal_cb_t sig_cb);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
|
@ -39,3 +39,14 @@ zap_status_t skel_init(zap_software_interface_t **zint);
|
||||||
zap_status_t skel_destroy(void);
|
zap_status_t skel_destroy(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
|
@ -37,3 +37,15 @@ zap_status_t zap_mutex_trylock(zap_mutex_t *mutex);
|
||||||
zap_status_t zap_mutex_unlock(zap_mutex_t *mutex);
|
zap_status_t zap_mutex_unlock(zap_mutex_t *mutex);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
|
@ -41,10 +41,12 @@ typedef unsigned __int64 uint64_t;
|
||||||
typedef unsigned __int32 uint32_t;
|
typedef unsigned __int32 uint32_t;
|
||||||
typedef __int32 int32_t;
|
typedef __int32 int32_t;
|
||||||
typedef intptr_t zap_ssize_t;
|
typedef intptr_t zap_ssize_t;
|
||||||
|
typedef int zap_filehandle_t;
|
||||||
#else
|
#else
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
typedef int zap_socket_t;
|
typedef int zap_socket_t;
|
||||||
typedef ssize_t zap_ssize_t;
|
typedef ssize_t zap_ssize_t;
|
||||||
|
typedef int zap_filehandle_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef size_t zap_size_t;
|
typedef size_t zap_size_t;
|
||||||
|
@ -167,8 +169,8 @@ typedef enum {
|
||||||
ZAP_COMMAND_GET_CODEC,
|
ZAP_COMMAND_GET_CODEC,
|
||||||
ZAP_COMMAND_SET_NATIVE_CODEC,
|
ZAP_COMMAND_SET_NATIVE_CODEC,
|
||||||
ZAP_COMMAND_GET_NATIVE_CODEC,
|
ZAP_COMMAND_GET_NATIVE_CODEC,
|
||||||
ZAP_COMMAND_ENABLE_TONE_DETECT,
|
ZAP_COMMAND_ENABLE_DTMF_DETECT,
|
||||||
ZAP_COMMAND_DISABLE_TONE_DETECT,
|
ZAP_COMMAND_DISABLE_DTMF_DETECT,
|
||||||
ZAP_COMMAND_SEND_DTMF,
|
ZAP_COMMAND_SEND_DTMF,
|
||||||
ZAP_COMMAND_SET_DTMF_ON_PERIOD,
|
ZAP_COMMAND_SET_DTMF_ON_PERIOD,
|
||||||
ZAP_COMMAND_GET_DTMF_ON_PERIOD,
|
ZAP_COMMAND_GET_DTMF_ON_PERIOD,
|
||||||
|
@ -180,6 +182,8 @@ typedef enum {
|
||||||
ZAP_COMMAND_ONHOOK,
|
ZAP_COMMAND_ONHOOK,
|
||||||
ZAP_COMMAND_ENABLE_PROGRESS_DETECT,
|
ZAP_COMMAND_ENABLE_PROGRESS_DETECT,
|
||||||
ZAP_COMMAND_DISABLE_PROGRESS_DETECT,
|
ZAP_COMMAND_DISABLE_PROGRESS_DETECT,
|
||||||
|
ZAP_COMMAND_TRACE_INPUT,
|
||||||
|
ZAP_COMMAND_TRACE_OUTPUT,
|
||||||
ZAP_COMMAND_COUNT
|
ZAP_COMMAND_COUNT
|
||||||
} zap_command_t;
|
} zap_command_t;
|
||||||
|
|
||||||
|
@ -322,3 +326,15 @@ typedef struct hashtable_itr zap_hash_itr_t;
|
||||||
typedef struct key zap_hash_key_t;
|
typedef struct key zap_hash_key_t;
|
||||||
typedef struct value zap_hash_val_t;
|
typedef struct value zap_hash_val_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
|
@ -39,3 +39,15 @@ zap_status_t wanpipe_init(zap_io_interface_t **zint);
|
||||||
zap_status_t wanpipe_destroy(void);
|
zap_status_t wanpipe_destroy(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
|
@ -229,3 +229,14 @@ zap_status_t zt_init(zap_io_interface_t **zint);
|
||||||
zap_status_t zt_destroy(void);
|
zap_status_t zt_destroy(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
|
@ -208,8 +208,8 @@ void teletone_multi_tone_init(teletone_multi_tone_t *mt, teletone_tone_map_t *ma
|
||||||
}
|
}
|
||||||
|
|
||||||
int teletone_multi_tone_detect (teletone_multi_tone_t *mt,
|
int teletone_multi_tone_detect (teletone_multi_tone_t *mt,
|
||||||
int16_t sample_buffer[],
|
int16_t sample_buffer[],
|
||||||
int samples)
|
int samples)
|
||||||
{
|
{
|
||||||
int sample, limit, j, x = 0;
|
int sample, limit, j, x = 0;
|
||||||
teletone_process_t v1, famp;
|
teletone_process_t v1, famp;
|
||||||
|
@ -295,8 +295,8 @@ int teletone_multi_tone_detect (teletone_multi_tone_t *mt,
|
||||||
|
|
||||||
|
|
||||||
int teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
int teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||||
int16_t sample_buffer[],
|
int16_t sample_buffer[],
|
||||||
int samples)
|
int samples)
|
||||||
{
|
{
|
||||||
teletone_process_t row_energy[GRID_FACTOR];
|
teletone_process_t row_energy[GRID_FACTOR];
|
||||||
teletone_process_t col_energy[GRID_FACTOR];
|
teletone_process_t col_energy[GRID_FACTOR];
|
||||||
|
@ -426,8 +426,8 @@ int teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||||
|
|
||||||
|
|
||||||
int teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
int teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state,
|
||||||
char *buf,
|
char *buf,
|
||||||
int max)
|
int max)
|
||||||
{
|
{
|
||||||
if (max > dtmf_detect_state->current_digits) {
|
if (max > dtmf_detect_state->current_digits) {
|
||||||
max = dtmf_detect_state->current_digits;
|
max = dtmf_detect_state->current_digits;
|
||||||
|
|
|
@ -137,11 +137,11 @@ static void launch_channel(struct sangoma_pri *spri, int channo)
|
||||||
|
|
||||||
if (!lead && loops == 300) {
|
if (!lead && loops == 300) {
|
||||||
#if 1
|
#if 1
|
||||||
if (zap_channel_command(chan, ZAP_COMMAND_SEND_DTMF, dtmf) != ZAP_SUCCESS) {
|
if (zap_channel_command(chan, ZAP_COMMAND_SEND_DTMF, dtmf) != ZAP_SUCCESS) {
|
||||||
printf("Critical Error: Failed to send dtmf\n");
|
printf("Critical Error: Failed to send dtmf\n");
|
||||||
zap_channel_close(&chan);
|
zap_channel_close(&chan);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -314,3 +314,13 @@ int main(int argc, char *argv[])
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
|
@ -23,39 +23,39 @@
|
||||||
static __inline int gettimeofday(struct timeval *tp, void *nothing)
|
static __inline int gettimeofday(struct timeval *tp, void *nothing)
|
||||||
{
|
{
|
||||||
#ifdef WITHOUT_MM_LIB
|
#ifdef WITHOUT_MM_LIB
|
||||||
SYSTEMTIME st;
|
SYSTEMTIME st;
|
||||||
time_t tt;
|
time_t tt;
|
||||||
struct tm tmtm;
|
struct tm tmtm;
|
||||||
/* mktime converts local to UTC */
|
/* mktime converts local to UTC */
|
||||||
GetLocalTime (&st);
|
GetLocalTime (&st);
|
||||||
tmtm.tm_sec = st.wSecond;
|
tmtm.tm_sec = st.wSecond;
|
||||||
tmtm.tm_min = st.wMinute;
|
tmtm.tm_min = st.wMinute;
|
||||||
tmtm.tm_hour = st.wHour;
|
tmtm.tm_hour = st.wHour;
|
||||||
tmtm.tm_mday = st.wDay;
|
tmtm.tm_mday = st.wDay;
|
||||||
tmtm.tm_mon = st.wMonth - 1;
|
tmtm.tm_mon = st.wMonth - 1;
|
||||||
tmtm.tm_year = st.wYear - 1900; tmtm.tm_isdst = -1;
|
tmtm.tm_year = st.wYear - 1900; tmtm.tm_isdst = -1;
|
||||||
tt = mktime (&tmtm);
|
tt = mktime (&tmtm);
|
||||||
tp->tv_sec = tt;
|
tp->tv_sec = tt;
|
||||||
tp->tv_usec = st.wMilliseconds * 1000;
|
tp->tv_usec = st.wMilliseconds * 1000;
|
||||||
#else
|
#else
|
||||||
/**
|
/**
|
||||||
** The earlier time calculations using GetLocalTime
|
** The earlier time calculations using GetLocalTime
|
||||||
** had a time resolution of 10ms.The timeGetTime, part
|
** had a time resolution of 10ms.The timeGetTime, part
|
||||||
** of multimedia apis offer a better time resolution
|
** of multimedia apis offer a better time resolution
|
||||||
** of 1ms.Need to link against winmm.lib for this
|
** of 1ms.Need to link against winmm.lib for this
|
||||||
**/
|
**/
|
||||||
unsigned long Ticks = 0;
|
unsigned long Ticks = 0;
|
||||||
unsigned long Sec =0;
|
unsigned long Sec =0;
|
||||||
unsigned long Usec = 0;
|
unsigned long Usec = 0;
|
||||||
Ticks = timeGetTime();
|
Ticks = timeGetTime();
|
||||||
|
|
||||||
Sec = Ticks/1000;
|
Sec = Ticks/1000;
|
||||||
Usec = (Ticks - (Sec*1000))*1000;
|
Usec = (Ticks - (Sec*1000))*1000;
|
||||||
tp->tv_sec = Sec;
|
tp->tv_sec = Sec;
|
||||||
tp->tv_usec = Usec;
|
tp->tv_usec = Usec;
|
||||||
#endif /* WITHOUT_MM_LIB */
|
#endif /* WITHOUT_MM_LIB */
|
||||||
(void)nothing;
|
(void)nothing;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* WIN32 */
|
#endif /* WIN32 */
|
||||||
#endif /* HAVE_GETTIMEOFDAY */
|
#endif /* HAVE_GETTIMEOFDAY */
|
||||||
|
@ -166,7 +166,7 @@ int sangoma_one_loop(struct sangoma_pri *spri)
|
||||||
FD_ZERO(&efds);
|
FD_ZERO(&efds);
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
//Windows macro for FD_SET includes a warning C4127: conditional expression is constant
|
//Windows macro for FD_SET includes a warning C4127: conditional expression is constant
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable:4127)
|
#pragma warning(disable:4127)
|
||||||
#endif
|
#endif
|
||||||
|
@ -238,3 +238,14 @@ int sangoma_run_pri(struct sangoma_pri *spri)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
|
@ -100,3 +100,15 @@ int main(int argc, char *argv[])
|
||||||
zap_global_destroy();
|
zap_global_destroy();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
|
@ -72,3 +72,14 @@ int main(int argc, char *argv[])
|
||||||
zap_global_destroy();
|
zap_global_destroy();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
|
@ -41,3 +41,14 @@ int main(int argc, char *argv[])
|
||||||
zap_global_destroy();
|
zap_global_destroy();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
|
@ -135,7 +135,7 @@ static void *zap_analog_channel_run(zap_thread_t *me, void *obj)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zap_channel_command(chan, ZAP_COMMAND_ENABLE_TONE_DETECT, &tt) != ZAP_SUCCESS) {
|
if (zap_channel_command(chan, ZAP_COMMAND_ENABLE_DTMF_DETECT, &tt) != ZAP_SUCCESS) {
|
||||||
snprintf(chan->last_error, sizeof(chan->last_error), "error initilizing tone detector!");
|
snprintf(chan->last_error, sizeof(chan->last_error), "error initilizing tone detector!");
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -483,6 +483,7 @@ static zap_status_t process_event(zap_span_t *span, zap_event_t *event)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (event->channel->state == ZAP_CHANNEL_STATE_DOWN && !zap_test_flag(event->channel, ZAP_CHANNEL_INTHREAD)) {
|
if (event->channel->state == ZAP_CHANNEL_STATE_DOWN && !zap_test_flag(event->channel, ZAP_CHANNEL_INTHREAD)) {
|
||||||
|
/*zap_channel_command(event->channel, ZAP_COMMAND_TRACE_INPUT, "/tmp/inbound.ul");*/
|
||||||
sig.event_id = ZAP_SIGEVENT_START;
|
sig.event_id = ZAP_SIGEVENT_START;
|
||||||
zap_set_string(event->channel->caller_data.dnis, event->channel->chan_number);
|
zap_set_string(event->channel->caller_data.dnis, event->channel->chan_number);
|
||||||
data->sig_cb(&sig);
|
data->sig_cb(&sig);
|
||||||
|
@ -585,3 +586,13 @@ zap_status_t zap_analog_start(zap_span_t *span)
|
||||||
return zap_thread_create_detached(zap_analog_run, span);
|
return zap_thread_create_detached(zap_analog_run, span);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
|
@ -197,11 +197,11 @@ zap_size_t zap_buffer_write(zap_buffer_t *buffer, const void *data, zap_size_t d
|
||||||
freespace = buffer->datalen - buffer->used;
|
freespace = buffer->datalen - buffer->used;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (buffer->data != buffer->head) {
|
if (buffer->data != buffer->head) {
|
||||||
memmove(buffer->data, buffer->head, buffer->used);
|
memmove(buffer->data, buffer->head, buffer->used);
|
||||||
buffer->head = buffer->data;
|
buffer->head = buffer->data;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (freespace < datalen) {
|
if (freespace < datalen) {
|
||||||
zap_size_t new_size, new_block_size;
|
zap_size_t new_size, new_block_size;
|
||||||
|
|
|
@ -332,6 +332,8 @@ zap_status_t zap_span_add_channel(zap_span_t *span, zap_socket_t sockfd, zap_cha
|
||||||
new_chan->span_id = span->span_id;
|
new_chan->span_id = span->span_id;
|
||||||
new_chan->chan_id = span->chan_count;
|
new_chan->chan_id = span->chan_count;
|
||||||
new_chan->span = span;
|
new_chan->span = span;
|
||||||
|
new_chan->fds[0] = -1;
|
||||||
|
new_chan->fds[1] = -1;
|
||||||
zap_mutex_create(&new_chan->mutex);
|
zap_mutex_create(&new_chan->mutex);
|
||||||
zap_buffer_create(&new_chan->digit_buffer, 128, 128, 0);
|
zap_buffer_create(&new_chan->digit_buffer, 128, 128, 0);
|
||||||
zap_set_flag(new_chan, ZAP_CHANNEL_CONFIGURED | ZAP_CHANNEL_READY);
|
zap_set_flag(new_chan, ZAP_CHANNEL_CONFIGURED | ZAP_CHANNEL_READY);
|
||||||
|
@ -689,12 +691,18 @@ zap_status_t zap_channel_outgoing_call(zap_channel_t *zchan)
|
||||||
|
|
||||||
zap_status_t zap_channel_done(zap_channel_t *zchan)
|
zap_status_t zap_channel_done(zap_channel_t *zchan)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
assert(zchan != NULL);
|
assert(zchan != NULL);
|
||||||
|
|
||||||
memset(&zchan->caller_data, 0, sizeof(zchan->caller_data));
|
memset(&zchan->caller_data, 0, sizeof(zchan->caller_data));
|
||||||
zap_clear_flag_locked(zchan, ZAP_CHANNEL_INUSE);
|
zap_clear_flag_locked(zchan, ZAP_CHANNEL_INUSE);
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
if (zchan->fds[i] > -1) {
|
||||||
|
close(zchan->fds[i]);
|
||||||
|
zchan->fds[i] = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
return ZAP_SUCCESS;
|
return ZAP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -780,6 +788,36 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
|
||||||
zap_mutex_lock(zchan->mutex);
|
zap_mutex_lock(zchan->mutex);
|
||||||
|
|
||||||
switch(command) {
|
switch(command) {
|
||||||
|
case ZAP_COMMAND_TRACE_INPUT:
|
||||||
|
{
|
||||||
|
char *path = (char *) obj;
|
||||||
|
if (zchan->fds[0] > 0) {
|
||||||
|
close(zchan->fds[0]);
|
||||||
|
zchan->fds[0] = -1;
|
||||||
|
}
|
||||||
|
if ((zchan->fds[0] = open(path, O_WRONLY|O_CREAT|O_TRUNC, 755)) > -1) {
|
||||||
|
GOTO_STATUS(done, ZAP_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(zchan->last_error, sizeof(zchan->last_error), "%s", strerror(errno));
|
||||||
|
GOTO_STATUS(done, ZAP_FAIL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ZAP_COMMAND_TRACE_OUTPUT:
|
||||||
|
{
|
||||||
|
char *path = (char *) obj;
|
||||||
|
if (zchan->fds[1] > 0) {
|
||||||
|
close(zchan->fds[0]);
|
||||||
|
zchan->fds[1] = -1;
|
||||||
|
}
|
||||||
|
if ((zchan->fds[1] = open(path, O_WRONLY|O_CREAT|O_TRUNC, 755)) > -1) {
|
||||||
|
GOTO_STATUS(done, ZAP_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(zchan->last_error, sizeof(zchan->last_error), "%s", strerror(errno));
|
||||||
|
GOTO_STATUS(done, ZAP_FAIL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case ZAP_COMMAND_SET_INTERVAL:
|
case ZAP_COMMAND_SET_INTERVAL:
|
||||||
{
|
{
|
||||||
if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_INTERVAL)) {
|
if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_INTERVAL)) {
|
||||||
|
@ -863,7 +901,7 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
|
||||||
GOTO_STATUS(done, ZAP_SUCCESS);
|
GOTO_STATUS(done, ZAP_SUCCESS);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ZAP_COMMAND_ENABLE_TONE_DETECT:
|
case ZAP_COMMAND_ENABLE_DTMF_DETECT:
|
||||||
{
|
{
|
||||||
/* if they don't have thier own, use ours */
|
/* if they don't have thier own, use ours */
|
||||||
if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF)) {
|
if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF)) {
|
||||||
|
@ -880,7 +918,7 @@ zap_status_t zap_channel_command(zap_channel_t *zchan, zap_command_t command, vo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ZAP_COMMAND_DISABLE_TONE_DETECT:
|
case ZAP_COMMAND_DISABLE_DTMF_DETECT:
|
||||||
{
|
{
|
||||||
if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF)) {
|
if (!zap_channel_test_feature(zchan, ZAP_CHANNEL_FEATURE_DTMF)) {
|
||||||
zap_tone_type_t tt = ZAP_COMMAND_OBJ_INT;
|
zap_tone_type_t tt = ZAP_COMMAND_OBJ_INT;
|
||||||
|
@ -1216,6 +1254,9 @@ zap_status_t zap_channel_read(zap_channel_t *zchan, void *data, zap_size_t *data
|
||||||
}
|
}
|
||||||
|
|
||||||
status = zchan->zio->read(zchan, data, datalen);
|
status = zchan->zio->read(zchan, data, datalen);
|
||||||
|
if (zchan->fds[0]) {
|
||||||
|
write(zchan->fds[0], data, *datalen);
|
||||||
|
}
|
||||||
|
|
||||||
if (status == ZAP_SUCCESS && zap_test_flag(zchan, ZAP_CHANNEL_TRANSCODE) && zchan->effective_codec != zchan->native_codec) {
|
if (status == ZAP_SUCCESS && zap_test_flag(zchan, ZAP_CHANNEL_TRANSCODE) && zchan->effective_codec != zchan->native_codec) {
|
||||||
if (zchan->native_codec == ZAP_CODEC_ULAW && zchan->effective_codec == ZAP_CODEC_SLIN) {
|
if (zchan->native_codec == ZAP_CODEC_ULAW && zchan->effective_codec == ZAP_CODEC_SLIN) {
|
||||||
|
@ -1391,6 +1432,10 @@ zap_status_t zap_channel_write(zap_channel_t *zchan, void *data, zap_size_t data
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (zchan->fds[1]) {
|
||||||
|
write(zchan->fds[1], data, *datalen);
|
||||||
|
}
|
||||||
|
|
||||||
status = zchan->zio->write(zchan, data, datalen);
|
status = zchan->zio->write(zchan, data, datalen);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
|
@ -1731,3 +1776,13 @@ void print_bits(uint8_t *b, int bl, char *buf, int blen, int e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
|
@ -250,3 +250,14 @@ zap_status_t zap_isdn_configure_span(zap_span_t *span, Q921NetUser_t mode, Q931D
|
||||||
|
|
||||||
return ZAP_SUCCESS;
|
return ZAP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
|
@ -108,3 +108,15 @@ zap_status_t skel_destroy(void)
|
||||||
{
|
{
|
||||||
return ZAP_FAIL;
|
return ZAP_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
|
@ -119,15 +119,15 @@ zap_status_t zap_thread_create_detached_ex(zap_thread_function_t func, void *dat
|
||||||
|
|
||||||
status = ZAP_SUCCESS;
|
status = ZAP_SUCCESS;
|
||||||
goto done;
|
goto done;
|
||||||
failpthread:
|
failpthread:
|
||||||
pthread_attr_destroy(&thread->attribute);
|
pthread_attr_destroy(&thread->attribute);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
if (thread) {
|
if (thread) {
|
||||||
free(thread);
|
free(thread);
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,16 +157,16 @@ zap_status_t zap_mutex_create(zap_mutex_t **mutex)
|
||||||
|
|
||||||
goto success;
|
goto success;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
pthread_mutexattr_destroy(&attr);
|
pthread_mutexattr_destroy(&attr);
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
success:
|
success:
|
||||||
#endif
|
#endif
|
||||||
*mutex = check;
|
*mutex = check;
|
||||||
status = ZAP_SUCCESS;
|
status = ZAP_SUCCESS;
|
||||||
|
|
||||||
done:
|
done:
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,3 +217,14 @@ zap_status_t zap_mutex_unlock(zap_mutex_t *mutex)
|
||||||
#endif
|
#endif
|
||||||
return ZAP_SUCCESS;
|
return ZAP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
|
@ -72,6 +72,8 @@ static unsigned wp_open_range(zap_span_t *span, unsigned spanno, unsigned start,
|
||||||
|
|
||||||
if (sockfd != WP_INVALID_SOCKET && zap_span_add_channel(span, sockfd, type, &chan) == ZAP_SUCCESS) {
|
if (sockfd != WP_INVALID_SOCKET && zap_span_add_channel(span, sockfd, type, &chan) == ZAP_SUCCESS) {
|
||||||
zap_log(ZAP_LOG_INFO, "configuring device s%dc%d as OpenZAP device %d:%d fd:%d\n", spanno, x, chan->span_id, chan->chan_id, sockfd);
|
zap_log(ZAP_LOG_INFO, "configuring device s%dc%d as OpenZAP device %d:%d fd:%d\n", spanno, x, chan->span_id, chan->chan_id, sockfd);
|
||||||
|
chan->physical_span_id = spanno;
|
||||||
|
chan->physical_chan_id = x;
|
||||||
if (type == ZAP_CHAN_TYPE_FXS || type == ZAP_CHAN_TYPE_FXO) {
|
if (type == ZAP_CHAN_TYPE_FXS || type == ZAP_CHAN_TYPE_FXO) {
|
||||||
wanpipe_tdm_api_t tdm_api;
|
wanpipe_tdm_api_t tdm_api;
|
||||||
|
|
||||||
|
@ -532,3 +534,14 @@ zap_status_t wanpipe_destroy(void)
|
||||||
memset(&wanpipe_interface, 0, sizeof(wanpipe_interface));
|
memset(&wanpipe_interface, 0, sizeof(wanpipe_interface));
|
||||||
return ZAP_SUCCESS;
|
return ZAP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
|
@ -90,6 +90,9 @@ static unsigned zt_open_range(zap_span_t *span, unsigned start, unsigned end, za
|
||||||
}
|
}
|
||||||
zap_log(ZAP_LOG_INFO, "configuring device %s as OpenZAP device %d:%d fd:%d\n", path, chan->span_id, chan->chan_id, sockfd);
|
zap_log(ZAP_LOG_INFO, "configuring device %s as OpenZAP device %d:%d fd:%d\n", path, chan->span_id, chan->chan_id, sockfd);
|
||||||
|
|
||||||
|
chan->physical_span_id = ztp.span_no;
|
||||||
|
chan->physical_chan_id = ztp.chan_no;
|
||||||
|
|
||||||
if (type == ZAP_CHAN_TYPE_FXS || type == ZAP_CHAN_TYPE_FXO) {
|
if (type == ZAP_CHAN_TYPE_FXS || type == ZAP_CHAN_TYPE_FXO) {
|
||||||
if (ztp.g711_type == ZT_G711_ALAW) {
|
if (ztp.g711_type == ZT_G711_ALAW) {
|
||||||
chan->native_codec = chan->effective_codec = ZAP_CODEC_ALAW;
|
chan->native_codec = chan->effective_codec = ZAP_CODEC_ALAW;
|
||||||
|
@ -559,3 +562,14 @@ zap_status_t zt_destroy(void)
|
||||||
memset(&zt_interface, 0, sizeof(zt_interface));
|
memset(&zt_interface, 0, sizeof(zt_interface));
|
||||||
return ZAP_SUCCESS;
|
return ZAP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For Emacs:
|
||||||
|
* Local Variables:
|
||||||
|
* mode:c
|
||||||
|
* indent-tabs-mode:t
|
||||||
|
* tab-width:4
|
||||||
|
* c-basic-offset:4
|
||||||
|
* End:
|
||||||
|
* For VIM:
|
||||||
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
||||||
|
*/
|
||||||
|
|
Loading…
Reference in New Issue