📄 unadspdlibpipes.pas
字号:
// simply pass data through
result := len;
onNewData(data, result, self);
end;
end;
// -- --
function unaDSPDLibWavePipe.isActive(): bool;
begin
// inherited will return false, since "device" is nil
//
result := f_active;
end;
{ unavclDSPDLibMultiBand }
// -- --
procedure unavclDSPDLibMultiBand.AfterConstruction();
begin
inherited;
//
freqAssignMode := unafam_powerOf2;
numBands := c_defNumBands;
end;
// -- --
function unavclDSPDLibMultiBand.allocateNBuf(n: uint): pFloatArray;
begin
result := malloc(n * sizeOf(dspl_float));
end;
// -- --
function unavclDSPDLibMultiBand.applyDeviceFormat(const format: WAVEFORMATEX; isSrc: bool): bool;
begin
// apply format on automation
result := inherited applyDeviceFormat(format, isSrc);
//
if (result) then
checkFreqMode();
end;
// -- --
procedure unavclDSPDLibMultiBand.checkFreqMode();
var
i: int;
frq: pFloatArray;
max: dspl_float;
f: dspl_float;
n: uint;
begin
case (f_freqAssignMode) of
unafam_manual: begin
// not much to care about
//
// just make sure we have freq buffer large enough to hold the bands,
// and adjust the size of freq buffer as necessary
frequency[getNumFreq() - 1] := frequency[getNumFreq() - 1];
end;
unafam_powerOf2: begin
//
n := getNumFreq();
if ((0 < n) and (0 < pcmFormat.nSamplesPerSec)) then begin
//
max := pcmFormat.nSamplesPerSec / 2.75625;
frq := allocateNBuf(n);
try
for i := 1 to n do begin
//
f := max / (1 shl (int(n) - i));
frq[i - 1] := f / pcmFormat.nSamplesPerSec;
end;
//
automation.dspl_obj_setc(dsplObj, DSPL_PID or DSPL_P_FRQ, pdspl_float(frq), n);
finally
mrealloc(frq);
end;
//
end; // 0 < n
end;
end; // case
end;
// -- --
procedure unavclDSPDLibMultiBand.doSetNumBands(value: uint);
begin
if (f_numBands <> value) then begin
//
f_numBands := value;
//
automation.dspl_obj_seti(dsplObj, DSPL_PID or DSPL_P_OTHER, numBands); // set number of bands
//
checkFreqMode();
end;
end;
// -- --
function unavclDSPDLibMultiBand.getFreq(band: uint): dspl_float;
var
chunk: pdspl_chunk;
begin
chunk := automation.root.getc(dsplObj, DSPL_PID or DSPL_P_FRQ);
if ((nil <> chunk) and (int(band) < chunk.r_len)) then
result := pFloatArray(chunk.r_fp)[band] * pcmFormat.nSamplesPerSec
else
result := 0.0;
end;
// -- --
function unavclDSPDLibMultiBand.getNumFreq(): int;
begin
result := numBands;
end;
// -- --
procedure unavclDSPDLibMultiBand.setFreq(band: uint; const value: dspl_float);
var
i: int;
fbuf: pFloatArray;
chunk: pdspl_chunk;
n: uint;
begin
if (int(band) < getNumFreq()) then begin
//
chunk := automation.root.getc(dsplObj, DSPL_PID or DSPL_P_FRQ);
if ((nil <> chunk) and (int(band) < chunk.r_len)) then begin
//
pFloatArray(chunk.r_fp)[band] := value / pcmFormat.nSamplesPerSec;
//
// assuming the chunk will not be re-allocated
automation.dspl_obj_setc(dsplObj, DSPL_PID or DSPL_P_FRQ, chunk.r_fp, getNumFreq()); // we also make sure number of bands is properly specified
end
else begin
//
// must allocate a larger chunk
n := getNumFreq();
fbuf := allocateNBuf(n);
if (0 < n) then begin
//
try
for i := 0 to n - 1 do begin
//
if (i = int(band)) then
fbuf[i] := value / pcmFormat.nSamplesPerSec //
else
if (i < chunk.r_len) then
fbuf[i] := pFloatArray(chunk.r_fp)[i] // take old values we have in the chunk
else
fbuf[i] := 0.0; // zero the rest
//
end;
//
automation.dspl_obj_setc(dsplObj, DSPL_PID or DSPL_P_FRQ, pdspl_float(fbuf), getNumFreq());
finally
mrealloc(fbuf);
end;
end;
end;
//
end;
end;
// -- --
procedure unavclDSPDLibMultiBand.setNumBands(value: uint);
begin
doSetNumBands(value);
end;
{ TunavclDSPDLibEQ }
// -- --
constructor TunavclDSPDLibEQ.create(owner: tComponent);
begin
inherited; // creates automation
//
f_dsplObj := automation.dspl_objNew(DSPL_OID or DSPL_EQMB);
end;
// -- --
procedure TunavclDSPDLibEQ.doSetNumBands(value: uint);
begin
inherited;
//
// just make sure we have gain buffer large enough to hold the numBands
// and adjust the size of gain buffer if necessary
gain[numBands - 1] := gain[numBands - 1];
end;
// -- --
function TunavclDSPDLibEQ.getGain(band: uint): dspl_float;
var
chunk: pdspl_chunk;
begin
chunk := automation.root.getc(dsplObj, DSPL_PID or DSPL_P_GAIN);
if ((nil <> chunk) and (int(band) < chunk.r_len)) then
result := v2db(pFloatArray(chunk.r_fp)[band])
else
result := 0.0;
end;
// -- --
procedure TunavclDSPDLibEQ.setGain(band: uint; const value: dspl_float);
var
i: int;
gbuf: pFloatArray;
chunk: pdspl_chunk;
begin
if (band < numBands) then begin
//
chunk := automation.root.getc(dsplObj, DSPL_PID or DSPL_P_GAIN);
if ((nil <> chunk) and (int(band) < chunk.r_len)) then begin
//
pFloatArray(chunk.r_fp)[band] := db2v(value);
//
// assuming the chunk will not be re-allocated
automation.dspl_obj_setc(dsplObj, DSPL_PID or DSPL_P_GAIN, chunk.r_fp, numBands);
end
else begin
//
// must allocate a larger chunk
gbuf := allocateNBuf(numBands);
if (0 < numBands) then begin
try
for i := 0 to numBands - 1 do begin
//
if (i = int(band)) then
gbuf[i] := db2v(value)
else
if (i < chunk.r_len) then
gbuf[i] := pFloatArray(chunk.r_fp)[i] // take old values we have in the chunk
else
gbuf[i] := db2v(0.0); // zero the rest
//
end;
//
automation.dspl_obj_setc(dsplObj, DSPL_PID or DSPL_P_GAIN, pdspl_float(gbuf), numBands);
finally
mrealloc(gbuf);
end;
end;
//
end;
end;
end;
{ TunavclDSPDLibMBSP }
// -- --
procedure TunavclDSPDLibMBSP.AfterConstruction();
begin
inherited;
//
processDataInPlace := false; // assign default value
end;
// -- --
procedure TunavclDSPDLibMBSP.BeforeDestruction();
var
c: uint;
begin
inherited;
//
for c := low(f_localFBuf) to high(f_localFBuf) do begin
//
f_localFBufSize[c] := 0;
mrealloc(f_localFBuf[c]);
end;
end;
// -- --
function TunavclDSPDLibMBSP.convertOutFloat2PCM(out buf: pointer): int;
var
p, b, c: uint;
s: uint;
nSamples: uint;
outBuf: pdspl_float;
f: dspl_float;
//
pcmBits: uint; // local copy of pcmFormat.wBitsPerSample
pcmChannels: uint;
begin
result := 0;
//
pcmBits := pcmFormat.wBitsPerSample;
pcmChannels := pcmFormat.nChannels;
//
// convert float samples to integer values (if we have to)
if ((0 < pcmBits) and (0 < pcmChannels) and (0 < numBands)) then begin
//
// 1. calculate the resulting samples, taking passThrough in account
//
for c := 0 to pcmChannels - 1 do begin
//
for b := 0 to numBands - 1 do begin
//
automation.getMultiOutData(c, b, outBuf, nSamples);
f_localRaw[c][b] := pFloatArray(outBuf);
//
if (1 > nSamples) then
continue; // no out data in this channel/band?
//
if (f_localFBufSize[c] <> int(nSamples) * sizeOf(dspl_float)) then begin
//
f_localFBufSize[c] := nSamples * sizeOf(dspl_float);
mrealloc(f_localFBuf[c], f_localFBufSize[c]);
end;
//
// sum up samples in this channel with current band
for s := 0 to nSamples - 1 do begin
//
if (f_bandPT[b]) then
f := outBuf^
else
f := 0.0; // this band is not included in result
//
if (0 = b) then
f_localFBuf[c][s] := f // take samples from first band as a result
else
f_localFBuf[c][s] := f_localFBuf[c][s] + f;
//
inc(outBuf);
end;
//
end; // for all bands
//
// notify we have some samples ready
if (assigned(f_onRawSamplesAvail)) then
f_onRawSamplesAvail(self, nSamples, numBands, c, @f_localRaw[c]);
//
end; // for all channels
//
// 2. convert result to output buffer
//
for c := 0 to pcmChannels - 1 do begin
//
nSamples := f_localFBufSize[c] div sizeOf(dspl_float);
//
result := nSamples * pcmChannels * (1 + (pcmBits - 1) shr 3);
if (f_localBufSize < result) then begin
//
mrealloc(f_localBuf, result);
f_localBufSize := result;
end;
//
p := c;
for s := 0 to nSamples - 1 do begin
//
f := f_localFBuf[c][s];
if (f > 1.0) then
f := 1.0;
//
if (f < -1.0) then
f := -1.0;
//
case (pcmBits) of
8: pArray(f_localBuf)[p] := trunc(f * $FF + $80);
16: pSmallIntArray(f_localBuf)[p] := trunc(f * $7FFF);
24: pInt32Array(f_localBuf)[p] := trunc(f * $7FFFFF);
32: pFloatArray(f_localBuf)[p] := f;
end;
//
inc(p, pcmChannels); // go to next sample in same channel
//
end; // for all samples
end; // for all channels
//
buf := f_localBuf;
//
end; // 0 < channels
end;
// -- --
constructor TunavclDSPDLibMBSP.create(owner: tComponent);
var
i: int;
begin
inherited; // creates automation
//
f_dsplObj := automation.dspl_objNew(DSPL_OID or DSPL_MBSP);
//
for i := low(f_bandPT) to high(f_bandPT) do
f_bandPT[i] := true;
end;
// -- --
function TunavclDSPDLibMBSP.getNumFreq(): int;
begin
result := numBands - 1;
end;
// -- --
function TunavclDSPDLibMBSP.getPT(band: uint): bool;
begin
result := f_bandPT[band];
end;
// -- --
procedure TunavclDSPDLibMBSP.setPT(band: uint; value: bool);
begin
f_bandPT[band] := value;
end;
//
// -- IDE --
//
procedure Register();
begin
RegisterComponents('VC2.5 DSP', [
TunavclDSPDLibEQ,
TunavclDSPDLibMBSP
]);
end;
// -- unit globals --
initialization
g_root := unaDspDLibRoot.create();
finalization
freeAndNil(g_root);
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -