<?xml version="1.0" encoding="windows-1252" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg xmlns="http://www.w3.org/2000/svg" width="1000" height="1000" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>test</title>
<g>
</g>
<script>
<![CDATA[
// Screenkoordinaten
var x0 = 0;
var xn = 1000;
var y0 = 1000;
var yn = 0;
// Wertebereich
var X0 = 0.1;
var Xn = 0.105;
var Y0 = -1.1;
var Yn = 1.1;
function toScreen(X, X0, Xn, x0, xn)
{
return x0 + (X - X0) / (Xn - X0) * (xn - x0);
}
function X2S(X)
{
return toScreen(X, X0, Xn, x0, xn);
}
function Y2S(Y)
{
return toScreen(Y, Y0, Yn, y0, yn);
}
var svgroot = document.documentElement;
function drawAxes(c, w)
{
var lineX = document.createElementNS("http://www.w3.org/2000/svg", "line");
lineX.style.fill = "none";
lineX.style.stroke = c;
lineX.style.strokeWidth = "" + w + "px";
lineX.x1.baseVal.value = X2S(0);
lineX.y1.baseVal.value = Y2S(Y0);
lineX.x2.baseVal.value = X2S(0);
lineX.y2.baseVal.value = Y2S(Yn);
svgroot.appendChild(lineX);
var lineY = document.createElementNS("http://www.w3.org/2000/svg", "line");
lineY.style.fill = "none";
lineY.style.stroke = c;
lineY.style.strokeWidth = "" + w + "px";
lineY.x1.baseVal.value = X2S(X0);
lineY.y1.baseVal.value = Y2S(0);
lineY.x2.baseVal.value = X2S(Xn);
lineY.y2.baseVal.value = Y2S(0);
svgroot.appendChild(lineY);
}
function drawBuffer(b, c, w)
{
b.length
var path = document.createElementNS("http://www.w3.org/2000/svg", "path");
segments = path.pathSegList;
path.style.fill = "none";
path.style.stroke = c;
path.style.strokeWidth = "" + w + "px";
segments.appendItem(path.createSVGPathSegMovetoAbs(X2S(0), Y2S(0)));
for (var x = 0; x < b.length; ++x)
{
if (!isNaN(b[x]))
{
segments.appendItem(path.createSVGPathSegLinetoAbs(X2S(x/b.length), Y2S(b[x])));
}
}
svgroot.appendChild(path);
}
]]>
</script>
<script>
<![CDATA[
function calcSplinesParams(b, p0, pn, A, B, C, D)
{
var n = b.length - 1;
function buildLES(b, p0, pn, B, d)
{
var n = b.length - 1;
for (var i = 1; i < n; ++i)
{
B[i] = [];
for (var j = 0; j <= n; ++j)
{
switch (j)
{
case i - 1:
B[i][j] = i / b.length - (i - 1) / b.length;
break;
case i:
B[i][j] = 2 * ((i + 1) / b.length - (i - 1) / b.length);
break;
case i + 1:
B[i][j] = (i + 1) / b.length - i / b.length;
break;
default:
B[i][j] = 0;
}
}
d[i] = 3 * ((b[i+1] - b[i]) / ((i + 1) / b.length - i / b.length) - (b[i] - b[i-1]) / (i / b.length - (i - 1) / b.length));
}
// 2 Zusatzbedingungen
B[0] = [];
B[n] = [];
for (var j = 0; j <= n; ++j)
{
B[0][j] = 0;
B[n][j] = 0;
}
B[0][0] = 2;
d[0] = p0;
B[n][n] = 2;
d[n] = pn;
}
function solveLES(A, b)
{
// Lösen des lin. Gl. Systems A*x=b nach Gauß
var n = b.length;
// Diagonalenfeld normalisieren
for (var i = 0; i < n; ++i)
{
if (A[i][i] == 0) // 0-en in der Diagonale entfernen
{
for (var j = i + 1; j < n; ++j)
{
if (A[j][i] != 0)
{
for (var k = 0; k < n; k++)
{
A[i][k] += A[j][k];
}
b[i] += b[j];
break;
}
}
}
// Diagonalen auf 1 bringen
var d = A[i][i];
if (d != 0)
{
for (var j = 0; j < n; ++j)
{
A[i][j] /= d;
}
b[i] /= d;
}
// Spalten außerhalb der Diagonalen auf 0 bringen
for (var j = 0; j < n; ++j)
{
if (i != j )
{
d = A[j][i];
for (var k = 0; k < n; ++k)
{
A[j][k] -= d * A[i][k];
}
b[j] -= d * b[i];
}
}
}
}
var M = [];
var a = [];
var be = [];
var c = [];
buildLES(b, p0, pn, M, be);
solveLES(M, be);
for(var i = 0; i < n; ++i)
{
a[i]=(be[i+1] - be[i]) / (3 * ((i + 1) / b.length - (i) / b.length));
c[i]=(b[i+1] - b[i]) / ((i + 1) / b.length - (i) / b.length) - (be[i+1] + 2 * be[i]) / 3 * ((i + 1) / b.length - (i) / b.length);
}
// jetzt haben wir Si(x)=ai(x-xi)^3 + bi(x-xi)^2 + ci(x-xi) + yi
for(var i = 0; i < n; ++i)
{
A[i] = a[i];
B[i] = be[i] - 3 * a[i] * (i / b.length);
C[i] = 3 * a[i] * (i / b.length) * (i / b.length) - 2 * be[i] * (i / b.length) + c[i];
D[i] = -a[i] * (i / b.length) * (i / b.length) * (i / b.length) + be[i] * (i / b.length) * (i / b.length) - c[i] * (i / b.length) + b[i];
}
// jetzt haben wir Si(x)=Ai*x^3 + Bi*x^2 + Ci*x + Di
}
function calcSplinesParamsForPoints(b, p0, pn, A, B, C, D, n0, nx)
{
var P = [];
var n = 0;
for (var p = n0; p <= nx; p++)
{
if (p >= 0 && p < b.length)
{
P[n++] = {
x: p / b.length,
y: b[p]
};
}
}
n = P.length - 1;
function buildLES(P, p0, pn, B, d)
{
var n = P.length - 1;
for (var i = 1; i < n; ++i)
{
B[i] = [];
for (var j = 0; j <= n; ++j)
{
switch (j)
{
case i - 1:
B[i][j] = P[i].x - P[i-1].x;
break;
case i:
B[i][j] = 2 * (P[i+1].x - P[i-1].x);
break;
case i + 1:
B[i][j] = P[i+1].x - P[i].x;
break;
default:
B[i][j] = 0;
}
}
d[i] = 3 * ((P[i+1].y - P[i].y) / (P[i+1].x - P[i].x) - (P[i].y - P[i-1].y) / (P[i].x - P[i-1].x));
}
// 2 Zusatzbedingungen
B[0] = [];
B[n] = [];
for (var j = 0; j <= n; ++j)
{
B[0][j] = 0;
B[n][j] = 0;
}
B[0][0] = 2;
d[0] = p0;
B[n][n] = 2;
d[n] = pn;
}
function solveLES(A, b)
{
// Lösen des lin. Gl. Systems A*x=b nach Gauß
var n = b.length;
// Diagonalenfeld normalisieren
for (var i = 0; i < n; ++i)
{
if (A[i][i] == 0) // 0-en in der Diagonale entfernen
{
for (var j = i + 1; j < n; ++j)
{
if (A[j][i] != 0)
{
for (var k = 0; k < n; k++)
{
A[i][k] += A[j][k];
}
b[i] += b[j];
break;
}
}
}
// Diagonalen auf 1 bringen
var d = A[i][i];
if (d != 0)
{
for (var j = 0; j < n; ++j)
{
A[i][j] /= d;
}
b[i] /= d;
}
// Spalten außerhalb der Diagonalen auf 0 bringen
for (var j = 0; j < n; ++j)
{
if (i != j )
{
d = A[j][i];
for (var k = 0; k < n; ++k)
{
A[j][k] -= d * A[i][k];
}
b[j] -= d * b[i];
}
}
}
}
var M = [];
var a = [];
var b = [];
var c = [];
buildLES(P, p0, pn, M, b);
solveLES(M, b);
for(var i = 0; i < n; ++i)
{
a[i]=(b[i+1] - b[i]) / (3 * (P[i+1].x - P[i].x));
c[i]=(P[i+1].y - P[i].y) / (P[i+1].x - P[i].x) - (b[i+1] + 2 * b[i]) / 3 * (P[i+1].x - P[i].x);
}
// jetzt haben wir Si(x)=ai(x-xi)^3 + bi(x-xi)^2 + ci(x-xi) + yi
for(var i = 0; i < n; ++i)
{
A[i] = a[i];
B[i] = b[i] - 3 * a[i] * P[i].x;
C[i] = 3 * a[i] * P[i].x * P[i].x - 2 * b[i] * P[i].x + c[i];
D[i] = -a[i] * P[i].x * P[i].x * P[i].x + b[i] * P[i].x * P[i].x - c[i] * P[i].x + P[i].y;
}
// jetzt haben wir Si(x)=Ai*x^3 + Bi*x^2 + Ci*x + Di
}
]]>
</script>
<script>
<![CDATA[
//globals
var i;
var inRate = 22050;
var outRate = 48000;
var sinusIn = new Float32Array(inRate);
for (i = 0; i < inRate; ++i)
{
sinusIn[i] = Math.random()*2-1;// Math.sin(Math.PI * 2 / inRate * 2 * i);
}
var color = ["blue", "green", "red"];
drawAxes("black", 1);
drawBuffer(sinusIn, "blue", 1)
var sinusOut = new Float32Array(outRate);
for (i = 0; i < outRate; ++i)
{
sinusOut[i] = Math.sin(Math.PI * 2 / outRate * 2 * i);
}
//drawBuffer(sinusOut, "green", 3)
// Krümmung (2. Ableitung) am 1. und am letzten Punkt
var p0 = 1;
var pn = 0;
var sinusC2 = new Float32Array(outRate);
sinusC2[0] = 0; // hier noch den letzten wert aus dem vorherigen durchgang hinzunehmen
for (i = 1; i < outRate; ++i)
{
var A = [];
var B = [];
var C = [];
var D = [];
var inIdx = (i / outRate) * inRate;
inIdx = Math.ceil(inIdx);
if (inIdx > inRate -1)
{
break;
}
calcSplinesParamsForPoints(sinusIn, p0, pn, A, B, C, D, inIdx - 2, inIdx + 1);
if (inIdx > 2)
{
inIdx = 1;
}
else if (inIdx > 1)
{
inIdx = 0;
}
sinusC2[i] = A[inIdx] * i/outRate * i/outRate * i/outRate + B[inIdx] * i/outRate * i/outRate + C[inIdx] * i/outRate + D[inIdx];
}
for (;i < outRate; ++i)
{
// entweder werte puffern oder extrapolieren
sinusC2[i] = 0;
}
drawBuffer(sinusC2, "red", 1);
var outputBuffer = new Float32Array(outRate);
var Len = outputBuffer.length;
var r_ptr = 0;
var ratioWeight = 0;
var pBs = 1.0021354346;
for (var ev=0; ev < Len; ev++)
{
var firstSample = sinusIn[r_ptr];
//Interpolation Sampleratio berechnen
var ratio = pBs * inRate / outRate;
ratioWeight += ratio;
if (1 <= ratioWeight)
{
ratioWeight -= 1;
sinusIn[r_ptr] = 0;
r_ptr+=1;
var sample = sinusIn[r_ptr];
//do Interpolartion
sample = (ratioWeight * sample + (ratio - ratioWeight) * firstSample) / ratio;
}
if (sample < -1) sample = -1;
if (sample > 1) sample = -1;
outputBuffer[ev] = sample;
} //ende for
drawBuffer(outputBuffer, "green", 1);
]]>
</script>
</svg>