This is energy.c in view mode; [Download] [Up]
/*------------------------------------------------------------------------------ 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); } }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.