fixed trace bug
[lcr.git] / tones.c
diff --git a/tones.c b/tones.c
index 45c05c9..fd85529 100644 (file)
--- a/tones.c
+++ b/tones.c
@@ -9,15 +9,6 @@
 **                                                                           **
 \*****************************************************************************/ 
 
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <errno.h>
 #include "main.h"
 
 /* 
@@ -38,12 +29,12 @@ the read_tone() will return law or 16bit mono. the read_tone will convert all ot
 struct fmt {
        unsigned short  stereo; /* 1 = pcm, 2 = adpcm */
        unsigned short  channels; /* number of channels */
-       unsigned long   sample_rate; /* sample rate */
-       unsigned long   data_rate; /* data rate */
+       unsigned int   sample_rate; /* sample rate */
+       unsigned int   data_rate; /* data rate */
        unsigned short  bytes_sample; /* bytes per sample (all channels) */
        unsigned short  bits_sample; /* bits per sample (one channel) */
 };
-int open_tone(char *file, int *codec, signed long *length, signed long *left)
+int open_tone(char *file, int *codec, signed int *length, signed int *left)
 {
        int fh;
        char filename[256];        
@@ -51,7 +42,7 @@ int open_tone(char *file, int *codec, signed long *length, signed long *left)
        unsigned char buffer[256];
        struct fmt *fmt;
        int channels, bytes;
-       unsigned long size, chunk;
+       unsigned int size, chunk;
        int gotfmt = 0;
        struct stat _stat;
        int linksize;
@@ -155,7 +146,7 @@ int open_tone(char *file, int *codec, signed long *length, signed long *left)
                        read(fh, buffer, 8);
                        chunk=(buffer[4]) + (buffer[5]<<8) + (buffer[6]<<16) + (buffer[7]<<24);
                        size -= (8+chunk);
-//                     printf("%c%c%c%c lenght=%d\n",buffer[0],buffer[1],buffer[2],buffer[3],chunk);
+//                     printf("%c%c%c%c length=%d\n",buffer[0],buffer[1],buffer[2],buffer[3],chunk);
                        if (size < 0)
                        {
                                close(fh);
@@ -165,7 +156,7 @@ int open_tone(char *file, int *codec, signed long *length, signed long *left)
                        }
                        if (!strncmp((char *)buffer, "fmt ", 4))
                        {
-                               if (chunk != 16)
+                               if (chunk < 16)
                                {
                                        close(fh);
                                        errno = 0;
@@ -214,27 +205,28 @@ int open_tone(char *file, int *codec, signed long *length, signed long *left)
                                        if (codec)
                                                *codec = CODEC_MONO;
                                        if (length)
-                                               *length = ((signed long)chunk)>>1;
+                                               *length = ((signed int)chunk)>>1;
                                        if (left)
-                                               *left = ((signed long)chunk)>>1;
+                                               *left = ((signed int)chunk)>>1;
+//                                     printf("left=%d\n",*left);
                                } else
                                if (bytes==2 && channels==2)
                                {
                                        if (codec)
                                                *codec = CODEC_STEREO;
                                        if (length)
-                                               *length = ((signed long)chunk)>>2;
+                                               *length = ((signed int)chunk)>>2;
                                        if (left)
-                                               *left = ((signed long)chunk)>>2;
+                                               *left = ((signed int)chunk)>>2;
                                } else
                                if (bytes==1 && channels==1)
                                {
                                        if (codec)
                                                *codec = CODEC_8BIT;
                                        if (length)
-                                               *length = (signed long)chunk;
+                                               *length = (signed int)chunk;
                                        if (left)
-                                               *left = (signed long)chunk;
+                                               *left = (signed int)chunk;
                                } else
                                {
                                        close(fh);
@@ -276,11 +268,17 @@ int open_tone(char *file, int *codec, signed long *length, signed long *left)
 /*
  * read from tone, check size
  * the len must be the number of samples, NOT for the bytes to read!!
+ * the data returned is law-code
  */
-int read_tone(int fh, void *buffer, int codec, int len, signed long size, signed long *left, int speed)
+int read_tone(int fh, unsigned char *buffer, int codec, int len, signed int size, signed int *left, int speed)
 {
        int l;
        int offset;
+       signed short buffer16[len], *buf16 = buffer16;
+       signed short buffer32[len<<1], *buf32 = buffer32;
+       unsigned char buffer8[len], *buf8 = buffer8;
+       signed int sample;
+       int i = 0;
 //printf("left=%ld\n",*left);
 
        /* if no *left is given (law has unknown length) */
@@ -319,17 +317,25 @@ int read_tone(int fh, void *buffer, int codec, int len, signed long size, signed
                break;
 
                case CODEC_MONO:
-               l = read(fh, buffer, len<<1); /* as is */
-               if (l>0)
-                       l = l>>1;
+                       l = read(fh, buf16, len<<1);
+                       if (l>0)
+                       {
+                               l = l>>1;
+                               while(i < l)
+                               {
+                                       sample = *buf16++;
+                                       if (sample < -32767)
+                                               sample = -32767;
+                                       if (sample > 32767)
+                                               sample = 32767;
+                                       *buffer++ = audio_s16_to_law[sample & 0xffff];
+                                       i++;
+                               }
+                       }
                break;
 
                case CODEC_STEREO:
                {
-                       signed short buffer32[len<<1], *buf32 = buffer32;
-                       signed short *buf16 = (signed short *)buffer;
-                       signed long sample;
-                       int i = 0;
                        l = read(fh, buf32, len<<2);
                        if (l>0)
                        {
@@ -341,7 +347,7 @@ int read_tone(int fh, void *buffer, int codec, int len, signed long size, signed
                                                sample = -32767;
                                        if (sample > 32767)
                                                sample = 32767;
-                                       *buf16++ = sample;
+                                       *buffer++ = audio_s16_to_law[sample & 0xffff];
                                        i++;
                                }
                        }
@@ -350,15 +356,12 @@ int read_tone(int fh, void *buffer, int codec, int len, signed long size, signed
 
                case CODEC_8BIT:
                {
-                       unsigned char buffer8[len], *buf8 = buffer8;
-                       signed short *buf16 = (signed short *)buffer;
-                       int i = 0;
                        l = read(fh, buf8, len);
                        if (l>0)
                        {
                                while(i < l)
                                {
-                                       *buf16++ = (((*buf8++) << 8) - 0x8000) & 0xffff;
+                                       *buffer++ = audio_s16_to_law[(((*buf8++)<<8)-0x8000) & 0xffff];
                                        i++;
                                }
                        }
@@ -366,8 +369,7 @@ int read_tone(int fh, void *buffer, int codec, int len, signed long size, signed
                break;
 
                default:
-               PERROR("codec %d is not specified or supported, exitting...\n", codec);
-               exit(-1);
+               FATAL("codec %d is not supported.\n", codec);
        }
 
        if (l>0 && left)
@@ -395,12 +397,12 @@ void free_tones(void)
                {
                        temp = tonesettone_temp;
                        tonesettone_temp = tonesettone_temp->next;
-                       free(temp);
+                       FREE(temp, sizeof(struct tonesettone));
                        memuse--;
                }
                temp = toneset_temp;
                toneset_temp = toneset_temp->next;
-               free(temp);
+               FREE(temp, sizeof(struct toneset));
                memuse--;
        }
        toneset_first = NULL;
@@ -420,8 +422,8 @@ int fetch_tones(void)
        char filename[256], name[256];
        int fh;
        int tone_codec;
-       signed long tone_size, tone_left, real_size;
-       unsigned long memory = 0;
+       signed int tone_size, tone_left;
+       unsigned int memory = 0;
        int samples = 0;
 
        /* if disabled */
@@ -454,15 +456,9 @@ int fetch_tones(void)
                printf("PBX: Fetching tones '%s'\n", p);
                PDEBUG(DEBUG_PORT, "fetching tones directory '%s'\n", p);
 
-               *toneset_nextpointer = (struct toneset *)calloc(1, sizeof(struct toneset));
-               if (*toneset_nextpointer == NULL)
-               {
-                       PERROR("No memory for tone set: '%s'\n",p);
-                       return(0);
-               }
+               *toneset_nextpointer = (struct toneset *)MALLOC(sizeof(struct toneset));
                memuse++;
                memory += sizeof(struct toneset);
-               memset(*toneset_nextpointer, 0 , sizeof(struct toneset));
                SCPY((*toneset_nextpointer)->directory, p);
                tonesettone_nextpointer = &(*toneset_nextpointer)->first;
 
@@ -515,43 +511,11 @@ int fetch_tones(void)
                                continue;
                        }
 
-                       /* real size */
-                       switch(tone_codec)
-                       {
-                               case CODEC_LAW:
-                               real_size = tone_size;
-                               break;
-
-                               case CODEC_MONO:
-                               real_size = tone_size << 1;
-                               break;
-
-                               case CODEC_STEREO:
-                               real_size = tone_size << 1;
-                               break;
-
-                               case CODEC_8BIT:
-                               real_size = tone_size << 1;
-                               break;
-
-                               default:
-                               PERROR("codec %d is not specified or supported, exitting...\n", tone_codec);
-                               exit(-1);
-                       }
-
-                       /* allocate tone */
-                       *tonesettone_nextpointer = (struct tonesettone *)calloc(1, sizeof(struct tonesettone)+real_size);
-                       if (*toneset_nextpointer == NULL)
-                       {
-                               PERROR("No memory for tone set: '%s'\n",p);
-                               close(fh);
-                               fduse--;
-                               return(0);
-                       }
+                       /* Allocate tone */
+                       *tonesettone_nextpointer = (struct tonesettone *)MALLOC(sizeof(struct tonesettone)+tone_size);
                        memuse++;
 //printf("tone:%s, %ld bytes\n", name, tone_size);
-                       memset(*tonesettone_nextpointer, 0 , sizeof(struct tonesettone)+real_size);
-                       memory += sizeof(struct tonesettone)+real_size;
+                       memory += sizeof(struct tonesettone)+tone_size;
                        samples ++;
 
                        /* load tone */
@@ -580,7 +544,7 @@ int fetch_tones(void)
 /*
  * opens the fetched tone (if available)
  */
-void *open_tone_fetched(char *dir, char *file, int *codec, signed long *length, signed long *left)
+void *open_tone_fetched(char *dir, char *file, int *codec, signed int *length, signed int *left)
 {
        struct toneset *toneset;
        struct tonesettone *tonesettone;
@@ -629,7 +593,7 @@ void *open_tone_fetched(char *dir, char *file, int *codec, signed long *length,
  * read from fetched tone, check size
  * the len must be the number of samples, NOT for the bytes to read!!
  */
-int read_tone_fetched(void **fetched, void *buffer, int codec, int len, signed long size, signed long *left, int speed)
+int read_tone_fetched(void **fetched, void *buffer, int len, signed int size, signed int *left, int speed)
 {
        int l;
 //printf("left=%ld\n",*left);
@@ -643,24 +607,10 @@ int read_tone_fetched(void **fetched, void *buffer, int codec, int len, signed l
 
        if (*left < len)
                len = *left;
-       switch(codec)
-       {
-               case CODEC_LAW:
-               memcpy(buffer, *fetched, len);
-               *((char **)fetched) += len;
-               l = len;
-               break;
 
-               case CODEC_MONO:
-               memcpy(buffer, *fetched, len<<1);
-               *((char **)fetched) += len<<1;
-               l = len;
-               break;
-
-               default:
-               PERROR("codec %d is not specified or supported, exitting...\n", codec);
-               exit(-1);
-       }
+       memcpy(buffer, *fetched, len);
+       *((char **)fetched) += len;
+       l = len;
 
        if (l>0 && left)
                *left -= l;