[Asterisk-Users] Asterisk Native Sound Distortion (ulaw)

John Marvin jm-asterisk at themarvins.org
Tue Sep 12 05:50:13 MST 2006


shadowym wrote:

> I found that the distortion was consistent.  In other words it happened in
> the same way at the same time in a particular file.  I suspect it has
> something to do with how Asterisk plays it back and not any sort of
> hardware/IDE/interrupt issue.  Kris, the developer of Astlinux didn't seem
> to have any ideas why it would not work as well on Asterisk either.

If the distortion is consistant as you say, then you are probably seeing 
the same problem I found a workaround for.

I was disappointed in the sound quality of the gsm files, so I was happy 
to find the Native Sounds files. However, I then ran into the clicks and 
pops when playing them. Reading some of the earlier comments in this 
discussion someone mentioned an issue with Asterisk not padding files to 
even 20ms increments when playing them. So, although that may be a bug 
in Asterisk, I thought I would see if that was the problem by writing a 
quick C program to pad all my ulaw files to multiples of 160 bytes. 
Voila, all clicks and pops were gone. So, I don't know if that is the 
only issue, and perhaps there are other problems people are having, but 
padding the files fixed the issue for me. Obviously this should be fixed 
in Asterisk.

If anyone else wants to try this experiment I've enclosed the simple C 
program I wrote below. If you compile it and call it padulaw here is how 
I fixed all the files:

find /var/lib/asterisk/sounds -type f -name '*.ulaw' | xargs padulaw

This program could be easily modified to pad .sln files to a multiple of 
320 bytes (the files would be padded with 0x0000 rather than 0xff).

John

#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>

#define ULAW_SILENCE 0xff
#define MS20_BYTES  160

unsigned char silence[MS20_BYTES];

void pad_file(char *);

main(int argc, char **argv)
{
     int i;
     int nfiles;

     if (argc < 2) {
         fprintf(stderr,"Usage: %s <file name> ...\n",argv[0]);
         exit(1);
     }

     nfiles = argc - 1;
     for (i = 0; i < nfiles; i++) {
         pad_file(argv[i+1]);
     }

     exit(0);
}

void
pad_file(char *fname)
{
     int fd;
     int i;
     struct stat sbuf;
     int filesize;
     int remainder;
     int nwrite;

     fd = open(fname,O_WRONLY|O_APPEND);
     if (fd < 0) {
         fprintf(stderr,"Could not open %s for writing.\n",fname);
         return;
     }

     if (fstat(fd,&sbuf) != 0) {
         fprintf(stderr,"Could not stat file %s.\n",fname);
         return;
     }

     filesize = (int) sbuf.st_size;
     remainder = filesize % MS20_BYTES;
     if (remainder == 0) {
         close(fd);
         return;
     }

     nwrite = MS20_BYTES - remainder;
     for (i = 0; i < nwrite; i++)
         silence[i] = (unsigned char)ULAW_SILENCE;

     if (write(fd,(void *)silence,nwrite) != nwrite) {
         fprintf(stderr,"Write Failure on file %s\n",fname);
         return;
     }

     close(fd);
     return;
}


More information about the asterisk-users mailing list