From - Thu May 1 18:48:12 1997 Path: news.unizar.es!news.rediris.es!news.uoregon.edu!tezcat!cam-news-hub1.bbnplanet.com!cpk-news-hub1.bbnplanet.com!news.bbnplanet.com!howland.erols.net!newshub2.home.com!newshub1.home.com!news.home.com!enews.sgi.com!news.corp.sgi.com!news.sgi.com!gazette.engr.sgi.com!candiru!cook From: cook@candiru.engr.sgi.com (Doug Cook) Newsgroups: comp.sys.sgi.audio Subject: Re: audio normalization Date: 28 Apr 1997 17:55:07 GMT Organization: Silicon Graphics, Inc. Mountain View, CA Lines: 158 Message-ID: <5k2o9r$l2r@gazette.engr.sgi.com> References: <5k1c2s$gg0@news.jhu.edu> NNTP-Posting-Host: candiru.engr.sgi.com Xref: news.unizar.es comp.sys.sgi.audio:1316 In article <5k1c2s$gg0@news.jhu.edu>, robodude@jhunix.hcf.jhu.edu writes: > > Is there a program available for SGIs that will normalize audio? I'm > talking about a utility like sox that should consume very little memory. I > realize that even soundeditor normalizes audio; unfortunately it requires > far too much ram. An efficient program should require very little ram if > it is allowed multiple passes through a sound file, so I assume that > soundeditor is trying to edit the entire sample at once. I was hoping that > sox did this, but it (at least version 10.x) doesn't. Just hacked this up. Haven't tested it thoroughly. Should work with pretty much any audio file in any format. Here are the compilation flags: cc -O -o normalize normalize.c -laudiofile -ldmedia -Doug #include #include #include #define NFRAMES_PER_READ 100000 /* * A simple program to normalize an audio file. * * Doug Cook * Silicon Graphics, Inc. 1997 * * Limitations: * Will get fooled if the only '.' in a pathname is not a filename suffix * (i.e. "./test" will make it unhappy). * Always converts the whole file: no way to specify a range of interest. */ main(int argc, char **argv) { char *filename; char string[MAXPATHLEN]; AFfilehandle infile; AFfilehandle outfile; AFfilesetup filesetup; int nchans; char *nullstr = ""; int i,j; char *dot,*suffix; double samprate; double *inbuf,*outbuf; int fmt; double max = 0.0; double scale; if (argc != 2) { fprintf(stderr,"Usage:%s \n",argv[0]); exit(-1); } filename = argv[1]; infile = afOpenFile(filename,"r",NULL); if (!infile) { fprintf(stderr,"Failed to open file %s\n",filename); exit(-1); } /* * Look for a suffix in the filename. This is a pretty * simplistic way of doing this. */ if (dot = strrchr(filename,'.')) { *dot = 0; suffix = dot+1; } else { suffix = nullstr; } nchans = afGetChannels(infile,AF_DEFAULT_TRACK); fmt = afGetFileFormat(infile,0); samprate = afGetRate(infile,AF_DEFAULT_TRACK); afSetVirtualSampleFormat(infile, AF_DEFAULT_TRACK, AF_SAMPFMT_DOUBLE, 32); inbuf = malloc(NFRAMES_PER_READ * nchans*sizeof(double)); if (!inbuf) { fprintf(stderr,"Unable to allocate memory buffer\n"); exit(-1); } outbuf = malloc(NFRAMES_PER_READ*nchans*sizeof(double)); if (!outbuf) { fprintf(stderr,"Unable to allocate memory buffer\n"); exit(-1); } filesetup = afNewFileSetup(); afInitFileFormat(filesetup, fmt); afInitChannels(filesetup, AF_DEFAULT_TRACK, nchans); afInitRate(filesetup, AF_DEFAULT_TRACK, samprate); sprintf(string, "%s_norm.%s",filename,suffix); printf("creating %s\n",string); outfile = afOpenFile(string,"w",filesetup); if (!outfile) { fprintf(stderr,"Open failed for %s\n",string); exit(-1); } afSetVirtualSampleFormat(outfile, AF_DEFAULT_TRACK, AF_SAMPFMT_DOUBLE, 32); /* * pass 1: find the maximum sample value in the file. */ while (1) { int nread; nread = afReadFrames(infile, AF_DEFAULT_TRACK, inbuf, NFRAMES_PER_READ); if (!nread) { break; } for (i = 0; i < nchans*nread; i++) { double samp; samp = inbuf[i]; if (samp < 0) samp = -samp; if (samp > max) max = samp; } } printf("max = %llf\n", max); scale = 1.0 / max; /* return to beginning of input file */ afSeekFrame(infile, AF_DEFAULT_TRACK, 0); /* * pass 2: normalize. */ while (1) { int nread; nread = afReadFrames(infile, AF_DEFAULT_TRACK, inbuf, NFRAMES_PER_READ); if (!nread) { break; } for (i = 0; i < nchans*nread; i++) { double samp; samp = inbuf[i]; outbuf[i] = samp * scale; } afWriteFrames(outfile, AF_DEFAULT_TRACK,outbuf, nread); } afCloseFile(infile); afCloseFile(outfile); }