📄 sound.c
字号:
/* Compute sample frequency */ if (sampleFreq <= 0) sampleFreq = 1/sigLeft->dx; /* Allocation of array of short */ samplesLeft = (short *) Malloc(sizeof(short)*sigLeft->size); for(i=0;i<sigLeft->size;i++) samplesLeft[i] = (int) (32767*((sigLeft->Y[i])/max)); /* One or two channels ? */ if (sigRight==NULL) samplesRight=NULL; else { samplesRight = (short *) Malloc(sizeof(short)*sigLeft->size); for(i=0;i<sigLeft->size;i++) samplesRight[i] = (int) (32767*((sigRight->Y[i])/max)); } /* Then play it */ XXSoundPlay(samplesLeft,samplesRight,sigLeft->size,sampleFreq); /* Desallocation */ Free(samplesLeft); if(samplesRight) Free(samplesRight);}/* * Stop a currently playing sound */void SoundStop(void){ XXSoundStopPlaying();}/* * Recording a mono sound into 'signalLeft' or a stereo sound into 'signalLeft' and 'signalRight'. * See the help of XXSoundRecord. * Returns YES if a sound was recorded and NO otherwise. */char SoundRecord(SIGNAL sigLeft,SIGNAL sigRight, unsigned char soundQuality, unsigned long customSampleFreq,unsigned char customBitsPerSample, unsigned long maxNbSamples){ unsigned long nbSamples; LWFLOAT sampleFreq; /* Empty the signals */ ClearSignal(sigLeft); if(sigRight) ClearSignal(sigRight); /* Record sound */ if(sigRight==NULL) { XXSoundRecord(&(sigLeft->Y),NULL, &nbSamples,&sampleFreq, soundQuality, customSampleFreq,customBitsPerSample, maxNbSamples); } else { XXSoundRecord(&(sigLeft->Y),&(sigRight->Y), &nbSamples,&sampleFreq, soundQuality, customSampleFreq,customBitsPerSample, maxNbSamples); } /* Case when nothing was recorded */ if (nbSamples == 0) return(NO); /* Init signal fields */ sigLeft->sizeMallocY = nbSamples; sigLeft->size = nbSamples; sigLeft->dx = 1./sampleFreq; sigLeft->x0 = 0; sigLeft->firstp = 0; sigLeft->type = YSIG; sigLeft->lastp = nbSamples-1; if(sigRight!=NULL) { sigRight->sizeMallocY = nbSamples; sigRight->size = nbSamples; sigRight->dx = 1./sampleFreq; sigRight->x0 = 0; sigRight->firstp = 0; sigRight->type = YSIG; sigRight->lastp = nbSamples-1; } return(YES);}void C_Sound(char **argv){ char *action; char *file,*format; int size; SoundFormat sf,*sf1; SIGNAL sigLeft=NULL,sigRight=NULL; LWFLOAT duration,start; /* Only for recording */ unsigned long maxNbSamples = 0; unsigned char soundQuality; unsigned long customSampleFreq = 0; unsigned char customBitsPerSample = 16; LWFLOAT fCustomSampleFreq = 0.0; int first,sizeAsked; char flagNormalize,flagSample,flagMaxVolume; char opt; char *str; int i,j; int samplingRate; LWFLOAT max; LISTV lv; argv = ParseArgv(argv,tWORD,&action,-1); if (!strcmp(action,"info")) { argv = ParseArgv(argv,tSTR,&file,0); if (SoundInfo(file, &sf, &size)==NO) Errorf1(""); lv = TNewListv(); SetResultValue(lv); AppendInt2Listv(lv,size); AppendInt2Listv(lv,sf.samplingRate); AppendInt2Listv(lv,sf.nChannels); AppendStr2Listv(lv,sf.basicSoundFormat->name); return; } if(!strcmp(action,"read")) { argv = ParseArgv(argv,tSIGNAL,&sigLeft,tSIGNAL_,NULL,&sigRight,tSTR,&file,-1); if (*argv != NULL && **argv != '-') { argv = ParseArgv(argv,tSTR,&format,-1); if (strncmp(format,"raw",3)) Errorf("You must specify a 'raw' format"); if (Name2SoundFormat(format,&sf) == NO) Errorf("Invalid format '%s'",format); sf1 = &sf; } else sf1 = NULL; duration = -1; start = -1; sizeAsked = -1; first = -1; flagNormalize = YES; flagSample = NO; while ((opt = ParseOption(&argv))) { switch(opt) { case 'd': argv = ParseArgv(argv,tFLOAT,&duration,-1); if (duration <= 0) ErrorUsage(); if (first != -1 || sizeAsked != -1) Errorf("You must not use at the same time the options s,d with S,D"); break; case 'D': argv = ParseArgv(argv,tINT,&sizeAsked,-1); if (sizeAsked <= 0) ErrorUsage(); if (start != -1 || duration != -1) Errorf("You must not use at the same time the options s,d with S,D"); flagSample = YES; break; case 's': argv = ParseArgv(argv,tFLOAT,&start,-1); if (start < 0) ErrorUsage(); if (first != -1 || sizeAsked != -1) Errorf("You must not use at the same time the options s,d with S,D"); break; case 'S': argv = ParseArgv(argv,tINT,&first,-1); if (first <= 0) ErrorUsage(); if (start != -1 || duration != -1) Errorf("You must not use at the same time the options s,d with S,D"); flagSample = YES; break; case 'n': flagNormalize = NO; break; default: ErrorOption(opt); } } NoMoreArgs(argv); if (flagSample) { duration = sizeAsked; start = first; } SoundRead(file,sigLeft,sigRight,flagSample,start,duration,flagNormalize,sf1); return; } if(!strcmp(action,"write")) { argv = ParseArgv(argv,tSIGNALI,&sigLeft,tSIGNALI_,NULL,&sigRight,tSTR,&file,tSTR_,"",&format,-1); if (sigRight != NULL && sigRight->size != sigLeft->size) Errorf("The signals should have the same size"); if (*format != '\0') { if (Name2SoundFormat(format,&sf) == NO) Errorf("Unknown sound format '%s'",format); sf1 = &sf; } else sf1 = NULL; flagNormalize = YES; max = -1; while ((opt = ParseOption(&argv))) { switch(opt) { case 'n': argv = ParseArgv(argv,tFLOAT_,-1.0,&max,-1); if (max == 0) Errorf("Bad Value for <max>=%g in '-n' option",max); flagNormalize = NO; break; default: ErrorOption(opt); } } NoMoreArgs(argv); SoundWrite(file,sigLeft,sigRight,flagNormalize,max,sf1); return; } if(!strcmp(action,"format")) { argv = ParseArgv(argv,tSTR_,"*",&str,-1); if (*argv == NULL) { for (i=0;theBasicSoundFormats[i].name !=NULL;i++) { if (MatchStr(theBasicSoundFormats[i].name,str)) { Printf("%s",theBasicSoundFormats[i].name); for (j=15;j>=strlen(theBasicSoundFormats[i].name);j--) Printf(" "); Printf(": %s\n",theBasicSoundFormats[i].info); } } for (i=0;i<nSoundFormats;i++) { if (MatchStr(theSoundFormats[i].name,str)) { Printf("%s",theSoundFormats[i].name); for (j=15;j>=strlen(theSoundFormats[i].name);j--) Printf(" "); Printf(": %s\n",theSoundFormats[i].basicSoundFormat->name); } } } else { argv = ParseArgv(argv,tSTR,&format,0); if (Name2SoundFormat(format,&sf) == NO) Errorf("Sorry, I don't know the sound format '%s'",format); for (i=0;i<nSoundFormats;i++) { if (!strcmp(theSoundFormats[i].name,str)) break; } if (i == nSoundFormats) { if (nSoundFormats == NMAXSF-1) Errorf("Sorry, too many formats already defined (maximum is %d).",NMAXSF); i = nSoundFormats; nSoundFormats++; theSoundFormats[i].name = CopyStr(str); } theSoundFormats[i].basicSoundFormat = sf.basicSoundFormat; theSoundFormats[i].samplingRate = sf.samplingRate; theSoundFormats[i].nChannels = sf.nChannels; } return; } if (!strcmp(action,"play")) { /* argv = ParseArgv(argv,tSIGNALI,&sigLeft,tSIGNALI_,NULL,&sigRight,tINT_,-1,&samplingRate,-1); */ argv = ParseArgv(argv,tSIGNALI,&sigLeft,-1); argv = ParseArgv(argv,tSIGNALI_,NULL,&sigRight,-1); argv = ParseArgv(argv,tINT_,-1,&samplingRate,-1); flagMaxVolume = YES; while(opt = ParseOption(&argv)) { switch(opt) { case 'n': flagMaxVolume = NO; break; default: ErrorOption(opt); } } NoMoreArgs(argv); Printf("Starts playing...");Flush(); SoundPlay(sigLeft,sigRight,flagMaxVolume,samplingRate); Printf("Done\n"); return; } if (!strcmp(action,"record")) { /* Read the first signal */ argv = ParseArgv(argv,tSIGNAL,&sigLeft,-1); /* We interpret the next argument as a signal, if possible */ ParseArgv(argv,tSIGNAL_,NULL,&sigRight,-1); /* If we did not read a signal, then we read the duration */ if (sigRight == NULL) argv = ParseArgv(argv,tFLOAT_,0.0,&duration,-1); /* If we read a signal, we may have confused <duration> with the name of a signal ! */ else { /* If we cannot read <duration> now, it means what we believed was * a valid signal name was indeed <duration>. So no signal * was given as an input ! We must correct it and read <duration> */ if (ParseFloat_(*(argv+1),0.0,&duration) == NO) { sigRight = NULL; argv = ParseArgv(argv,tFLOAT_,0.0,&duration,-1); } /* Else, we have now correctly read <sigRight> and <duration> */ else argv+=2; } /* Now we can read the quality */ argv = ParseArgv(argv,tSTR_,"cd",&str,-1); /* Determine the sound quality */ if (!strcmp(str,"cd")) { soundQuality = cdSoundQuality; NoMoreArgs(argv); } else if (!strcmp(str,"voice")) { soundQuality = voiceSoundQuality; NoMoreArgs(argv); } else if (!strcmp(str,"phone")) { soundQuality = phoneSoundQuality; NoMoreArgs(argv); } else if (!strcmp(str,"custom")) { soundQuality = customSoundQuality; /* REMI : this will be simplified when there is a tLONGINT type ! */ argv = ParseArgv(argv,tFLOAT,&fCustomSampleFreq,tINT,&customBitsPerSample,0); customSampleFreq = (unsigned long)fCustomSampleFreq; } else Errorf("Bad Sound quality '%s'",str); // For non-interactive recording, we should convert the duration to a number of samples if(duration >= 0) { switch(soundQuality) { case cdSoundQuality : maxNbSamples = (int) (duration*44100); break; case voiceSoundQuality : maxNbSamples = (int) (duration*22050); break; case phoneSoundQuality : maxNbSamples = (int) (duration*8000); break; case customSoundQuality : maxNbSamples = (int) (duration*customSampleFreq); } } else Errorf("Bad duration %g !",duration); if (SoundRecord(sigLeft,sigRight, soundQuality,customSampleFreq,customBitsPerSample, maxNbSamples)) SetResultf("1"); else SetResultf("0"); return; } if (!strcmp(action,"stop")) { SoundStop(); return; } Errorf("Bad action '%s'",action); }/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -