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.