home *** CD-ROM | disk | FTP | other *** search
- /*------------------------------------------------------------------------------
- ENERGY CALCULATION
-
- This file contains procedures for computing the energy from a sound file and creating a new
- sound file which is used to display the energy the same way sounds themselves are displayed.
-
- Usage: (void) energy("<file>.snd")
- This creates a new sound file "<file>.snd.energy"
- ------------------------------------------------------------------------------*/
-
- #import <stdio.h>
- #import <math.h>
- #import <sound/sound.h>
- #import "globals.h"
-
- /* number of mu-law values over which to compute the energy for a period of 10ms */
- #define N (FRAME_SIZE * 3)
-
- /* constant used to discriminate between 16-bit linear signal values */
- #define DISCRIMINANT 5000
-
- /*----------------------------------------------------------------
- Take array of original 8 bit coded mu-law signals (originalSound), extract
- signal and transform each element to 16 bit linear for calculating the energy
- then transform the elements back in 8 bit coded mu-law signal (newSound)
- ----------------------------------------------------------------*/
- void
- soundToEnergyToSound(originalSound,newSound,newSoundSize)
- int newSoundSize;
- unsigned char
- *originalSound,/*pointer to contents of original sound file */
- *newSound;/* pointer to contents of new sound file to be created */
- {
- int j;
- /* compute average energy for all frames */
- for(j=0;j<newSoundSize;j+=1)
- {
- register double sumEnergy=0;
- {
- /* compute the sum of the energy over three frames for frame number j */
- register int i,supLimit;
- for(i=j*FRAME_SIZE,supLimit=i+N;i<supLimit;++i)
- sumEnergy+=abs(SNDiMulaw(originalSound[i]));
- }
- {
- register double averageEnergy=sumEnergy/N; /* compute average energy for frame j */
-
- /* multiply the energy by a large constant after having taken the
- log of it in order that SNDMulaw be able to discriminate the values
- of the energy for different frames (i.e. different values of j) */
-
- averageEnergy=averageEnergy>1 ? DISCRIMINANT * log10(averageEnergy) : 0;
-
- /* convert energy for frame j back to sound and store it in an array;
- this will be stored in a sound file later */
- {
- unsigned char energyToSound=SNDMulaw(averageEnergy),
- *mulawArray=newSound+j*FRAME_SIZE;
- int i;
- for(i=0;i<FRAME_SIZE;++i) mulawArray[i]=energyToSound;
- }
- }
- }
- }
- /* take a string of the form "string.snd" and return a string of the form "string.snd.energy" */
- char
- *addSuffix(soundFileName)
- char *soundFileName;
- {
- extern int strlen(); extern char *strcpy(),*strcat();
- int length=strlen(soundFileName);
- char *newName=(char *)malloc((length+8) * sizeof(char));
- if(newName==NULL) {fprintf(stderr,"malloc failed for new name");exit(-1);}
- strcpy(newName,soundFileName);
- newName[length]='\0';
- return (char *) strcat(newName,".energy");
- }
-
- /*----------------------------------------------------------------
- Procedure "energy" takes the name of a .snd file (ex: "forty.snd") as argument
- and creates a new file with the suffix .snd.energy (ex: "forty.snd.energy") for
- the purpose of displaying the energy the same way as sounds are displayed
- ----------------------------------------------------------------*/
- void
- energy(soundFileName)
- char *soundFileName;
- {
- SNDSoundStruct *sound;
-
- /* read sound file whose energy is to be computed */
- if(SND_ERR_NONE!=SNDReadSoundfile(soundFileName,&sound))
- {fprintf(stderr,"cannot read file");exit(-1);}
- {
- SNDSoundStruct *newSound;
- {
- /* compute size (in frames) of array which is to hold mu-law values coming from
- the conversion sound-to-energy-to-sound done in procedure soundToEnergyToSound */
- int newSoundSize=sound->dataSize/FRAME_SIZE;
- newSoundSize=newSoundSize>2 ? newSoundSize-2 : 0;
-
- /* allocate storage for new sound structure to be filled by procedure soundToEnergyToSound */
- if(SND_ERR_NONE !=SNDAlloc(
- &newSound,
- newSoundSize*FRAME_SIZE,
- SND_FORMAT_MULAW_8,
- SND_RATE_CODEC,
- 1,
- 0))
- {fprintf(stderr,"cannot allocate storage for new sound structure");exit(-1);}
-
- soundToEnergyToSound(
- (unsigned char *)((int)sound + sound->dataLocation),
- (unsigned char *)((int)newSound + newSound->dataLocation),
- newSoundSize);
- }
- {
- char *suffixAddedFileName=addSuffix(soundFileName);
-
- /* write newSound stucture (representing the display
- pattern of the energy) to file suffixAddedFile */
-
- SNDWriteSoundfile(suffixAddedFileName,newSound);
- free(suffixAddedFileName);
- }
- SNDFree(sound); SNDFree(newSound);
- }
- }
-
-