Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
174
Src/Plugins/DSP/dsp_sc/Include/c_datapump.h
Normal file
174
Src/Plugins/DSP/dsp_sc/Include/c_datapump.h
Normal file
|
@ -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__
|
156
Src/Plugins/DSP/dsp_sc/Include/c_wavein.h
Normal file
156
Src/Plugins/DSP/dsp_sc/Include/c_wavein.h
Normal file
|
@ -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__
|
Loading…
Add table
Add a link
Reference in a new issue