⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sound.c

📁 LastWave
💻 C
📖 第 1 页 / 共 3 页
字号:
    Errorf("SoundRead : You should specify at least 1 signal");  if (start <= 0 && flagSample) start = 1;  if (start <= 0 && !flagSample) start = 0;      /* Does the file exist ? */  stream = FOpen(file,"r");  if (stream == NULL)     Errorf("SoundRead : File '%s' does not exist",file);  FClose(stream);    f = ConvertFilename(file);    /* This is the case the raw format has been forced   and all the parameters specified */  if (sf1 != NULL) {    if (sf1->nChannels == 0) {      if (sig1 == NULL) sf1->nChannels = 1;      else sf1->nChannels = 2;    }    if (sf1->nChannels <= 0) Errorf("SoundRead() : The number of channels should be strictly positive");    if (sf1->samplingRate == 0) sf1->samplingRate = 1;    if (sf1->samplingRate <= 0) Errorf("SoundRead() : The samplingRate should be strictly positive");    sf.samplingRate = info.samplerate = sf1->samplingRate;    sf.nChannels = info.channels = sf1->nChannels;    info.pcmbitwidth = sf1->basicSoundFormat->bitWidth;    info.format = sf1->basicSoundFormat->format;    sf.basicSoundFormat = sf1->basicSoundFormat;    if ((sndfile = sf_open_read(f,&info)) == NULL)       Errorf("SoundRead() : Cannot read the file using the raw format you specified",file);    sf_close(sndfile);    size = info.samples;    }  /* Otherwise we first read the information to know     if the file is readable (using the extension if necessary) */  else {    if (SoundInfo(file, &sf, &size) == NO) Errorf1("");    info.samplerate = sf.samplingRate;    info.format = sf.basicSoundFormat->format;    info.pcmbitwidth = sf.basicSoundFormat->bitWidth;    info.channels = sf.nChannels;  }  /* Convert the start and duration variables into number of samples */  if (flagSample == NO) {    first = (int) (start*sf.samplingRate+1+.5);    sizeAsked = (int) (duration*sf.samplingRate+.5);  }  else {    first = (int) (start+.5);    sizeAsked = (int) (duration+.5);  }  /* Compute the number of samples to read */  if (sizeAsked <= 0) sizeAsked = size;  sizeAsked = MIN((sizeAsked+first-1),(size));  sizeAsked = sizeAsked-first+1;      /* Some checkings */  if (sf.nChannels == 1 && sig1 != NULL) {    Errorf("SoundRead() : Sorry, the sound file '%s' has just one channel",file);  }  if (first > size) {    if (flagSample) Errorf("SoundRead() : Sorry, the sound file '%s' is too short for <start>=%d samples",file,first);    else  Errorf("SoundRead() : Sorry, the sound file '%s' is too short for <start>=%g seconds",file,start);  }    /* Set some variables */  samplingRate = sf.samplingRate;  nChannels = sf.nChannels;      /* Special case of the LastWave format */  if ((sf.basicSoundFormat->format & SF_FORMAT_TYPEMASK) == SF_FORMAT_LW) {    ReadSigFile(sig,file,first-1,sizeAsked,0,0);    sig->x0 = 0;    sig->dx = 1./samplingRate;    if (flagNormalize) {      xMin = 1;      xMax = -1;      MinMaxSig(sig,&xMin,&xMax,&yMin,&yMax,&iMin,&iMax,NO);      yMax = MAX(fabs(yMax),fabs(yMin));      for (i=0;i<sig->size;i++) sig->Y[i] /= yMax;    }         return;  }      /* Look for the first sample */  if ((sndfile = sf_open_read(f,&info)) == NULL) Errorf("SoundRead() : Weird error");  if (sf_seek(sndfile,(first-1)*nChannels,SEEK_SET)==-1) {    sf_close(sndfile);    Errorf("SoundRead() : Weird error : Problem for seeking sample number '%d' of sound file %f",first,file);    return;  }    /* Allocate a double array and read the sound in it */  sound = DoubleAlloc(sizeAsked*nChannels);    sizeAsked = sf_read_double(sndfile,sound,sizeAsked*nChannels,flagNormalize)/nChannels;    /* Close the file */  sf_close(sndfile);    /* Error while reading ? */  if (sizeAsked == -1) {    Free(sound);    Errorf("SoundRead() : problem while reading sound file '%f'",file);  }        /* Fill up the signal(s) */  if (sig != NULL) {    SizeSignal(sig,sizeAsked,YSIG);    sig->x0 = 0;    sig->dx = 1./samplingRate;  }  if (sig1 != NULL && nChannels == 2) {    SizeSignal(sig1,sizeAsked,YSIG);    sig1->x0 = 0;    sig1->dx = 1./samplingRate;  }    /* Fill up the signal(s)     Case of a mono sound file read in a signal */  if (nChannels == 1) {    for (i=0;i<sizeAsked;i++) sig->Y[i] = sound[i];  }  /* Case of a multichannel sound file read in a single signal :    only the first channel is read */  else if (sig != NULL && sig1 == NULL) {     for (i=0,j=0;i<sizeAsked;i++,j+=nChannels) sig->Y[i] = sound[j];  }  /* or only the second channel is read ???????	  */  else if (sig == NULL && sig1 != NULL) {     for (i=0,j=0;i<sizeAsked;i++,j+=nChannels) sig1->Y[i] = sound[j+1];  }  /* Case of a multichannel sound file read in two signals	  */  else {    for (i=0,j=0;i<sizeAsked;i++,j+=nChannels) {      sig->Y[i] = sound[j];      sig1->Y[i] = sound[j+1];    }  }    /* Free the double array */  Free(sound);}    /* * Routine for writing a sound in a file * *  file : the soundfile it will create *  sig,sig1 : the signals to read (sig1 could be NULL). Only a sound file with 1 or 2 channels is supported. *  flagNormalize : if YES then the signals will be normalized to the maximum amplitude before being written *                  if NO then 'maxNorm' is used as the maximum amplitude value.  *  maxNorm : specifies the maximum amplitude value in the case flagNormalize==NO.  *            If it is negative then the format maximum amplitude is used (e.g., [-32768,32767] for 16 bits integers). *  sf : the sound format to be used (if it is NULL then the extension of the <file> should be used to determine it) */void SoundWrite(char *file,SIGNAL sig, SIGNAL sig1, char flagNormalize, LWFLOAT maxNorm, SoundFormat *sf){  char *f;  SF_INFO info;  int samplingRate;  int size;  int nChannels;  SNDFILE *sndfile;  double *sound,maxp,maxm,max;  int i ,j;  unsigned long l;  SoundFormat *sf1;  SoundFormat soundFormat;  char *str;      if (sig == NULL) Errorf("SoundWrite() : The first signal should be specified");  if (sig1 != NULL && sig->size != sig1->size) Errorf("SoundWrite() : The two signals should have the same size");    /* Set the sampling rate and the number of channels */  samplingRate =  (int) (1/sig->dx+.5);  if (sig1 == NULL) nChannels = 1;  else nChannels = 2;    /* Case we have to use the extension to understand the format */      sf1 = sf;  if (sf1 == NULL) {    sf1 = &soundFormat;    str = strlen(file)+file;    while (str != file && *str != '.') str--;    if (*str != '.') Errorf("SoundWrite : Sorry, I cannot understand what the format you want me to use is");     if (Name2SoundFormat(str+1,sf1) == NO) Errorf("SoundWrite : Sorry, I cannot understand what the format you want me to use is");         /* Check the compatibility */    if (sf1->samplingRate != 0 && sf1->samplingRate != samplingRate)       Errorf("SoundWrite : Sorry,incompatibility between the sampling rate the format requests (%d) and the sampling rate of the signal (%d)",sf1->samplingRate,samplingRate);    if (sf1->nChannels != 0 && sf1->nChannels != nChannels)       Errorf("SoundWrite : Sorry,incompatibility between the number of channels the format requests (%d) and the number of signals (%d)",sf1->nChannels,nChannels);  }  /* Special case of LastWave format (binary) */  if ((sf1->basicSoundFormat->format & SF_FORMAT_TYPEMASK) == SF_FORMAT_LW) {    if (nChannels == 2) Errorf("SoundWrite() : Sorry, only a single channel can be used in the LastWave format");    WriteSigFile(sig,file,YES,"y",YES,"","");    return;  }  /* Open the file */        f = ConvertFilename(file);  info.samplerate = samplingRate;  info.pcmbitwidth = sf1->basicSoundFormat->bitWidth;  info.format = sf1->basicSoundFormat->format;  info.channels = nChannels;  if ((sndfile = sf_open_write(f,&info)) == NULL) Errorf("SoundWrite() : Cannot open sound file '%s'",file);    /* Write in the case of a single signal */  if (sig1 == NULL) {    sound = DoubleAlloc(sig->size);    max = -1;    for (i = 0;i<sig->size;i++) {      sound[i] = sig->Y[i];      if (fabs(sound[i])>max) max = fabs(sound[i]);    }    if (flagNormalize || maxNorm > 0) {      l = 1;      if (flagNormalize) {        maxm = max/(l<<(sf1->basicSoundFormat->bitWidth-1));        maxp = max/((l<<(sf1->basicSoundFormat->bitWidth-1))-1);      }      else {        maxm = maxNorm/(l<<(sf1->basicSoundFormat->bitWidth-1));        maxp = maxNorm/((l<<(sf1->basicSoundFormat->bitWidth-1))-1);      }      for (i = 0;i<sig->size;i++) {        if (sound[i]>=0) sound[i] /= maxp;        else sound[i] /= maxm;      }    }       size = sf_write_double(sndfile,sound,sig->size,0);    Free(sound);    sf_close(sndfile);    if (size == -1) Errorf("SoundWrite() : Problem while writing sound file '%s'",file);    return;  }    /* Write in the case of 2 signals */  sound = DoubleAlloc(sig->size*2);  max = -1;  for (i = 0,j=0;i<sig->size;i++,j+=2) {    sound[j] = sig->Y[i];    sound[j+1] = sig1->Y[i];    if (fabs(sound[j])>max) max = fabs(sound[j]);    if (fabs(sound[j+1])>max) max = fabs(sound[j+1]);  }  if (flagNormalize || maxNorm > 0) {    l = 1;    if (flagNormalize) {      maxm = max/(l<<(sf1->basicSoundFormat->bitWidth-1));      maxp = max/((l<<(sf1->basicSoundFormat->bitWidth-1))-1);    }    else  {      maxm = maxNorm/(l<<(sf1->basicSoundFormat->bitWidth-1));      maxp = maxNorm/((l<<(sf1->basicSoundFormat->bitWidth-1))-1);    }    for (i = 0;i<2*sig->size;i++) {      if (sound[i]>=0) sound[i] /= maxp;      else sound[i] /= maxm;    }  }     size = sf_write_double(sndfile,sound,sig->size*2,0);  Free(sound);  sf_close(sndfile);  if (size == -1) Errorf("SoundWrite : Problem while writing sound file '%s'",file);}    /* REMI : ANSI interface to the SoundWrite function		  */void SoundWriteSamples(char *file,short *samplesLeft, short *samplesRight,unsigned long nbSamples, LWFLOAT sampleFreq,SoundFormat *sf){  static SIGNAL sigLeft  = NULL;  static SIGNAL sigRight = NULL;  unsigned long i;  /* Allocates the signals, only once */  if(sigLeft == NULL) {    sigLeft  = NewSignal();    sigRight = NewSignal();  }  /* Sets the size and copies the samplesLeft */  SizeSignal(sigLeft,nbSamples,YSIG);  for(i = 0; i < nbSamples; i++) {    sigLeft->Y[i] = samplesLeft[i];  }  if(sampleFreq < 2000) {    Warningf("SoundWriteSamples: Sampling rate %f Hz is below 2000 Hz, I changed it to 2000 Hz\n",sampleFreq);    sigLeft->dx = 1/2000;  }   else {    sigLeft->dx = 1/sampleFreq;  }    /* To play on one channel	   */  if(samplesRight == NULL) {    SoundWrite(file,sigLeft,NULL,YES,0.0,sf);  }  else {    SizeSignal(sigRight,nbSamples,YSIG);    for(i = 0; i < nbSamples; i++) {      sigRight->Y[i] = samplesRight[i];    }    sigRight->dx = sigLeft->dx;    SoundWrite(file,sigLeft,sigRight,YES,0.0,sf);  }}/*  * Play a sound which is represented by a 'signal'. * If 'sampleFreq' <= 0 then the dx of the signal is used * to compute the sample frequency otherwise 'sampleFreq' is used. * If 'flagMaxVolume' is YES then the signal is normalized to 1 before played * otherwise it is kept as it is (the values are supposed to be between -1 and 1). */void SoundPlay(SIGNAL sigLeft,SIGNAL sigRight,char flagMaxVolume, LWFLOAT sampleFreq){  LWFLOAT max;  int i;  short *samplesLeft,*samplesRight;  LWFLOAT t;  if(sigRight && (sigLeft->size!=sigRight->size))    Errorf("SoundPlay : the two channels have a different number of samples!");  /* Compute the max of the signal if normalization is needed */  if (flagMaxVolume) {    max = 0;    for(i=0;i<sigLeft->size;i++) {      max = MAX(max,fabs(sigLeft->Y[i]));    }    /* REMI : normalization of stereo signal */    if (sigRight) {      for(i=0;i<sigLeft->size;i++) {	max = MAX(max,fabs(sigRight->Y[i]));      }    }  }  else max = 1;  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -