123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 |
- #include "main.h"
- #include <ks.h>
- #include <ksmedia.h>
- #include <malloc.h>
- static void make_wfx(WAVEFORMATEX * wfx,int srate,int nch,int bps)
- {
- wfx->wFormatTag=WAVE_FORMAT_PCM;
- wfx->nChannels=nch;
- wfx->nSamplesPerSec=srate;
- wfx->nAvgBytesPerSec=srate*nch*(bps>>3);
- wfx->nBlockAlign=nch * (bps>>3);
- wfx->wBitsPerSample=bps;
- wfx->cbSize=0;
- }
- static void make_wfxe(WAVEFORMATEXTENSIBLE * wfx,int srate,int nch,int bps)
- {
- make_wfx(&wfx->Format,srate,nch,bps);
- wfx->Format.wFormatTag=WAVE_FORMAT_EXTENSIBLE;
- wfx->Format.cbSize=22;
- wfx->Samples.wReserved=0;
- wfx->dwChannelMask=0;
- wfx->SubFormat=KSDATAFORMAT_SUBTYPE_PCM;
- }
- #ifndef IN_MIDI_NO_WAVEIN_SOURCE
- extern cfg_int cfg_samp_revert;
- #define MMBOOL MIXERCONTROLDETAILS_BOOLEAN
- static MMBOOL *do_mixer_shit(DWORD param,DWORD type,BOOL store,UINT input,MMBOOL *tab)
- {
- UINT id=0;
- mixerGetID((HMIXEROBJ)param,&id,type);
- MIXERCAPS caps;
- mixerGetDevCaps(id,&caps,sizeof(caps));
- MIXERLINE ml;
- ZeroMemory(&ml,sizeof(ml));
- ml.cbStruct=sizeof(ml);
- ml.dwComponentType=MIXERLINE_COMPONENTTYPE_DST_WAVEIN;
- mixerGetLineInfo((HMIXEROBJ)id,&ml,MIXER_GETLINEINFOF_COMPONENTTYPE|MIXER_OBJECTF_MIXER);
- MIXERLINECONTROLS cs;
- MIXERCONTROL c;
- ZeroMemory(&cs,sizeof(cs));
- cs.cbStruct=sizeof(cs);
- cs.cControls=1;
- cs.dwLineID=ml.dwLineID;
- cs.dwControlType=MIXERCONTROL_CONTROLTYPE_MUX;
- cs.cbmxctrl=sizeof(c);
- cs.pamxctrl=&c;
- ZeroMemory(&c,sizeof(c));
- c.cbStruct=sizeof(c);
- if (!mixerGetLineControls((HMIXEROBJ)id,&cs,MIXER_OBJECTF_MIXER|MIXER_GETLINECONTROLSF_ONEBYTYPE))
- {
- if (store)
- {
- if (!tab)
- {
- tab=(MMBOOL*)alloca(sizeof(MMBOOL)*c.cMultipleItems);
- memset(tab,0,sizeof(MMBOOL)*c.cMultipleItems);
- tab[input].fValue=1;
- }
- }
- else
- {
- if (!tab) tab=new MMBOOL[c.cMultipleItems];
- }
- if (tab)
- {
- MIXERCONTROLDETAILS d;
- d.cbStruct=sizeof(d);
- d.dwControlID=c.dwControlID;
- d.cbDetails=sizeof(MMBOOL);
- d.cChannels=ml.cChannels;
- d.cMultipleItems=c.cMultipleItems;
- d.paDetails=tab;
-
- if (store) mixerSetControlDetails((HMIXEROBJ)id,&d,MIXER_SETCONTROLDETAILSF_VALUE |MIXER_OBJECTF_MIXER);
- else mixerGetControlDetails((HMIXEROBJ)id,&d,MIXER_GETCONTROLDETAILSF_VALUE |MIXER_OBJECTF_MIXER);
- }
- }
- return tab;
- }
- #endif
- class CVis : public CStream
- {
- private:
- #ifndef IN_MIDI_NO_WAVEIN_SOURCE
- MMBOOL * old_settings;
- UINT wavein_id;
- void src_init()
- {
- wavein_id=(UINT)cfg_wavein_dev;
- if (cfg_wavein_src)
- {
- if (cfg_samp_revert) old_settings = do_mixer_shit(wavein_id,MIXER_OBJECTF_WAVEIN,0,0,0);
- do_mixer_shit(wavein_id,MIXER_OBJECTF_WAVEIN,1,cfg_wavein_src-1,0);
- }
- }
- void src_deinit()
- {
- if (old_settings)
- {
- do_mixer_shit(wavein_id,MIXER_OBJECTF_WAVEIN,1,0,old_settings);
- delete[] old_settings;
- old_settings=0;
- }
- }
- #endif
- bool eof;
- public:
- bool init(int p_srate,int p_nch,int p_bps);
- void Eof() {eof=1;}
- virtual void Pause(int);
- virtual UINT ReadData(void*,UINT,bool*);
- virtual void Flush();
- virtual ~CVis();
- CVis()
- {
- #ifndef IN_MIDI_NO_WAVEIN_SOURCE
- old_settings=0;
- #endif
- eof=0;buffer=0;blox=0;hWi=0;}
- private:
- BYTE * buffer;
- UINT bufsize;
- UINT read_pos;
- UINT data;
- UINT blocksize;
- HWAVEIN hWi;
- WAVEHDR *blox;
- UINT numblocks;
- UINT cur_block,cur_done;
- int paused;
- UINT in_mm;
- int srate,nch,bps;
- // void on_done(WAVEBUFFER*);
- };
- void CVis::Flush()
- {
- if (paused) return;
- waveInReset(hWi);
- UINT n;
- for(n=0;n<numblocks;n++)
- {
- blox[n].dwUser=0;
- waveInAddBuffer(hWi,&blox[n],sizeof(WAVEHDR));
- }
- cur_block=0;
- cur_done=0;
- in_mm=numblocks;//added all blocks already
- read_pos=0;
- data=0;
- waveInStart(hWi);
- }
- void CALLBACK waveInProc(HWAVEIN hWi,UINT msg,DWORD dwIns,DWORD p1,DWORD p2)
- {
- if (msg==WIM_DATA && p1)
- {
- ((WAVEHDR*)p1)->dwUser=1;
- }
- }
- bool CVis::init(int p_srate,int p_nch,int p_bps)
- {
- srate=p_srate;
- nch=p_nch;
- bps=p_bps;
- blocksize=576 * (bps/8) * (nch);
- if (cfg_sampout) blocksize<<=3;
- numblocks=(2 * srate * nch * (bps>>3))/blocksize;
- bufsize=numblocks*blocksize;
- blox=new WAVEHDR[numblocks];
- memset(blox,0,sizeof(WAVEHDR)*numblocks);
- buffer=(BYTE*)malloc(bufsize);
- try
- {
- WAVEFORMATEX wfx;
- make_wfx(&wfx,srate,nch,bps);
- if (waveInOpen(&hWi,cfg_wavein_dev,&wfx,(DWORD)waveInProc,0,CALLBACK_FUNCTION))
- {
- WAVEFORMATEXTENSIBLE wfxe = {0};
- make_wfxe(&wfxe,srate,nch,bps);
- if (waveInOpen(&hWi,cfg_wavein_dev,&wfxe.Format,(DWORD)waveInProc,0,CALLBACK_FUNCTION))
- {
- return 0;
- }
- }
- } catch(...)//gay drivers etc
- {
- return 0;
- }
- #ifndef IN_MIDI_NO_WAVEIN_SOURCE
- src_init();
- #endif
- UINT n;
- for(n=0;n<numblocks;n++)
- {
- blox[n].lpData=(char*)(buffer+blocksize*n);
- blox[n].dwBufferLength=blocksize;
- waveInPrepareHeader(hWi,&blox[n],sizeof(WAVEHDR));
- }
- paused=0;
- Flush();
- #ifdef USE_LOG
- log_write("sampling started OK");
- #endif
- return 1;
- }
- CVis::~CVis()
- {
- #ifdef USE_LOG
- log_write("shutting down sampling");
- #endif
- if (hWi)
- {
- waveInReset(hWi);
- UINT n;
- for(n=0;n<numblocks;n++)
- {
- waveInUnprepareHeader(hWi,&blox[n],sizeof(WAVEHDR));
- }
- #ifndef IN_MIDI_NO_WAVEIN_SOURCE
- src_deinit();
- #endif
- waveInClose(hWi);
- hWi=0;
- }
- #ifdef USE_LOG
- log_write("sampling shut down OK");
- #endif
- if (blox) delete[] blox;
- if (buffer) free(buffer);
- }
- UINT CVis::ReadData(void * _dst,UINT bytes,bool * ks)
- {
- if (eof) return 0;
- BYTE * dst=(BYTE*)_dst;
- if (paused) return 0;
- while(!*ks)
- {
- while(blox[cur_done].dwUser)
- {
- blox[cur_done].dwUser=0;
- cur_done=(cur_done+1)%numblocks;
- in_mm--;
- data+=blocksize;
- }
- {
- UINT d=data;
- if (d)
- {
- if (d>bytes) d=bytes;
- if (read_pos+d>bufsize)
- {
- UINT foo=bufsize-read_pos;
- memcpy(dst,buffer+read_pos,foo);
- memcpy(dst+foo,buffer,read_pos=d-foo);
- }
- else
- {
- memcpy(dst,buffer+read_pos,d);
- read_pos+=d;
- }
- dst+=d;
- data-=d;
- bytes-=d;
- }
- }
- {
- UINT max=numblocks-(data+blocksize-1)/blocksize;
- while(in_mm < max)
- {
- waveInAddBuffer(hWi,&blox[cur_block],sizeof(WAVEHDR));
- cur_block=(cur_block+1)%numblocks;
- in_mm++;
- }
- }
- if (!bytes) break;
- MIDI_callback::Idle();
- }
- return dst-(BYTE*)_dst;
- }
- void CVis::Pause(int b)
- {
- paused=b;
- if (b)
- {
- waveInStop(hWi);
- }
- else
- {
- Flush();
- }
- }
- CStream * sampling_create(int srate,int nch,int bps)
- {
- CVis * ptr = new CVis;
- if (!ptr->init(srate,nch,bps))
- {
- delete ptr;
- ptr=0;
- }
- return ptr;
- }
|