ftp.nice.ch/pub/next/audio/editor/SndEdToBuzz.1.5.N.bs.tar.gz#/snded/energy.c

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.