diff options
Diffstat (limited to 'Src/Plugins/DSP/dsp_sc/Include')
-rw-r--r-- | Src/Plugins/DSP/dsp_sc/Include/c_datapump.h | 174 | ||||
-rw-r--r-- | Src/Plugins/DSP/dsp_sc/Include/c_wavein.h | 156 |
2 files changed, 330 insertions, 0 deletions
diff --git a/Src/Plugins/DSP/dsp_sc/Include/c_datapump.h b/Src/Plugins/DSP/dsp_sc/Include/c_datapump.h new file mode 100644 index 00000000..bcf3863b --- /dev/null +++ b/Src/Plugins/DSP/dsp_sc/Include/c_datapump.h @@ -0,0 +1,174 @@ +#ifndef __C_DATAPUMP_H__ +#define __C_DATAPUMP_H__ + +#include <stdlib.h> +#include <memory.h> +#include <stddef.h> +#pragma intrinsic(memcpy,memset) + +template<class T> class C_DATAPUMP { +private: +protected: + T *BufferBottom; // bottom of the physical buffer + T *BufferTop; // top of the physical buffer + T *BufferStart; // start of the logical buffer + T *BufferEnd; // end of the logical buffer + + virtual void addItems(T *inputBuffer, size_t inputSize) { // inputSize = number of <T> records inputBuffer contains + if(inputBuffer && inputSize) { + memcpy(BufferEnd,inputBuffer,inputSize*sizeof(T)); // copy our records in + BufferEnd += inputSize; + if(BufferEnd >= BufferTop) BufferEnd = BufferBottom + (BufferEnd-BufferTop); + } + } + + virtual void delItems(int where, size_t numItems) { // where: 0 = start, 1 = end + if(numItems > 0) { + if(numItems > size()) { // just void everything + BufferEnd = BufferStart; + } else { + if(where == 0) { // start + BufferStart += numItems; + if(BufferStart >= BufferTop) BufferStart = BufferBottom + (BufferTop-BufferStart); + } else if(where == 1) { // end + BufferEnd -= numItems; + if(BufferEnd < BufferBottom) BufferEnd = BufferTop - (BufferBottom-BufferEnd); + } + } + } + } + + virtual void getItems(T *outputBuffer, size_t outputSize) { // outputSize = number of <T> records outputBuffer needs + if(outputBuffer && outputSize) { + memcpy(outputBuffer,BufferStart,outputSize*sizeof(T)); + } + } + +public: + C_DATAPUMP(int bufferSize) { // bufferSize = number of <T> records + BufferBottom = NULL; + BufferTop = NULL; + BufferStart = NULL; + BufferEnd = NULL; + resizeBuffer(bufferSize); + } + + virtual ~C_DATAPUMP() { + if(getBufferSize() && BufferBottom) { + free(BufferBottom); + BufferBottom = NULL; + } + } + + virtual void resizeBuffer(size_t bufferSize) { // bufferSize = number of <T> records + // this will invalidate any data in the buffer, so be careful when calling this function + if(bufferSize) { + if(getBufferSize() != bufferSize) { + if(BufferBottom && BufferTop && getBufferSize()) { // buffer is valid + if(getBufferSize() > bufferSize) { // buffer is getting smaller (will invalidate buffer) + BufferTop -= getBufferSize()-bufferSize; + invalidate(); + } else { // buffer is getting larger (will _NOT_ invalidate buffer... nicely moves the data over =) + T *newBuffer = (T *)malloc(bufferSize * sizeof(T)); + // new + BufferEnd = newBuffer + get(newBuffer,bufferSize); + free(BufferBottom); + BufferBottom = newBuffer; + BufferTop = BufferBottom + bufferSize; + BufferStart = BufferBottom; + /* old + T *bufptr = newBuffer; + int top = BufferEnd >= BufferStart ? BufferEnd-BufferStart : BufferTop-BufferStart; // number of <T> records at top of physical buffer + int bottom = BufferEnd >= BufferStart ? 0 : BufferEnd-BufferBottom; // number of <T> records at bottom of physical buffer + if(top > 0) { + memcpy(bufptr,BufferStart,top*sizeof(T)); + bufptr += top; + } + if(bottom > 0) { + memcpy(bufptr,BufferBottom,bottom*sizeof(T)); + bufptr += bottom; + } + free(BufferBottom); + BufferBottom = newBuffer; + BufferTop = BufferBottom + bufferSize; + BufferStart = BufferBottom; + BufferEnd = bufptr; + */ + } + } else { // no buffer, create (invalidates the buffer... duh) + BufferBottom = (T *)malloc(bufferSize * sizeof(T)); + BufferTop = BufferBottom + bufferSize; + invalidate(); + } + } + } + } + + virtual size_t size() { // will get the number of <T> records the logical buffer contains + return BufferEnd >= BufferStart ? BufferEnd-BufferStart : (BufferTop-BufferStart)+(BufferEnd-BufferBottom); + } + + virtual size_t put(T *inputBuffer, size_t inputSize) { // inputSize = number of <T> records inputBuffer contains + // returns number of <T> records added to logical buffer + size_t retval = 0; + if(inputBuffer && inputSize) { + size_t fitting = ((BufferTop-BufferBottom)-1) - size(); // can't go over our logical boundary.... blah + if(fitting > inputSize) fitting = inputSize; // the entire thing can fit. yeay! + retval = fitting; + if(fitting > 0) { + T *bufptr = inputBuffer; + size_t top = BufferEnd >= BufferStart ? BufferTop-BufferEnd : 0; // number of <T> records free at top of physical buffer + size_t bottom = BufferEnd >= BufferStart ? BufferStart-BufferBottom : (BufferStart-BufferEnd); // number of <T> records free at bottom of physical buffer + if(top > 0) { + if(top > fitting) top = fitting; + addItems(bufptr,top); + fitting -= top; + bufptr += top; + } + if(bottom > 0 && fitting > 0) { + if(bottom > fitting) bottom = fitting; + addItems(bufptr,bottom); + } + } + } + return retval; + } + + virtual size_t get(T *outputBuffer, size_t outputSize) { // outputSize = number of <T> records outputBuffer needs + // returns number of <T> records pulled from the logical buffer + size_t retval = 0; + if(outputBuffer && outputSize) { + size_t fitting = size(); + if(fitting > outputSize) fitting = outputSize; + retval = fitting; + if(fitting > 0) { + T *bufptr = outputBuffer; + size_t top = BufferEnd >= BufferStart ? BufferEnd-BufferStart : BufferTop-BufferStart; // number of <T> records at top of physical buffer + size_t bottom = BufferEnd >= BufferStart ? 0 : BufferEnd-BufferBottom; // number of <T> records at bottom of physical buffer + if(top > 0) { + if(top > fitting) top = fitting; + getItems(bufptr,top); + delItems(0,top); + fitting -= top; + bufptr += top; + } + if(bottom > 0 && fitting > 0) { + if(bottom > fitting) bottom = fitting; + getItems(bufptr,bottom); + delItems(0,bottom); + } + } + } + return retval; + } + + virtual size_t getBufferSize() { // returns the size of the physical buffer in <T> items + return BufferTop-BufferBottom; + } + + virtual void invalidate() { // calling this will wipe all data in the buffer and reset the logical pointers + BufferStart = BufferEnd = BufferBottom; + } +}; + +#endif // !__C_DATAPUMP_H__
\ No newline at end of file diff --git a/Src/Plugins/DSP/dsp_sc/Include/c_wavein.h b/Src/Plugins/DSP/dsp_sc/Include/c_wavein.h new file mode 100644 index 00000000..7bcac3cb --- /dev/null +++ b/Src/Plugins/DSP/dsp_sc/Include/c_wavein.h @@ -0,0 +1,156 @@ +#ifndef __C_WAVEIN_H__ +#define __C_WAVEIN_H__ + +#include <windows.h> +#include <mmsystem.h> +#define EXIT_ON_ERROR(hr) \ + if (FAILED(hr)) { goto Exit; } +#define SAFE_RELEASE(what) \ + if ((what) != NULL) \ +{ (what)->Release(); (what) = NULL; } + +template<int numbuffers, int buffersize> class C_WAVEIN { +private: + short Samples[numbuffers][buffersize]; + WAVEFORMATEX wfx; + WAVEHDR wvhdr[numbuffers]; + HWAVEIN hwi; + WAVEINCAPS wic; + unsigned long iNumDevs, iy; + HRESULT hr; + IMMDeviceEnumerator *pEnumerate; + IMMDevice *pDevice; + IMMDeviceCollection *ppDevices; + IPropertyStore *pProps; + BOOL useXpSound; + PROPVARIANT varName; + char buf[1024]; +public: + C_WAVEIN() { + hwi = NULL; + memset(Samples, 0, sizeof(Samples)); + memset(wvhdr, 0, sizeof(wvhdr)); + iNumDevs = iy = 0; + hr = S_OK; + pEnumerate = NULL; + pDevice = NULL; + ppDevices = NULL; + pProps = NULL; + useXpSound = false; + memset(buf, 0, sizeof(buf)); + } + + virtual ~C_WAVEIN() { + Close(); + } + + char * getDeviceName(unsigned int devid=-1) { + hr = S_OK; + pEnumerate = NULL; + pDevice = NULL; + ppDevices = NULL; + pProps = NULL; + useXpSound = false; + PROPVARIANT varName; + PropVariantInit(&varName); + // Get enumerator for audio endpoint devices. + CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); + hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), + NULL, CLSCTX_INPROC_SERVER, + __uuidof(IMMDeviceEnumerator), + (void**)&pEnumerate); + EXIT_ON_ERROR(hr) + + hr = pEnumerate->GetDefaultAudioEndpoint(eCapture,eConsole,&pDevice); + EXIT_ON_ERROR(hr) +Exit: + if (FAILED(hr)) { + useXpSound = true; + } else + useXpSound = false; + + memset(buf, 0, sizeof(buf)); + if (useXpSound) { + if (!waveInGetDevCaps(devid, &wic, sizeof(WAVEINCAPS))) { + lstrcpyn(buf, wic.szPname, ARRAYSIZE(buf)); + goto Fin; + } + } else { + pDevice->OpenPropertyStore(STGM_READ, &pProps); + pProps->GetValue(PKEY_Device_FriendlyName, &varName); + WideCharToMultiByte(CP_ACP, 0, (LPWSTR)varName.pwszVal, -1, buf, ARRAYSIZE(buf), NULL, NULL); + goto Fin; + } +Fin: + PropVariantClear(&varName); + SAFE_RELEASE(pProps) + SAFE_RELEASE(pEnumerate) + SAFE_RELEASE(pDevice) + SAFE_RELEASE(ppDevices) + CoUninitialize(); + return buf; + } + + void Create(int sRate, int nCh,int devid=-1) { + if (hwi == NULL) { + wfx.wFormatTag = WAVE_FORMAT_PCM; + wfx.wBitsPerSample = 16; + wfx.nSamplesPerSec = sRate; + wfx.nChannels = (WORD)nCh; + wfx.nBlockAlign = (wfx.nChannels * wfx.wBitsPerSample) / 8; + wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign; + wfx.cbSize = 0; + waveInOpen(&hwi,devid,&wfx,0,0,CALLBACK_NULL); + waveInStop(hwi); + waveInReset(hwi); + for(int i = 0; i < numbuffers; i++) { + memset(&wvhdr[i],0,sizeof(wvhdr[i])); + wvhdr[i].lpData = (char *)&Samples[i]; + wvhdr[i].dwBufferLength = buffersize * sizeof(short); + waveInPrepareHeader(hwi,&wvhdr[i],sizeof(WAVEHDR)); + waveInAddBuffer(hwi,&wvhdr[i],sizeof(WAVEHDR)); + } + waveInStart(hwi); + } + } + + void Close() { + if (hwi != NULL) { + waveInStop(hwi); + waveInReset(hwi); + for(int i = 0; i < numbuffers; i++) { + if (wvhdr[i].dwFlags & WHDR_PREPARED) { + waveInUnprepareHeader(hwi,&wvhdr[i],sizeof(WAVEHDR)); + } + } + waveInClose(hwi); + hwi = NULL; + } + } + + short *operator[](int buffernum) { + return (short *)&Samples[buffernum]; + } + + int getNumSamples(int buffernum) { + return wvhdr[buffernum].dwBytesRecorded / (wfx.nChannels * sizeof(short)); + } + + int isOpen() { + return hwi != NULL; + } + + int isFilled(int buffernum) { + return wvhdr[buffernum].dwFlags & WHDR_DONE && wvhdr[buffernum].dwBytesRecorded <= buffersize * sizeof(short); + } + + void cycleBuffer(int buffernum) { + if (hwi != NULL) { + wvhdr[buffernum].dwFlags = WHDR_PREPARED; + wvhdr[buffernum].dwBytesRecorded = 0; + waveInAddBuffer(hwi,&wvhdr[buffernum],sizeof(WAVEHDR)); + } + } +}; + +#endif // !__C_WAVEIN_H__
\ No newline at end of file |