aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/DSP/dsp_sc/Include
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Plugins/DSP/dsp_sc/Include')
-rw-r--r--Src/Plugins/DSP/dsp_sc/Include/c_datapump.h174
-rw-r--r--Src/Plugins/DSP/dsp_sc/Include/c_wavein.h156
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