function effect8BitWav(const sp: SpParam): integer;
function effect16BitWav(const sp: SpParam): integer;
+function sinc(x: Single): Single;
procedure usage;
function effectwav(const sp: SpParam): integer;
implementation
function effect8BitWav(const sp: SpParam): integer;
-const
- depth = 1.0;
- rate = 170.0;
-var
- i, delayStart: integer;
- k, m: Single;
- pMem, pCpy: array of Byte;
- s: TMemoryStream;
begin
- result := 0;
- try
- s := TMemoryStream.Create;
- s.Write(sp.pWav^, sp.sizeOfData);
- s.Position := 0;
- s.Read(Pointer(pCpy)^, sp.sizeOfData);
- pMem := sp.pWav;
- i := sp.posOfData;
- k := 8 * sp.sizeOfData / sp.bitsPerSample;
- while i < k do
- begin
- m := depth * sin(2 * pi * rate / sp.samplePerSec);
- pMem[i + 0] := trunc(m * pMem[i + 0]) + 128;
- pMem[i + 1] := trunc(m * pMem[i + 1]) + 128;
- inc(i, 2);
- end;
- except
- result := -1;
- end;
- s.Free;
- Finalize(pCpy);
end;
function effect16BitWav(const sp: SpParam): integer;
const
j = 24;
var
- i, a, b, pmin, pmax, temp_size, offset0, offset1, p, q: integer;
- k, m, max, pitch, rate: Single;
- pMem, pCpy: array of SmallInt;
- r: array of Single;
+ i, k, a, b, pmin, pmax: integer;
+ len, temp_size, offset0, offset1, p, q: integer;
+ m, ma, pitch, rate: Single;
+ pMem, pCpy, pRes: array of SmallInt;
s: TMemoryStream;
+ r: array of Single;
begin
result := 0;
- s := TMemoryStream.Create;
try
- SetLength(pCpy, sp.sizeOfData);
- s.Write(sp.pWav^, sp.sizeOfData);
- s.Position := 0;
- s.Read(Pointer(pCpy)^, sp.sizeOfData);
- pMem := sp.pWav;
- i := sp.posOfData;
- k := 8 * sp.sizeOfData / sp.bitsPerSample;
- temp_size := trunc(sp.samplePerSec * 0.01);
- pmin := trunc(sp.samplePerSec * sp.bitsPerSample * 0.005);
- pmax := trunc(sp.samplePerSec * sp.bitsPerSample * 0.02);
+ temp_size := trunc(sp.samplePerSec * sp.bitsPerSample * sp.channels * 0.01);
+ pmin := trunc(sp.samplePerSec * sp.bitsPerSample * sp.channels * 0.005);
+ pmax := trunc(sp.samplePerSec * sp.bitsPerSample * sp.channels * 0.02);
SetLength(r, pmax - pmin);
offset0 := sp.posOfData;
offset1 := sp.posOfData;
rate := 0.66;
- while offset0 + pmax * 2 < sp.sizeOfData do
+ len := trunc(sp.sizeOfData / (rate * sp.channels));
+ SetLength(pCpy, len);
+ SetLength(pRes, len);
+ s := TMemoryStream.Create;
+ s.Write(sp.pWav^, sp.sizeOfData);
+ s.Position := 0;
+ s.Read(Pointer(pRes)^, s.Size);
+ s.Free;
+ Pointer(pMem) := sp.pWav;
+ k := (sp.sizeOfData - sp.posOfData) div sp.channels;
+ ma := 0.0;
+ p := pmin;
+ for b := 0 to pmax - pmin - 1 do
begin
- max := 0.0;
- p := pmin;
- for b := pmin to pmax do
+ r[b] := 0.0;
+ for a := sp.posOfData to sp.posOfData + temp_size do
+ r[b] := r[b] + pMem[a] * pMem[a + b];
+ if r[b] > ma then
begin
- r[b] := 0.0;
- for a := sp.posOfData to sp.posOfData + temp_size do
- r[b] := r[b] + pMem[a] * pCpy[a + b];
- if r[b] > max then
- begin
- max := r[b];
- p := b;
- end;
+ ma := r[b];
+ p := b;
end;
- for i := 0 to p - 1 do
+ end;
+ while offset1 + 2 * pmax < len do
+ begin
+ for i := 0 to p do
begin
- pMem[offset1 + i] := trunc(pCpy[offset0 + i]);
- pMem[offset1 + i + p] := trunc(pCpy[offset0 + p + i] * (p - i) / p +
- pCpy[offset0 + i] * i / p);
+ pCpy[offset1 + i] := pRes[offset0 + i];
+ pCpy[offset1 + i + p] := trunc(pRes[offset0 + p + i] * (p - i) / p +
+ pRes[offset0 + i] * i / p);
end;
q := trunc(rate * p / (1.0 - rate) + 0.5);
for i := p to q - 1 do
begin
- if offset0 + i >= sp.sizeOfData then
+ if offset1 + i + p >= len then
break;
- pMem[offset1 + p + i] := pCpy[offset0 + i];
+ pCpy[offset1 + p + i] := pMem[offset0 + i];
end;
inc(offset0, q);
inc(offset1, p + q);
end;
- pitch := 0.66;
- for i := sp.posOfData to sp.sizeOfData do
+ pitch := 1.5;
+ for i := sp.posOfData to k - 1 do
begin
m := pitch * i;
q := trunc(m);
for a := q - j div 2 to q + j div 2 do
- if (m >= sp.posOfData) and (m < sp.sizeOfData) then
- pMem[a] := trunc(pMem[a + 0] + pCpy[a + 0] * ArcSin(pi * (m - a)));
+ if (a >= sp.posOfData) and (a < len) then
+ pMem[i] := pCpy[a] + pRes[a] * trunc(sinc(pi * (m - a)))
+ else
+ pMem[i] := 0;
end;
except
result := -1;
end;
- Finalize(r);
- s.Free;
+ Finalize(pRes);
Finalize(pCpy);
+ Finalize(r);
+end;
+
+function sinc(x: Single): Single;
+begin
+ if x = 0 then
+ result := 1.0
+ else
+ result := sin(x) / x;
end;
procedure usage;
if sp.channels = 1 then
begin
Writeln('\83X\83e\83\8c\83I\83t\83@\83C\83\8b\82É\82µ\82Ä\82\82¾\82³\82¢');
- result := -1;
+ // result := -1;
end;
if sp.bitsPerSample = 8 then
result := effect8BitWav(sp)