📄 winsnd2.c
字号:
for(i=0;i<WINSND_NBUFS;++i){ WAVEHDR *hdr=&d->hdrs[i]; add_input_buffer(d,hdr,bsize); } d->running=TRUE; mr=waveInStart(d->indev); if (mr != MMSYSERR_NOERROR){ ms_error("waveInStart() error"); return ; } ms_ticker_set_time_func(f->ticker,winsnd_get_cur_time,d);}static void winsnd_read_postprocess(MSFilter *f){ WinSnd *d=(WinSnd*)f->data; MMRESULT mr; int i; ms_ticker_set_time_func(f->ticker,NULL,NULL); d->running=FALSE; mr=waveInStop(d->indev); if (mr != MMSYSERR_NOERROR){ ms_error("waveInStop() error"); return ; } mr=waveInReset(d->indev); if (mr != MMSYSERR_NOERROR){ ms_error("waveInReset() error"); return ; } for(i=0;i<WINSND_NBUFS;++i){ WAVEHDR *hdr=&d->hdrs[i]; if (hdr->dwFlags & WHDR_PREPARED) { mr = waveInUnprepareHeader(d->indev,hdr,sizeof (*hdr)); if (mr != MMSYSERR_NOERROR){ ms_error("waveInUnPrepareHeader() error"); } } } mr = waveInClose(d->indev); if (mr != MMSYSERR_NOERROR){ ms_error("waveInClose() error"); return ; } ms_message("Shutting down sound device (playing: %i) (input-output: %i) (notplayed: %i)", d->nbufs_playing, d->stat_input - d->stat_output, d->stat_notplayed); flushq(&d->rq,0);}static void winsnd_read_process(MSFilter *f){ WinSnd *d=(WinSnd*)f->data; mblk_t *m; int i; ms_mutex_lock(&d->mutex); while((m=getq(&d->rq))!=NULL){ ms_queue_put(f->outputs[0],m); } ms_mutex_unlock(&d->mutex); for(i=0;i<WINSND_NBUFS;++i){ WAVEHDR *hdr=&d->hdrs[i]; if (hdr->dwUser==0) { MMRESULT mr; mr=waveInUnprepareHeader(d->indev,hdr,sizeof(*hdr)); if (mr!=MMSYSERR_NOERROR) ms_warning("winsnd_read_process: Fail to unprepare header!"); add_input_buffer(d,hdr,hdr->dwBufferLength); } }}static void CALLBACKwrite_callback(HWAVEOUT outdev, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2){ WAVEHDR *hdr=(WAVEHDR *) dwParam1; WinSnd *d=(WinSnd*)dwInstance; switch (uMsg){ case WOM_OPEN: break; case WOM_CLOSE: case WOM_DONE: if (hdr){ d->nbufs_playing--; } if (d->stat_output==0) { d->stat_input=1; /* reset */ d->stat_notplayed=0; } d->stat_output++; break; }}static void winsnd_write_preprocess(MSFilter *f){ WinSnd *d=(WinSnd*)f->data; MMRESULT mr; DWORD dwFlag; int i; d->stat_input=0; d->stat_output=0; d->stat_notplayed=0; d->stat_minimumbuffer=WINSND_MINIMUMBUFFER; winsnd_apply_settings(d); /* Init Microphone device */ dwFlag = CALLBACK_FUNCTION; if (d->dev_id != WAVE_MAPPER) dwFlag = WAVE_MAPPED | CALLBACK_FUNCTION; mr = waveOutOpen (&d->outdev, d->dev_id, &d->wfx, (DWORD) write_callback, (DWORD)d, dwFlag); if (mr != MMSYSERR_NOERROR) { ms_error("Failed to open windows sound device %i. (waveOutOpen:0x%i)",d->dev_id, mr); mr = waveOutOpen (&d->outdev, WAVE_MAPPER, &d->wfx, (DWORD) write_callback, (DWORD)d, CALLBACK_FUNCTION); if (mr != MMSYSERR_NOERROR) { ms_error("Failed to open windows sound device %i. (waveOutOpen:0x%i)",d->dev_id, mr); d->outdev=NULL; return ; } } for(i=0;i<WINSND_NBUFS*2;++i){ WAVEHDR *hdr=&d->hdrs[i]; hdr->dwFlags=0; hdr->dwUser=0; }}static void winsnd_write_postprocess(MSFilter *f){ WinSnd *d=(WinSnd*)f->data; MMRESULT mr; int i; if (d->outdev==NULL) return; mr=waveOutReset(d->outdev); if (mr != MMSYSERR_NOERROR){ ms_error("waveOutReset() error"); return ; } for(i=0;i<WINSND_NBUFS*2;++i){ WAVEHDR *hdr=&d->hdrs[i]; mblk_t *old; if (hdr->dwFlags & WHDR_DONE){ mr=waveOutUnprepareHeader(d->outdev,hdr,sizeof(*hdr)); if (mr != MMSYSERR_NOERROR){ ms_error("waveOutUnprepareHeader error"); } old=(mblk_t*)hdr->dwUser; if (old) freemsg(old); hdr->dwUser=0; } } mr=waveOutClose(d->outdev); if (mr != MMSYSERR_NOERROR){ ms_error("waveOutClose() error"); return ; } ms_message("Shutting down sound device (playing: %i) (input-output: %i) (notplayed: %i)", d->nbufs_playing, d->stat_input - d->stat_output, d->stat_notplayed);}static void winsnd_write_process(MSFilter *f){ WinSnd *d=(WinSnd*)f->data; mblk_t *m,*old; MMRESULT mr; int i; int discarded=0; if (d->outdev==NULL) { ms_queue_flush(f->inputs[0]); return; }#ifdef AMD_HACK /* too many sound card are crappy on windows... */ d->stat_minimumbuffer=15;#endif if (d->nbufs_playing==0) ms_warning("no buffer currently playing (q.m_count=%i), (playing: %i)", f->inputs[0]->q.q_mcount, d->nbufs_playing); while((m=ms_queue_get(f->inputs[0]))!=NULL){ for(i=0;i<d->stat_minimumbuffer;++i){ WAVEHDR *hdr=&d->hdrs[i]; if (hdr->dwFlags & WHDR_DONE){ old=(mblk_t*)hdr->dwUser; mr=waveOutUnprepareHeader(d->outdev,hdr,sizeof(*hdr)); if (mr != MMSYSERR_NOERROR){ ms_error("waveOutUnprepareHeader error"); } freemsg(old); hdr->dwUser=0; } if (hdr->dwUser==0){ hdr->lpData=(LPSTR)m->b_rptr; hdr->dwBufferLength=msgdsize(m); hdr->dwFlags = 0; hdr->dwUser = (DWORD)m; mr = waveOutPrepareHeader(d->outdev,hdr,sizeof(*hdr)); if (mr != MMSYSERR_NOERROR){ ms_error("waveOutPrepareHeader() error"); freemsg(m); discarded++; d->stat_notplayed++; break; } ms_debug("waveOutPrepareHeader() done"); mr=waveOutWrite(d->outdev,hdr,sizeof(*hdr)); if (mr != MMSYSERR_NOERROR){ ms_error("waveOutWrite() error"); freemsg(m); discarded++; d->stat_notplayed++; break; }else { d->nbufs_playing++; /* ms_debug("waveOutWrite() done"); */ } break; } } if (i==d->stat_minimumbuffer){ ms_error("winsnd_write_process: All buffers are busy."); freemsg(m); discarded++; d->stat_notplayed++; } } if ( d->stat_output > 150 && ((d->stat_notplayed*100)/d->stat_output) >10 && d->stat_minimumbuffer<15) { d->stat_minimumbuffer+=6; ms_message("Increasing sound card number of write buffer to %i", d->stat_minimumbuffer); d->stat_notplayed = 0; /* reset number... */ } else if ( d->stat_output > 150 && ((d->stat_notplayed*100)/d->stat_output) >1 && d->stat_minimumbuffer<18) { d->stat_minimumbuffer+=3; ms_message("Increasing sound card number of write buffer to %i", d->stat_minimumbuffer); d->stat_notplayed = 0; /* reset number... */ } if (discarded>0) ms_warning("Extra data for sound card removed (%i buf), (playing: %i) (input-output: %i)", discarded, d->nbufs_playing, d->stat_input - d->stat_output);}static int set_rate(MSFilter *f, void *arg){ WinSnd *d=(WinSnd*)f->data; d->wfx.nSamplesPerSec=*((int*)arg); return 0;}static int set_nchannels(MSFilter *f, void *arg){ WinSnd *d=(WinSnd*)f->data; d->wfx.nChannels=*((int*)arg); return 0;}static int winsnd_get_stat_input(MSFilter *f, void *arg){ WinSnd *d=(WinSnd*)f->data; return d->stat_input;}static int winsnd_get_stat_ouptut(MSFilter *f, void *arg){ WinSnd *d=(WinSnd*)f->data; return d->stat_output;}static int winsnd_get_stat_discarded(MSFilter *f, void *arg){ WinSnd *d=(WinSnd*)f->data; return d->stat_notplayed;}static MSFilterMethod winsnd_methods[]={ { MS_FILTER_SET_SAMPLE_RATE , set_rate }, { MS_FILTER_SET_NCHANNELS , set_nchannels }, { MS_FILTER_GET_STAT_INPUT, winsnd_get_stat_input }, { MS_FILTER_GET_STAT_OUTPUT, winsnd_get_stat_ouptut }, { MS_FILTER_GET_STAT_DISCARDED, winsnd_get_stat_discarded }, { 0 , NULL }};MSFilterDesc winsnd_read_desc={ MS_WINSND_READ_ID, "MSWinSndRead", "Sound capture filter for Windows Sound drivers", MS_FILTER_OTHER, NULL, 0, 1, winsnd_init, winsnd_read_preprocess, winsnd_read_process, winsnd_read_postprocess, winsnd_uninit, winsnd_methods};MSFilterDesc winsnd_write_desc={ MS_WINSND_WRITE_ID, "MSWinSndWrite", "Sound playback filter for Windows Sound drivers", MS_FILTER_OTHER, NULL, 1, 0, winsnd_init, winsnd_write_preprocess, winsnd_write_process, winsnd_write_postprocess, winsnd_uninit, winsnd_methods};MSFilter *ms_winsnd_read_new(MSSndCard *card){ MSFilter *f=ms_filter_new_from_desc(&winsnd_read_desc); WinSndCard *wc=(WinSndCard*)card->data; WinSnd *d=(WinSnd*)f->data; d->dev_id=wc->in_devid; return f;}MSFilter *ms_winsnd_write_new(MSSndCard *card){ MSFilter *f=ms_filter_new_from_desc(&winsnd_write_desc); WinSndCard *wc=(WinSndCard*)card->data; WinSnd *d=(WinSnd*)f->data; d->dev_id=wc->out_devid; return f;}MS_FILTER_DESC_EXPORT(winsnd_read_desc)MS_FILTER_DESC_EXPORT(winsnd_write_desc)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -