Skip to content

Instantly share code, notes, and snippets.

@sp5wwp
Last active January 31, 2022 07:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sp5wwp/8001cc716ed7b67c0a9a6943dca9bf0a to your computer and use it in GitHub Desktop.
Save sp5wwp/8001cc716ed7b67c0a9a6943dca9bf0a to your computer and use it in GitHub Desktop.
Scalar Quantizer codebook generator script for Codec 2 delta LSF encoder
%-----------------------------------------------------------------------%
% 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