1 /*****************************************************************************\
5 **---------------------------------------------------------------------------**
6 ** Copyright: Andreas Eversberg **
8 ** opening and reading tone **
10 \*****************************************************************************/
15 #include <sys/types.h>
26 CODEC_OFF is a none accepted value
27 CODEC_LAW is 8 bit (1 byte) data 8khz
28 other codecs are 16 bit (2 bytes) data 8khz
29 the read_tone() will return law or 16bit mono. the read_tone will convert all other formats to 16bit mono.
35 * open the tone (don't increase fhuse, since it is done after calling this function)
36 * NOTE: length and left will be set to the number of samples, NOT bytes
39 unsigned short stereo; /* 1 = pcm, 2 = adpcm */
40 unsigned short channels; /* number of channels */
41 unsigned long sample_rate; /* sample rate */
42 unsigned long data_rate; /* data rate */
43 unsigned short bytes_sample; /* bytes per sample (all channels) */
44 unsigned short bits_sample; /* bits per sample (one channel) */
46 int open_tone(char *file, int *codec, signed long *length, signed long *left)
51 unsigned char buffer[256];
54 unsigned long size, chunk;
62 /* try to open the law file */
63 SPRINT(filename, "%s.isdn", file);
64 if ((fh = open(filename, O_RDONLY)) >= 0)
73 PERROR("Link chain too deep: '%s'\n", filename);
76 if (lstat(filename, &_stat) == -1)
79 PERROR("Cannot stat file: '%s'\n", filename);
82 if (!S_ISLNK(_stat.st_mode))
86 if ((linksize=readlink(filename, linkname, sizeof(linkname))) > 0)
88 linkname[linksize] = '\0';
92 PERROR("Cannot read link information: '%s'\n", filename);
95 if (linkname[0] == '/') /* absolute link */
97 SCPY(filename, linkname);
98 } else /* relative link */
100 /* remove filename */
102 while(strchr(p, '/'))
104 p = strchr(p, '/')+1;
107 /* concat the link */
108 SCAT(filename, linkname);
110 //printf("follow link: %s\n", filename);
114 *length = _stat.st_size;
116 *left = _stat.st_size;
122 /* try to open the wave file */
123 SPRINT(filename, "%s.wav", file);
124 if ((fh = open(filename, O_RDONLY)) >= 0)
126 /* get wave header */
128 size=(buffer[4]) + (buffer[5]<<8) + (buffer[6]<<16) + (buffer[7]<<24);
129 if (!!strncmp((char *)buffer, "RIFF", 4))
133 PERROR("%s is no riff file!\n", filename);
136 // printf("%c%c%c%c size=%ld\n",buffer[0],buffer[1],buffer[2],buffer[3],size);
139 if (!!strncmp((char *)buffer, "WAVE", 4))
143 PERROR("%s is no wave file!\n", filename);
148 if (size>0 && size<8)
152 PERROR("Remaining file size %ld not large enough for next chunk.\n",size);
156 chunk=(buffer[4]) + (buffer[5]<<8) + (buffer[6]<<16) + (buffer[7]<<24);
158 // printf("%c%c%c%c lenght=%d\n",buffer[0],buffer[1],buffer[2],buffer[3],chunk);
163 PERROR("Chunk '%c%c%c%c' is larger than remainig file size (length=%ld)\n",buffer[0],buffer[1],buffer[2],buffer[3], chunk);
166 if (!strncmp((char *)buffer, "fmt ", 4))
172 PERROR("File %s Fmt chunk illegal size.\n", filename);
175 read(fh, buffer, chunk);
176 fmt = (struct fmt *)buffer;
177 if (fmt->channels<1 || fmt->channels>2)
181 PERROR("File %s Only support one or two channels file.\n", filename);
184 channels = fmt->channels;
185 // printf("Channels: %d\n", channels);
186 if (fmt->sample_rate != 8000)
188 PERROR("Warning: File %s has sample rate of %ld.\n", filename, fmt->sample_rate);
190 // printf("Sample Rate: %ld\n", fmt->sample_rate);
191 if (fmt->bits_sample!=8 && fmt->bits_sample!=16)
195 PERROR("File %s has neigher 8 nor 16 bit samples.\n", filename);
198 bytes = (fmt->bits_sample==16)?2:1;
199 // printf("Bit-Resolution: %d\n", bytes*16-16);
202 if (!strncmp((char *)buffer, "data", 4))
208 PERROR("File %s No fmt chunk found before data chunk.\n", filename);
211 // printf("Length: %ld samples (%ld.%03ld seconds)\n", chunk/bytes/channels, chunk/bytes/channels/8000, ((chunk/bytes/channels)%8000)*1000/8000);
212 if (bytes==2 && channels==1)
217 *length = ((signed long)chunk)>>1;
219 *left = ((signed long)chunk)>>1;
221 if (bytes==2 && channels==2)
224 *codec = CODEC_STEREO;
226 *length = ((signed long)chunk)>>2;
228 *left = ((signed long)chunk)>>2;
230 if (bytes==1 && channels==1)
235 *length = (signed long)chunk;
237 *left = (signed long)chunk;
242 PERROR("File %s Is not MONO8, MONO16 nor STEREO16.\n", filename);
248 // PDEBUG(DEBUG_PORT, "Unknown chunk '%c%c%c%c'\n",buffer[0],buffer[1],buffer[2],buffer[3]);
249 while(chunk > sizeof(buffer))
251 read(fh, buffer, sizeof(buffer));
252 chunk -= sizeof(buffer);
255 read(fh, buffer, chunk);
263 PERROR("File %s No fmt chunk found in file.\n", filename);
268 PERROR("File %s No data chunk found in file.\n", filename);
277 * read from tone, check size
278 * the len must be the number of samples, NOT for the bytes to read!!
279 * the data returned is law-code
281 int read_tone(int fh, unsigned char *buffer, int codec, int len, signed long size, signed long *left, int speed)
285 signed short buffer16[len], *buf16 = buffer16;
286 signed short buffer32[len<<1], *buf32 = buffer32;
287 unsigned char buffer8[len], *buf8 = buffer8;
290 //printf("left=%ld\n",*left);
292 /* if no *left is given (law has unknown length) */
298 offset = ((len&(~4)) * (speed-1));
299 lseek(fh, offset, SEEK_CUR); /* step fowards, backwards (len must be round to 4 bytes, to be sure, that 16bit stereo will not drift out of sync)*/
300 *left -= offset; /* correct the current bytes left */
324 l = read(fh, buffer, len); /* as is */
328 l = read(fh, buf16, len<<1);
339 *buffer++ = audio_s16_to_law[sample & 0xffff];
347 l = read(fh, buf32, len<<2);
353 sample = (*buf32++) + (*buf32++);
358 *buffer++ = audio_s16_to_law[sample & 0xffff];
367 l = read(fh, buf8, len);
372 *buffer++ = audio_s16_to_law[(((*buf8++)<<8)-0x8000) & 0xffff];
380 FATAL("codec %d is not supported.\n", codec);
389 struct toneset *toneset_first = NULL;
394 void free_tones(void)
396 struct toneset *toneset_temp;
397 struct tonesettone *tonesettone_temp;
400 toneset_temp = toneset_first;
403 tonesettone_temp = toneset_temp->first;
404 while(tonesettone_temp)
406 temp = tonesettone_temp;
407 tonesettone_temp = tonesettone_temp->next;
408 FREE(temp, sizeof(struct tonesettone));
412 toneset_temp = toneset_temp->next;
413 FREE(temp, sizeof(struct toneset));
416 toneset_first = NULL;
420 * fetch tones as specified in options.conf
422 int fetch_tones(void)
425 struct dirent *dirent;
426 struct toneset **toneset_nextpointer;
427 struct tonesettone **tonesettone_nextpointer;
430 char filename[256], name[256];
433 signed long tone_size, tone_left;
434 unsigned long memory = 0;
438 if (!options.fetch_tones)
441 toneset_nextpointer = &toneset_first;
442 p = options.fetch_tones;
460 /* remove trailing / */
461 if (*p) if (p[strlen(p)-1] == '/')
462 p[strlen(p)-1] = '\0';
464 printf("PBX: Fetching tones '%s'\n", p);
465 PDEBUG(DEBUG_PORT, "fetching tones directory '%s'\n", p);
467 *toneset_nextpointer = (struct toneset *)MALLOC(sizeof(struct toneset));
469 memory += sizeof(struct toneset);
470 SCPY((*toneset_nextpointer)->directory, p);
471 tonesettone_nextpointer = &(*toneset_nextpointer)->first;
473 SPRINT(path, "%s/%s", INSTALL_DATA, p);
477 PERROR("Tone set not found: '%s'\n", path);
481 while((dirent=readdir(dir)))
483 SPRINT(name, "%s", dirent->d_name);
485 /* remove .isdn and .wave */
486 if (strlen(name) >= 4)
488 if (!strcmp(name+strlen(name)-4, ".wav"))
489 name[strlen(name)-4] = '\0';
491 if (strlen(name) >= 5)
493 if (!strcmp(name+strlen(name)-5, ".isdn"))
494 name[strlen(name)-5] = '\0';
497 SPRINT(filename, "%s/%s", path, name);
500 if (!strcmp(dirent->d_name, "."))
502 if (!strcmp(dirent->d_name, ".."))
506 fh = open_tone(filename, &tone_codec, &tone_size, &tone_left);
509 PERROR("Cannot open file: '%s'\n", filename);
516 PERROR("File has 0-length: '%s'\n", filename);
523 *tonesettone_nextpointer = (struct tonesettone *)MALLOC(sizeof(struct tonesettone)+tone_size);
525 //printf("tone:%s, %ld bytes\n", name, tone_size);
526 memory += sizeof(struct tonesettone)+tone_size;
530 read_tone(fh, (*tonesettone_nextpointer)->data, tone_codec, tone_size, tone_size, &tone_left, 1);
531 (*tonesettone_nextpointer)->size = tone_size;
532 (*tonesettone_nextpointer)->codec = (tone_codec==CODEC_LAW)?CODEC_LAW:CODEC_MONO;
533 SCPY((*tonesettone_nextpointer)->name, name);
538 tonesettone_nextpointer = &((*tonesettone_nextpointer)->next);
541 toneset_nextpointer = &((*toneset_nextpointer)->next);
545 printf("PBX: Memory used for tones: %ld bytes (%d samples)\n", memory, samples);
546 PDEBUG(DEBUG_PORT, "Memory used for tones: %ld bytes (%d samples)\n", memory, samples);
553 * opens the fetched tone (if available)
555 void *open_tone_fetched(char *dir, char *file, int *codec, signed long *length, signed long *left)
557 struct toneset *toneset;
558 struct tonesettone *tonesettone;
560 /* if anything fetched */
565 toneset = toneset_first;
568 //printf("1. comparing '%s' with '%s'\n", toneset->directory, dir);
569 if (!strcmp(toneset->directory, dir))
571 toneset = toneset->next;
577 tonesettone = toneset->first;
580 //printf("2. comparing '%s' with '%s'\n", tonesettone->name, file);
581 if (!strcmp(tonesettone->name, file))
583 tonesettone = tonesettone->next;
588 /* return information */
590 *length = tonesettone->size;
592 *left = tonesettone->size;
594 *codec = tonesettone->codec;
595 //printf("size=%ld, data=%08x\n", tonesettone->size, tonesettone->data);
596 return(tonesettone->data);
601 * read from fetched tone, check size
602 * the len must be the number of samples, NOT for the bytes to read!!
604 int read_tone_fetched(void **fetched, void *buffer, int len, signed long size, signed long *left, int speed)
607 //printf("left=%ld\n",*left);
609 /* if no *left is given (law has unknown length) */
619 memcpy(buffer, *fetched, len);
620 *((char **)fetched) += len;