📄 haudio.c
字号:
else if (a->rc==rOR) samps=0; else HError(6006,"OutSamples: Cannot access write buffer on RS6000 audio output device"); } return ((int)samps); }#endif#ifdef SGI_AUDIO return ALgetfilled(a->playPort);#endif#ifdef SUN16_AUDIO ioctl(a->audio_ctld, AUDIO_GETINFO, &a->audio_info); /* Since play.samples can be wrong we need to fix it at the end */ if (a->audio_info.play.eof==a->numWrites) a->numSamples=a->audio_info.play.samples; return(a->numSamples-a->audio_info.play.samples);#endif#ifdef HPUX_AUDIO { long st; ATransStatus atst; atst.time.type=ATTSamples; AGetTransStatus(a->audio,a->tid,&atst,&st); if (st!=AENoError || atst.state==ATSStopped) return(0); return(a->nToPlay-atst.time.u.samples); }#endif#ifdef OSS_AUDIO if (ioctl (audio_fd, SNDCTL_DSP_SYNC, NULL) < 0) HError(6006, "InitAudo: unable to sync audio device"); return 0;#endif#ifdef NO_AUDIO return(0);#endif}/* PlayAudio: play nSamples from buf thru output device a */static void PlayAudio(AudioOut a, short *buf, int nSamples){#ifdef MMAPI_AUDIO { mmApiBuf *p,*c; int i; if (trace & T_AUD) { printf(" Playing %d samples with MMAPI audio output\n",nSamples); fflush(stdout); } /* Find end of current list */ for (c=a->pHead;c!=NULL && c->next!=NULL;c=c->next); /* Add new buffer to end of list */ p=New(a->mem,sizeof(mmApiBuf)); p->waveHdr = mmeAllocMem(sizeof(WAVEHDR)); p->cur=0; p->n=nSamples; p->next=p->prev=NULL; p->size = nSamples*sizeof(short); p->waveData = mmeAllocMem(p->size); memcpy(p->waveData,buf,p->size); p->index = (c==NULL ? 1 : c->index+1); /* Set up header */ p->waveHdr->lpData = p->waveData; p->waveHdr->dwBufferLength = p->size; p->waveHdr->dwBytesRecorded = 0; /* Unused */ p->waveHdr->dwUser = p->index; p->waveHdr->dwFlags = 0; p->waveHdr->dwLoops = 0;#ifdef WIN32_AUDIO if ((a->mmError=waveOutPrepareHeader(a->waveOut, p->waveHdr, sizeof(WAVEHDR)))!=MMSYSERR_NOERROR) HError(6006,"PlayAudo: Header preparation failed");#endif /* Add in */ a->total+=nSamples; if (c==NULL) a->pHead=a->pTail=p; else c->next=p,a->pTail=p; /* And play */ if (a->current<0) a->current=p->index; /* Playing starts now */ if((a->mmError=waveOutWrite(a->waveOut, p->waveHdr, sizeof(WAVEHDR)))!=MMSYSERR_NOERROR) HError(6006,"PlayAudo: Failed to write to audio output device"); }#endif#ifdef RS6000_AUDIO { int i; long samps=0; UMSAudioTypes_Buffer aoutBuf; /* Note that the data is stored internally as unsigned char */ aoutBuf._length = nSamples*sizeof(short); aoutBuf._maximum = nSamples*sizeof(short); aoutBuf._buffer = (unsigned char *)buf; UMSAudioDevice_start(a->adevout, a->evout); if ((a->rc = UMSAudioDevice_write(a->adevout,a->evout,&aoutBuf, nSamples,&a->sw))!=rOK) HError(6006,"PlayAudi: Cannot write to RS6000 audio output device"); }#endif#ifdef SGI_AUDIO ALwritesamps(a->playPort, buf, nSamples);#endif#ifdef SUN16_AUDIO { int n,i; char *ptr; ptr = (char *) buf; n = nSamples*sizeof(short); while (n>0) { if ((i=write(a->audio_ctld,ptr,n))<=0) HError(6006,"PlayAudio: Failed to write to Sun audio"); ptr+=i;n-=i; } write(a->audio_ctld,buf,0); /* Increments eof counter */ a->numSamples+=nSamples;a->numWrites++; }#endif#ifdef HPUX_AUDIO { int n,i; long st; AudioAttrMask mask; ATransStatus atst; if ((a->socket = socket(AF_INET,SOCK_STREAM,0))<0) HError(6006,"PlayAudio: Cannot create HP audio socket"); mask=ASDataFormatMask|ASBitsPerSampleMask|ASSamplingRateMask|ASChannelsMask| ASInterleaveMask; a->tid = APlaySStream(a->audio,mask,&a->attr,&a->parms,&a->stream,&st); if (st!=0) HError(6006,"PlayAudio: Invalid HP audio parameters"); st=connect(a->socket,&a->stream.tcp_sockaddr,sizeof(struct sockaddr_in)); n=nSamples*sizeof(short); while(n>0) { if ((i=write(a->socket,buf,n))<0) HError(6006,"PlayAudio: Only wrote %d/%d samples to HP audio", n/2,nSamples); buf+=i; n-=i; } close(a->socket); a->nToPlay=nSamples; }#endif #ifdef OSS_AUDIO { char *ptr; int k, n; n=nSamples*sizeof(short); ptr=(char*)buf; while(n>0) { if ((k=write(audio_fd, ptr, n))<=0) HError(6006,"PlayAudio: Could not write to OSS audio"); ptr+=k; n-=k; } }#endif #ifdef NO_AUDIO if(nSamples && buf[0]); /* keep compiler quiet */#endif a->isActive = TRUE;}/* SetVol: set output play level (0-1) of output device */static void SetVol(AudioOut a, float volume){ if (a==NULL) return; if (volume>1.0) volume = 1.0;#ifdef MMAPI_AUDIO { DWORD vol; vol=65535*volume;vol=((vol<<16)&0xffff0000)|(vol&0x0000ffff);#ifdef DEC_AUDIO if ((a->mmError=waveOutSetVolume(a->waveOutDev, (DWORD)vol))!=MMSYSERR_NOERROR) HError(6006,"SetVol: Failed to set MMAPI volume [ERR=%d]",a->mmError);#endif#ifdef WIN32_AUDIO /* Windows lets you set the instance volume */ if ((a->mmError=waveOutSetVolume(a->waveOut, (DWORD)vol))!=MMSYSERR_NOERROR) HError(6006,"SetVol: Failed to set MMAPI volume [ERR=%d]",a->mmError);#endif }#endif#ifdef RS6000_AUDIO UMSAudioDevice_set_volume(a->adevout,a->evout,100*volume);#endif #ifdef SGI_AUDIO a->params[3] = a->params[5] = (int)(volume*255.0); ALsetparams(AL_DEFAULT_DEVICE,a->params,6);#endif#ifdef SUN16_AUDIO a->audio_info.play.gain = (uint_t) (AUDIO_MIN_GAIN + (AUDIO_MAX_GAIN-AUDIO_MIN_GAIN)*volume); ioctl(a->audio_ctld, AUDIO_SETINFO, &a->audio_info);#endif#ifdef HPUX_AUDIO a->parms.play_volume = (AGainDB) (-100*(1.0-volume));#endif#ifdef OSS_AUDIO { int f, v; v = (int) (100.0*volume); f = (v & 0xff) | ((v & 0xff) << 8); if (ioctl(mixer_fd, MIXER_WRITE(SOUND_MIXER_PCM), &f)==-1) HError(6006, "SetVol: unable to set OSS mixer volume"); }#endif}/* -------------------- End of Device Dependent Code ----------------- *//* InitAudio: initialise this module */void InitAudio(void){ int i; Boolean b; Register(haudio_version,haudio_vc_id); numParm = GetConfig("HAUDIO", TRUE, cParm, MAXGLOBS); if (numParm>0){ if (GetConfInt(cParm,numParm,"TRACE",&i)) trace = i; if (GetConfBool(cParm,numParm,"LINEOUT",&b)) lineOut = b; if (GetConfBool(cParm,numParm,"PHONESOUT",&b)) phonesOut = b; if (GetConfBool(cParm,numParm,"SPEAKEROUT",&b)) speakerOut = b; if (GetConfBool(cParm,numParm,"LINEIN",&b)) lineIn = b; if (GetConfBool(cParm,numParm,"MICIN",&b)) micIn = b; if (GetConfInt(cParm,numParm,"VOLUMETYPE",&i)) volType = (VolType) i; }#ifdef MMAPI_AUDIO sMagic=(65535 - getpid()<<12) ^ (time(NULL));#endif}/* --------------------------- Status Handling ------------------- */static char * aiStatMap[] = { "AI_CLEARED","AI_WAITSIG", "AI_SAMPLING","AI_STOPPED", "AI_ERROR" };/* ChangeState: change state of audio input and trace if enabled */static void ChangeState(AudioIn a, AudioInStatus newState){ if (a->status != newState) { if (trace&T_STC) printf("HAudio: %s -> %s\n",aiStatMap[a->status],aiStatMap[newState]); a->status = newState; }}/* ---------------------- Replay Buffer Routines --------------------- *//* EXPORT->AttachReplayBuf: create a replay buffer in a of given size */void AttachReplayBuf(AudioIn a, int bufSize){ if (trace&T_TOP) printf("HAudio: attaching replay buffer\n"); if (a==NULL) HError(6015,"AttachReplayBuf: null audio device"); a->rbuf.isActive = TRUE; a->rbuf.inx = a->rbuf.outx = a->rbuf.used = 0; a->rbuf.size = bufSize; a->rbuf.data = (short *)New(a->mem,bufSize*sizeof(short));}/* ResetReplayBuf: reset replay buf to empty */static void ResetReplayBuf(AudioIn a){ a->rbuf.inx = a->rbuf.outx = a->rbuf.used = 0;}/* SaveInReplay: save a sample in replay buf, overwrite if nec. */static void SaveInReplay(AudioIn a, short x){ if (a->rbuf.isActive==FALSE) return; a->rbuf.data[a->rbuf.inx] = x; a->rbuf.inx = (a->rbuf.inx + 1) % a->rbuf.size; if (a->rbuf.used==a->rbuf.size) a->rbuf.outx = a->rbuf.inx; else ++a->rbuf.used;}/* EXPORT->GetReplayBuf: Get upto nSamples from replay buffer */int GetReplayBuf(AudioIn a, int nSamples, short *buf){ int i,n; if (trace&T_TOP) printf("HAudio: getting replay buffer\n"); if (a==NULL) HError(6015,"GetReplayBuf: null audio device"); if (!a->rbuf.isActive) HError(6020,"GetReplayBuf: replay buf not active"); n = (a->rbuf.used<nSamples)?a->rbuf.used:nSamples; for (i=0; i<n; i++){ buf[i] = a->rbuf.data[a->rbuf.outx]; a->rbuf.outx = (a->rbuf.outx + 1) % a->rbuf.size; --a->rbuf.used; } return n;}/* EXPORT-> PlayReplayBuffer: Output nSamples from ai's replay buffer to ao */void PlayReplayBuffer(AudioOut ao, AudioIn ai){ if (trace&T_TOP) printf("HAudio: playing replay buffer\n"); if (ai==NULL) HError(6015,"PlayReplayBuffer: null audio in device"); if (ao==NULL) HError(6015,"PlayReplayBuffer: null audio out device"); if (!ai->rbuf.isActive) HError(6020,"PlayReplayBuffer: replay buf not active"); if (ao->vol >= 0) SetVol(ao,ao->vol); if (ai->rbuf.used == 0) return; if (ai->rbuf.inx <= ai->rbuf.outx){ PlayAudio(ao,ai->rbuf.data+ai->rbuf.outx,ai->rbuf.size - ai->rbuf.outx); if (ai->rbuf.inx>0) PlayAudio(ao,ai->rbuf.data,ai->rbuf.inx); } else PlayAudio(ao,ai->rbuf.data+ai->rbuf.outx,ai->rbuf.inx - ai->rbuf.outx);}/* ----------------- Low level input buffering ------------------ */static AudioIn sigAudio; /* Globals used for signalling */static int sigNum=NULLSIG;static volatile Boolean waitForSigH;static volatile Boolean alreadyFilling;static int nz=0;/* ProtectedFillBufferFromAudio: Read samples from audio, try to block until min samples are available from buffer. Semaphores guarantee that this is not exectuted whilst signal handler is already in this function */static void ProtectedFillBufferFromAudio(AudioIn a,int min){ int n,m,avail,wanted,freeSpace; if (a->status!=AI_SAMPLING) return; avail = InSamples(a); wanted = min - a->nInBuffer; n = (avail<wanted)?wanted:avail; if (n <= 0) return; freeSpace = a->bufferSize - a->nInBuffer; if (n > freeSpace) n = freeSpace; if (a->inBufPos+n>a->bufferSize) { /* Need to roll over end of buffer */ m = a->bufferSize - a->inBufPos; ReadAudio(a,a->buffer+a->inBufPos,m); n -= m; a->inBufPos=0; } ReadAudio(a,a->buffer+a->inBufPos,n); a->inBufPos += n; a->nInBuffer += n;}/* StopAudioNow: stop the audio device immediately */static void StopAndFlushAudio(AudioIn a, Boolean deferred){ if (trace&T_TOP) printf("HAudio: stopping audio input %s\n",deferred?"deferred":""); ProtectedFillBufferFromAudio(a,0); StopAudi(a); ProtectedFillBufferFromAudio(a,0); ChangeState(a,AI_STOPPED); CloseAudi(a);}/* FillBufferFromAudio: called by main process as often as possible */static void FillBufferFromAudio(AudioIn a,int min){ if (a->sig<0 && KeyPressed(0)) StopAndFlushAudio(a,FALSE); alreadyFilling=TRUE; while(waitForSigH); ProtectedFillBufferFromAudio(a,min); if(stopSignalled) { StopAndFlushAudio(a,TRUE); stopSignalled = FALSE; } alreadyFilling=FALSE;}/* SignalFillBufferAndStopAudio: called by stop signal */static void SignalFillBufferAndStopAudio(AudioIn a){ waitForSigH=TRUE; if (alreadyFilling) { if (trace&T_TOP) printf("HAudio: stopping audio input later\n"); stopSignalled = TRUE; } else StopAndFlushAudio(a,FALSE); waitForSigH=FALSE;}/* GetSampleFromBuffer: primary access point to audio buffer */static sho
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -