From 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d Mon Sep 17 00:00:00 2001 From: Jef Date: Tue, 24 Sep 2024 14:54:57 +0200 Subject: Initial community commit --- Src/Plugins/Input/in_midi/sampling.cpp | 333 +++++++++++++++++++++++++++++++++ 1 file changed, 333 insertions(+) create mode 100644 Src/Plugins/Input/in_midi/sampling.cpp (limited to 'Src/Plugins/Input/in_midi/sampling.cpp') diff --git a/Src/Plugins/Input/in_midi/sampling.cpp b/Src/Plugins/Input/in_midi/sampling.cpp new file mode 100644 index 00000000..06c34653 --- /dev/null +++ b/Src/Plugins/Input/in_midi/sampling.cpp @@ -0,0 +1,333 @@ +#include "main.h" +#include +#include +#include + +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;ndwUser=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;nbytes) 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; +} \ No newline at end of file -- cgit