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 length=%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;
220 // printf("left=%d\n",*left);
222 if (bytes==2 && channels==2)
225 *codec = CODEC_STEREO;
227 *length = ((signed long)chunk)>>2;
229 *left = ((signed long)chunk)>>2;
231 if (bytes==1 && channels==1)
236 *length = (signed long)chunk;
238 *left = (signed long)chunk;
243 PERROR("File %s Is not MONO8, MONO16 nor STEREO16.\n", filename);
249 // PDEBUG(DEBUG_PORT, "Unknown chunk '%c%c%c%c'\n",buffer[0],buffer[1],buffer[2],buffer[3]);
250 while(chunk > sizeof(buffer))
252 read(fh, buffer, sizeof(buffer));
253 chunk -= sizeof(buffer);
256 read(fh, buffer, chunk);
264 PERROR("File %s No fmt chunk found in file.\n", filename);
269 PERROR("File %s No data chunk found in file.\n", filename);
278 * read from tone, check size
279 * the len must be the number of samples, NOT for the bytes to read!!
280 * the data returned is law-code
282 int read_tone(int fh, unsigned char *buffer, int codec, int len, signed long size, signed long *left, int speed)
286 signed short buffer16[len], *buf16 = buffer16;
287 signed short buffer32[len<<1], *buf32 = buffer32;
288 unsigned char buffer8[len], *buf8 = buffer8;
291 //printf("left=%ld\n",*left);
293 /* if no *left is given (law has unknown length) */
299 offset = ((len&(~4)) * (speed-1));
300 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)*/
301 *left -= offset; /* correct the current bytes left */
325 l = read(fh, buffer, len); /* as is */
329 l = read(fh, buf16, len<<1);
340 *buffer++ = audio_s16_to_law[sample & 0xffff];
348 l = read(fh, buf32, len<<2);
354 sample = (*buf32++) + (*buf32++);
359 *buffer++ = audio_s16_to_law[sample & 0xffff];
368 l = read(fh, buf8, len);
373 *buffer++ = audio_s16_to_law[(((*buf8++)<<8)-0x8000) & 0xffff];
381 FATAL("codec %d is not supported.\n", codec);
390 struct toneset *toneset_first = NULL;
395 void free_tones(void)
397 struct toneset *toneset_temp;
398 struct tonesettone *tonesettone_temp;
401 toneset_temp = toneset_first;
404 tonesettone_temp = toneset_temp->first;
405 while(tonesettone_temp)
407 temp = tonesettone_temp;
408 tonesettone_temp = tonesettone_temp->next;
409 FREE(temp, sizeof(struct tonesettone));
413 toneset_temp = toneset_temp->next;
414 FREE(temp, sizeof(struct toneset));
417 toneset_first = NULL;
421 * fetch tones as specified in options.conf
423 int fetch_tones(void)
426 struct dirent *dirent;
427 struct toneset **toneset_nextpointer;
428 struct tonesettone **tonesettone_nextpointer;
431 char filename[256], name[256];
434 signed long tone_size, tone_left;
435 unsigned long memory = 0;
439 if (!options.fetch_tones)
442 toneset_nextpointer = &toneset_first;
443 p = options.fetch_tones;
461 /* remove trailing / */
462 if (*p) if (p[strlen(p)-1] == '/')
463 p[strlen(p)-1] = '\0';
465 printf("PBX: Fetching tones '%s'\n", p);
466 PDEBUG(DEBUG_PORT, "fetching tones directory '%s'\n", p);
468 *toneset_nextpointer = (struct toneset *)MALLOC(sizeof(struct toneset));
470 memory += sizeof(struct toneset);
471 SCPY((*toneset_nextpointer)->directory, p);
472 tonesettone_nextpointer = &(*toneset_nextpointer)->first;
474 SPRINT(path, "%s/%s", INSTALL_DATA, p);
478 PERROR("Tone set not found: '%s'\n", path);
482 while((dirent=readdir(dir)))
484 SPRINT(name, "%s", dirent->d_name);
486 /* remove .isdn and .wave */
487 if (strlen(name) >= 4)
489 if (!strcmp(name+strlen(name)-4, ".wav"))
490 name[strlen(name)-4] = '\0';
492 if (strlen(name) >= 5)
494 if (!strcmp(name+strlen(name)-5, ".isdn"))
495 name[strlen(name)-5] = '\0';
498 SPRINT(filename, "%s/%s", path, name);
501 if (!strcmp(dirent->d_name, "."))
503 if (!strcmp(dirent->d_name, ".."))
507 fh = open_tone(filename, &tone_codec, &tone_size, &tone_left);
510 PERROR("Cannot open file: '%s'\n", filename);
517 PERROR("File has 0-length: '%s'\n", filename);
524 *tonesettone_nextpointer = (struct tonesettone *)MALLOC(sizeof(struct tonesettone)+tone_size);
526 //printf("tone:%s, %ld bytes\n", name, tone_size);
527 memory += sizeof(struct tonesettone)+tone_size;
531 read_tone(fh, (*tonesettone_nextpointer)->data, tone_codec, tone_size, tone_size, &tone_left, 1);
532 (*tonesettone_nextpointer)->size = tone_size;
533 (*tonesettone_nextpointer)->codec = (tone_codec==CODEC_LAW)?CODEC_LAW:CODEC_MONO;
534 SCPY((*tonesettone_nextpointer)->name, name);
539 tonesettone_nextpointer = &((*tonesettone_nextpointer)->next);
542 toneset_nextpointer = &((*toneset_nextpointer)->next);
546 printf("PBX: Memory used for tones: %ld bytes (%d samples)\n", memory, samples);
547 PDEBUG(DEBUG_PORT, "Memory used for tones: %ld bytes (%d samples)\n", memory, samples);
554 * opens the fetched tone (if available)
556 void *open_tone_fetched(char *dir, char *file, int *codec, signed long *length, signed long *left)
558 struct toneset *toneset;
559 struct tonesettone *tonesettone;
561 /* if anything fetched */
566 toneset = toneset_first;
569 //printf("1. comparing '%s' with '%s'\n", toneset->directory, dir);
570 if (!strcmp(toneset->directory, dir))
572 toneset = toneset->next;
578 tonesettone = toneset->first;
581 //printf("2. comparing '%s' with '%s'\n", tonesettone->name, file);
582 if (!strcmp(tonesettone->name, file))
584 tonesettone = tonesettone->next;
589 /* return information */
591 *length = tonesettone->size;
593 *left = tonesettone->size;
595 *codec = tonesettone->codec;
596 //printf("size=%ld, data=%08x\n", tonesettone->size, tonesettone->data);
597 return(tonesettone->data);
602 * read from fetched tone, check size
603 * the len must be the number of samples, NOT for the bytes to read!!
605 int read_tone_fetched(void **fetched, void *buffer, int len, signed long size, signed long *left, int speed)
608 //printf("left=%ld\n",*left);
610 /* if no *left is given (law has unknown length) */
620 memcpy(buffer, *fetched, len);
621 *((char **)fetched) += len;