Last active
January 31, 2022 07:47
-
-
Save sp5wwp/8001cc716ed7b67c0a9a6943dca9bf0a to your computer and use it in GitHub Desktop.
Scalar Quantizer codebook generator script for Codec 2 delta LSF encoder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
%-----------------------------------------------------------------------% | |
% Scalar Quantizer codebook generator for Codec 2 | |
% | |
% Wojciech Kaczmarski, SP5WWP | |
% M17 Project, 28/01/2022 | |
%-----------------------------------------------------------------------% | |
%consts | |
SPF=160; % 20ms frame at 8kHz = 160 samples per frame | |
%sample | |
[sample, Fs]=audioread("corpus.wav"); | |
%window | |
w=hamming(SPF); | |
len=length(sample); | |
frame=zeros(SPF); | |
a=zeros(11); | |
n_frames=(len-mod(len, SPF)-SPF)/(SPF/2); | |
lsf=zeros(n_frames, 10); | |
%iterate through the whole sample, but omit last few samples | |
%samples overlap! thats why the step is set to SPF/2 | |
for i=1:SPF/2:len-mod(len, SPF)-SPF | |
frame=sample(i:i+SPF-1).*w; | |
[a, ~]=lpc(frame, 10); | |
lsf(round(i/(SPF/2)+1),:) = poly2lsf(a).'; %cos(poly2lsf(a).'); %cosine domain | |
end | |
%--------------------------generate codebooks--------------------------- | |
%-------------------------------dlsp1.txt------------------------------- | |
fp=fopen('dlsp1.txt', 'w'); | |
fprintf(fp, "1 32\n"); | |
h=histogram((lsf(:,1)/pi*4000.0), 200); | |
set=[]; | |
for i=1:200 | |
for j=1:(h.BinCounts(i)) | |
set(end+1,1)=h.BinEdges(i)+h.BinWidth/2.0; | |
end | |
end | |
[~, qn0]=kmeans(set(:,1), 32); | |
qn0=sort(qn0,1,'ascend'); | |
for i=1:32 | |
fprintf(fp, "%1.1f\n", qn0(i)); | |
end | |
fprintf(fp, "\n"); | |
fclose(fp); | |
%-------------------------------dlsp2.txt------------------------------- | |
fp=fopen('dlsp2.txt', 'w'); | |
fprintf(fp, "1 32\n"); | |
deltas=[]; | |
for i=1:n_frames | |
k(1)=dsearchn(qn0, (lsf(i,1)/pi*4000.0)); | |
if (lsf(i,2)/pi*4000.0)-qn0(k(1))>5 %we dont want to have LSFs too close to each other | |
deltas(end+1)=(lsf(i,2)/pi*4000.0)-qn0(k(1)); | |
end | |
end | |
h=histogram(deltas, 200); | |
set=[]; | |
for i=1:200 | |
for j=1:(h.BinCounts(i)) | |
set(end+1,1)=h.BinEdges(i)+h.BinWidth/2.0; | |
end | |
end | |
[~, qn1]=kmeans(set(:,1), 32); | |
qn1=sort(qn1,1,'ascend'); | |
for i=1:32 | |
fprintf(fp, "%1.1f\n", qn1(i)); | |
end | |
fprintf(fp, "\n"); | |
fclose(fp); | |
%-------------------------------dlsp3.txt------------------------------- | |
fp=fopen('dlsp3.txt', 'w'); | |
fprintf(fp, "1 32\n"); | |
deltas=[]; | |
for i=1:n_frames | |
k(1)=dsearchn(qn0, (lsf(i,1)/pi*4000.0)); | |
k(2)=dsearchn(qn1, (lsf(i,2)/pi*4000.0)-qn0(k(1))); | |
if (lsf(i,3)/pi*4000.0)-qn0(k(1))-qn1(k(2))>5 %we dont want to have LSFs too close to each other | |
deltas(end+1)=(lsf(i,3)/pi*4000.0)-qn0(k(1))-qn1(k(2)); | |
end | |
end | |
h=histogram(deltas, 200); | |
set=[]; | |
for i=1:200 | |
for j=1:(h.BinCounts(i)) | |
set(end+1,1)=h.BinEdges(i)+h.BinWidth/2.0; | |
end | |
end | |
[~, qn2]=kmeans(set(:,1), 32); | |
qn2=sort(qn2,1,'ascend'); | |
for i=1:32 | |
fprintf(fp, "%1.1f\n", qn2(i)); | |
end | |
fprintf(fp, "\n"); | |
fclose(fp); | |
%-------------------------------dlsp4.txt------------------------------- | |
fp=fopen('dlsp4.txt', 'w'); | |
fprintf(fp, "1 32\n"); | |
deltas=[]; | |
for i=1:n_frames | |
k(1)=dsearchn(qn0, (lsf(i,1)/pi*4000.0)); | |
k(2)=dsearchn(qn1, (lsf(i,2)/pi*4000.0)-qn0(k(1))); | |
k(3)=dsearchn(qn2, (lsf(i,3)/pi*4000.0)-qn1(k(2))-qn0(k(1))); | |
if (lsf(i,4)/pi*4000.0)-qn0(k(1))-qn1(k(2))-qn2(k(3))>5 %we dont want to have LSFs too close to each other | |
deltas(end+1)=(lsf(i,4)/pi*4000.0)-qn0(k(1))-qn1(k(2))-qn2(k(3)); | |
end | |
end | |
h=histogram(deltas, 200); | |
set=[]; | |
for i=1:200 | |
for j=1:(h.BinCounts(i)) | |
set(end+1,1)=h.BinEdges(i)+h.BinWidth/2.0; | |
end | |
end | |
[~, qn3]=kmeans(set(:,1), 32); | |
qn3=sort(qn3,1,'ascend'); | |
for i=1:32 | |
fprintf(fp, "%1.1f\n", qn3(i)); | |
end | |
fprintf(fp, "\n"); | |
fclose(fp); | |
%-------------------------------dlsp5.txt------------------------------- | |
fp=fopen('dlsp5.txt', 'w'); | |
fprintf(fp, "1 32\n"); | |
deltas=[]; | |
for i=1:n_frames | |
k(1)=dsearchn(qn0, (lsf(i,1)/pi*4000.0)); | |
k(2)=dsearchn(qn1, (lsf(i,2)/pi*4000.0)-qn0(k(1))); | |
k(3)=dsearchn(qn2, (lsf(i,3)/pi*4000.0)-qn1(k(2))-qn0(k(1))); | |
k(4)=dsearchn(qn3, (lsf(i,4)/pi*4000.0)-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
if (lsf(i,5)/pi*4000.0)-qn0(k(1))-qn1(k(2))-qn2(k(3))-qn3(k(4))>5 %we dont want to have LSFs too close to each other | |
deltas(end+1)=(lsf(i,5)/pi*4000.0)-qn0(k(1))-qn1(k(2))-qn2(k(3))-qn3(k(4)); | |
end | |
end | |
h=histogram(deltas, 200); | |
set=[]; | |
for i=1:200 | |
for j=1:(h.BinCounts(i)) | |
set(end+1,1)=h.BinEdges(i)+h.BinWidth/2.0; | |
end | |
end | |
[~, qn4]=kmeans(set(:,1), 32); | |
qn4=sort(qn4,1,'ascend'); | |
for i=1:32 | |
fprintf(fp, "%1.1f\n", qn4(i)); | |
end | |
fprintf(fp, "\n"); | |
fclose(fp); | |
%-------------------------------dlsp6.txt------------------------------- | |
fp=fopen('dlsp6.txt', 'w'); | |
fprintf(fp, "1 32\n"); | |
deltas=[]; | |
for i=1:n_frames | |
k(1)=dsearchn(qn0, (lsf(i,1)/pi*4000.0)); | |
k(2)=dsearchn(qn1, (lsf(i,2)/pi*4000.0)-qn0(k(1))); | |
k(3)=dsearchn(qn2, (lsf(i,3)/pi*4000.0)-qn1(k(2))-qn0(k(1))); | |
k(4)=dsearchn(qn3, (lsf(i,4)/pi*4000.0)-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
k(5)=dsearchn(qn4, (lsf(i,5)/pi*4000.0)-qn3(k(4))-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
if (lsf(i,6)/pi*4000.0)-qn0(k(1))-qn1(k(2))-qn2(k(3))-qn3(k(4))-qn4(k(5))>5 %we dont want to have LSFs too close to each other | |
deltas(end+1)=(lsf(i,6)/pi*4000.0)-qn0(k(1))-qn1(k(2))-qn2(k(3))-qn3(k(4))-qn4(k(5)); | |
end | |
end | |
h=histogram(deltas, 200); | |
set=[]; | |
for i=1:200 | |
for j=1:(h.BinCounts(i)) | |
set(end+1,1)=h.BinEdges(i)+h.BinWidth/2.0; | |
end | |
end | |
[~, qn5]=kmeans(set(:,1), 32); | |
qn5=sort(qn5,1,'ascend'); | |
for i=1:32 | |
fprintf(fp, "%1.1f\n", qn5(i)); | |
end | |
fprintf(fp, "\n"); | |
fclose(fp); | |
%-------------------------------dlsp7.txt------------------------------- | |
fp=fopen('dlsp7.txt', 'w'); | |
fprintf(fp, "1 32\n"); | |
deltas=[]; | |
for i=1:n_frames | |
k(1)=dsearchn(qn0, (lsf(i,1)/pi*4000.0)); | |
k(2)=dsearchn(qn1, (lsf(i,2)/pi*4000.0)-qn0(k(1))); | |
k(3)=dsearchn(qn2, (lsf(i,3)/pi*4000.0)-qn1(k(2))-qn0(k(1))); | |
k(4)=dsearchn(qn3, (lsf(i,4)/pi*4000.0)-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
k(5)=dsearchn(qn4, (lsf(i,5)/pi*4000.0)-qn3(k(4))-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
k(6)=dsearchn(qn5, (lsf(i,6)/pi*4000.0)-qn4(k(5))-qn3(k(4))-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
if (lsf(i,7)/pi*4000.0)-qn0(k(1))-qn1(k(2))-qn2(k(3))-qn3(k(4))-qn4(k(5))-qn5(k(6))>5 %we dont want to have LSFs too close to each other | |
deltas(end+1)=(lsf(i,7)/pi*4000.0)-qn0(k(1))-qn1(k(2))-qn2(k(3))-qn3(k(4))-qn4(k(5))-qn5(k(6)); | |
end | |
end | |
h=histogram(deltas, 200); | |
set=[]; | |
for i=1:200 | |
for j=1:(h.BinCounts(i)) | |
set(end+1,1)=h.BinEdges(i)+h.BinWidth/2.0; | |
end | |
end | |
[~, qn6]=kmeans(set(:,1), 32); | |
qn6=sort(qn6,1,'ascend'); | |
for i=1:32 | |
fprintf(fp, "%1.1f\n", qn6(i)); | |
end | |
fprintf(fp, "\n"); | |
fclose(fp); | |
%-------------------------------dlsp8.txt------------------------------- | |
fp=fopen('dlsp8.txt', 'w'); | |
fprintf(fp, "1 32\n"); | |
deltas=[]; | |
for i=1:n_frames | |
k(1)=dsearchn(qn0, (lsf(i,1)/pi*4000.0)); | |
k(2)=dsearchn(qn1, (lsf(i,2)/pi*4000.0)-qn0(k(1))); | |
k(3)=dsearchn(qn2, (lsf(i,3)/pi*4000.0)-qn1(k(2))-qn0(k(1))); | |
k(4)=dsearchn(qn3, (lsf(i,4)/pi*4000.0)-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
k(5)=dsearchn(qn4, (lsf(i,5)/pi*4000.0)-qn3(k(4))-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
k(6)=dsearchn(qn5, (lsf(i,6)/pi*4000.0)-qn4(k(5))-qn3(k(4))-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
k(7)=dsearchn(qn6, (lsf(i,7)/pi*4000.0)-qn5(k(6))-qn4(k(5))-qn3(k(4))-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
if (lsf(i,8)/pi*4000.0)-qn0(k(1))-qn1(k(2))-qn2(k(3))-qn3(k(4))-qn4(k(5))-qn5(k(6))-qn6(k(7))>5 %we dont want to have LSFs too close to each other | |
deltas(end+1)=(lsf(i,8)/pi*4000.0)-qn0(k(1))-qn1(k(2))-qn2(k(3))-qn3(k(4))-qn4(k(5))-qn5(k(6))-qn6(k(7)); | |
end | |
end | |
h=histogram(deltas, 200); | |
set=[]; | |
for i=1:200 | |
for j=1:(h.BinCounts(i)) | |
set(end+1,1)=h.BinEdges(i)+h.BinWidth/2.0; | |
end | |
end | |
[~, qn7]=kmeans(set(:,1), 32); | |
qn7=sort(qn7,1,'ascend'); | |
for i=1:32 | |
fprintf(fp, "%1.1f\n", qn7(i)); | |
end | |
fprintf(fp, "\n"); | |
fclose(fp); | |
%-------------------------------dlsp9.txt------------------------------- | |
fp=fopen('dlsp9.txt', 'w'); | |
fprintf(fp, "1 32\n"); | |
deltas=[]; | |
for i=1:n_frames | |
k(1)=dsearchn(qn0, (lsf(i,1)/pi*4000.0)); | |
k(2)=dsearchn(qn1, (lsf(i,2)/pi*4000.0)-qn0(k(1))); | |
k(3)=dsearchn(qn2, (lsf(i,3)/pi*4000.0)-qn1(k(2))-qn0(k(1))); | |
k(4)=dsearchn(qn3, (lsf(i,4)/pi*4000.0)-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
k(5)=dsearchn(qn4, (lsf(i,5)/pi*4000.0)-qn3(k(4))-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
k(6)=dsearchn(qn5, (lsf(i,6)/pi*4000.0)-qn4(k(5))-qn3(k(4))-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
k(7)=dsearchn(qn6, (lsf(i,7)/pi*4000.0)-qn5(k(6))-qn4(k(5))-qn3(k(4))-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
k(8)=dsearchn(qn7, (lsf(i,8)/pi*4000.0)-qn6(k(7))-qn5(k(6))-qn4(k(5))-qn3(k(4))-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
if (lsf(i,9)/pi*4000.0)-qn0(k(1))-qn1(k(2))-qn2(k(3))-qn3(k(4))-qn4(k(5))-qn5(k(6))-qn6(k(7))-qn7(k(8))>5 %we dont want to have LSFs too close to each other | |
deltas(end+1)=(lsf(i,9)/pi*4000.0)-qn0(k(1))-qn1(k(2))-qn2(k(3))-qn3(k(4))-qn4(k(5))-qn5(k(6))-qn6(k(7))-qn7(k(8)); | |
end | |
end | |
h=histogram(deltas, 200); | |
set=[]; | |
for i=1:200 | |
for j=1:(h.BinCounts(i)) | |
set(end+1,1)=h.BinEdges(i)+h.BinWidth/2.0; | |
end | |
end | |
[~, qn8]=kmeans(set(:,1), 32); | |
qn8=sort(qn8,1,'ascend'); | |
for i=1:32 | |
fprintf(fp, "%1.1f\n", qn8(i)); | |
end | |
fprintf(fp, "\n"); | |
fclose(fp); | |
%-------------------------------dlsp10.txt------------------------------- | |
fp=fopen('dlsp10.txt', 'w'); | |
fprintf(fp, "1 32\n"); | |
deltas=[]; | |
for i=1:n_frames | |
k(1)=dsearchn(qn0, (lsf(i,1)/pi*4000.0)); | |
k(2)=dsearchn(qn1, (lsf(i,2)/pi*4000.0)-qn0(k(1))); | |
k(3)=dsearchn(qn2, (lsf(i,3)/pi*4000.0)-qn1(k(2))-qn0(k(1))); | |
k(4)=dsearchn(qn3, (lsf(i,4)/pi*4000.0)-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
k(5)=dsearchn(qn4, (lsf(i,5)/pi*4000.0)-qn3(k(4))-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
k(6)=dsearchn(qn5, (lsf(i,6)/pi*4000.0)-qn4(k(5))-qn3(k(4))-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
k(7)=dsearchn(qn6, (lsf(i,7)/pi*4000.0)-qn5(k(6))-qn4(k(5))-qn3(k(4))-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
k(8)=dsearchn(qn7, (lsf(i,8)/pi*4000.0)-qn6(k(7))-qn5(k(6))-qn4(k(5))-qn3(k(4))-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
k(9)=dsearchn(qn8, (lsf(i,9)/pi*4000.0)-qn7(k(8))-qn6(k(7))-qn5(k(6))-qn4(k(5))-qn3(k(4))-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
if (lsf(i,10)/pi*4000.0)-qn0(k(1))-qn1(k(2))-qn2(k(3))-qn3(k(4))-qn4(k(5))-qn5(k(6))-qn6(k(7))-qn7(k(8))-qn8(k(9))>5 %we dont want to have LSFs too close to each other | |
deltas(end+1)=(lsf(i,10)/pi*4000.0)-qn0(k(1))-qn1(k(2))-qn2(k(3))-qn3(k(4))-qn4(k(5))-qn5(k(6))-qn6(k(7))-qn7(k(8))-qn8(k(9)); | |
end | |
end | |
h=histogram(deltas, 200); | |
set=[]; | |
for i=1:200 | |
for j=1:(h.BinCounts(i)) | |
set(end+1,1)=h.BinEdges(i)+h.BinWidth/2.0; | |
end | |
end | |
[~, qn9]=kmeans(set(:,1), 32); | |
qn9=sort(qn9,1,'ascend'); | |
for i=1:32 | |
fprintf(fp, "%1.1f\n", qn9(i)); | |
end | |
fprintf(fp, "\n"); | |
fclose(fp); | |
%-------------------------------test------------------------------- | |
k(1)=dsearchn(qn0, lsf(500,1)/pi*4000.0); | |
err(1)=qn0(k(1))-lsf(500,1)/pi*4000.0; | |
k(2)=dsearchn(qn1, lsf(500,2)/pi*4000.0-qn0(k(1))); | |
err(2)=qn0(k(1))+qn1(k(2))-lsf(500,2)/pi*4000.0; | |
k(3)=dsearchn(qn2, lsf(500,3)/pi*4000.0-qn1(k(2))-qn0(k(1))); | |
err(3)=qn0(k(1))+qn1(k(2))+qn2(k(3))-lsf(500,3)/pi*4000.0; | |
k(4)=dsearchn(qn3, lsf(500,4)/pi*4000.0-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
err(4)=qn0(k(1))+qn1(k(2))+qn2(k(3))+qn3(k(4))-lsf(500,4)/pi*4000.0; | |
k(5)=dsearchn(qn4, lsf(500,5)/pi*4000.0-qn3(k(4))-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
err(5)=qn0(k(1))+qn1(k(2))+qn2(k(3))+qn3(k(4))+qn4(k(5))-lsf(500,5)/pi*4000.0; | |
k(6)=dsearchn(qn5, lsf(500,6)/pi*4000.0-qn4(k(5))-qn3(k(4))-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
err(6)=qn0(k(1))+qn1(k(2))+qn2(k(3))+qn3(k(4))+qn4(k(5))+qn5(k(6))-lsf(500,6)/pi*4000.0; | |
k(7)=dsearchn(qn6, lsf(500,7)/pi*4000.0-qn5(k(6))-qn4(k(5))-qn3(k(4))-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
err(7)=qn0(k(1))+qn1(k(2))+qn2(k(3))+qn3(k(4))+qn4(k(5))+qn5(k(6))+qn6(k(7))-lsf(500,7)/pi*4000.0; | |
k(8)=dsearchn(qn7, lsf(500,8)/pi*4000.0-qn6(k(7))-qn5(k(6))-qn4(k(5))-qn3(k(4))-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
err(8)=qn0(k(1))+qn1(k(2))+qn2(k(3))+qn3(k(4))+qn4(k(5))+qn5(k(6))+qn6(k(7))+qn7(k(8))-lsf(500,8)/pi*4000.0; | |
k(9)=dsearchn(qn8, lsf(500,9)/pi*4000.0-qn7(k(8))-qn6(k(7))-qn5(k(6))-qn4(k(5))-qn3(k(4))-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
err(9)=qn0(k(1))+qn1(k(2))+qn2(k(3))+qn3(k(4))+qn4(k(5))+qn5(k(6))+qn6(k(7))+qn7(k(8))+qn8(k(9))-lsf(500,9)/pi*4000.0; | |
k(10)=dsearchn(qn9, lsf(500,10)/pi*4000.0-qn8(k(9))-qn7(k(8))-qn6(k(7))-qn5(k(6))-qn4(k(5))-qn3(k(4))-qn2(k(3))-qn1(k(2))-qn0(k(1))); | |
err(10)=qn0(k(1))+qn1(k(2))+qn2(k(3))+qn3(k(4))+qn4(k(5))+qn5(k(6))+qn6(k(7))+qn7(k(8))+qn8(k(9))+qn9(k(10))-lsf(500,10)/pi*4000.0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment