Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WP2000 - Codec 2 Algorithm Description #31

Merged
merged 41 commits into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
112f3b5
kicking off Codec 2 documentation
drowe67 Nov 17, 2023
9bc86bc
building up plot support
drowe67 Nov 18, 2023
cef07b4
drafted time-freq speech section, building up sinsuoidal model figure
drowe67 Nov 18, 2023
ce5e8ba
macro for sinusoid
drowe67 Nov 18, 2023
def80d4
building up sinusoid figure
drowe67 Nov 18, 2023
f778670
sinusoidal figure OK
drowe67 Nov 19, 2023
24d7b22
parameter updates
drowe67 Nov 19, 2023
3d9443f
building up encoder block diagram
drowe67 Nov 19, 2023
1b311ba
encoder block diagram
drowe67 Nov 19, 2023
4d2492d
building up detailed design intro
drowe67 Nov 22, 2023
3dca356
building up NLP figure
drowe67 Nov 22, 2023
70bf39e
inserted DC notch into NLP
drowe67 Nov 23, 2023
04ebf69
Mooneer's suggestions - thanks
drowe67 Nov 23, 2023
ed463b0
moved some introductory info from DD to Intro
drowe67 Nov 23, 2023
17a30f0
first draft of NLP section, Glossary
drowe67 Nov 23, 2023
f95b590
sinusoidal encoder block diagram
drowe67 Nov 23, 2023
97b20b4
drafted sinusoidal analysis section
drowe67 Nov 24, 2023
899fce8
building up synthesis section
drowe67 Nov 24, 2023
0b6a207
first pass of synthesis section
drowe67 Nov 25, 2023
125a169
sinusoidal synthesiser figure
drowe67 Nov 25, 2023
b3ed577
rough draft of phase synthesis copied from source
drowe67 Nov 25, 2023
12bbb03
first draft of voicing estimation
drowe67 Nov 27, 2023
9a18256
make notation more consistent across sections
drowe67 Nov 27, 2023
ba7321c
draft of phase synthesis section
drowe67 Nov 28, 2023
fbbea09
phase synthesis edits
drowe67 Nov 28, 2023
f3b4305
phase model edits and LPC/LSP encoder block diagram
drowe67 Nov 29, 2023
067eaa7
LPC/LSP enocder description, decoder block diagram
drowe67 Dec 1, 2023
43defe5
decoder description, mode table
drowe67 Dec 2, 2023
0098976
building up 700C section
drowe67 Dec 6, 2023
71b86a8
mic EQ and VQ mean removal maths
drowemyriota Dec 6, 2023
670b278
aligning 700C figures with maths
drowemyriota Dec 8, 2023
348f68f
added LPC/LSP and LPC post figure figures, plus code to generate them
drowe67 Dec 9, 2023
c27e56d
oops we forgot to rm this in recent clean up
drowe67 Dec 10, 2023
8a9b13e
removed newamp2 code
drowe67 Dec 10, 2023
d1c085a
Added a list or source files; edited Further Work section
drowe67 Dec 10, 2023
05110e5
first pass at Makefile to build doc
drowe67 Dec 10, 2023
7e88771
proof read, minor edits, update symbol glossary
drowe67 Dec 10, 2023
ea0379f
ctest, README.md, first pass at github action
drowe67 Dec 10, 2023
21dd265
way to run doc ctest without over writing codec2.doc
drowe67 Dec 11, 2023
18c5e48
exclude test_codec2_doc when running tests on github actions
drowe67 Dec 11, 2023
b8e4527
don't need tex packages as we've excluded that test for now
drowe67 Dec 11, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
run: |
sudo apt-get update
sudo apt-get install octave octave-common octave-signal liboctave-dev gnuplot sox p7zip-full python3-numpy valgrind clang-format

- name: Create Build Directory
shell: bash
run: mkdir $GITHUB_WORKSPACE/build_linux
Expand Down Expand Up @@ -50,7 +50,7 @@ jobs:
- name: Run ctests
working-directory: ${{github.workspace}}/build_linux
shell: bash
run: ctest --output-on-failure
run: ctest --output-on-failure -E test_codec2_doc

- name: Test library installation
working-directory: ${{github.workspace}}/build_linux
Expand Down
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,11 @@ if(UNITTEST)
COMMAND sh -c "cd ${CMAKE_CURRENT_SOURCE_DIR};
clang-format --dry-run --Werror src/*.c src/*.h unittest/*.c demo/*.c")

add_test(NAME test_codec2_doc
COMMAND sh -c "cd ${CMAKE_CURRENT_SOURCE_DIR}/doc;
make clean;
CODEC2_SRC=${CMAKE_CURRENT_SOURCE_DIR} CODEC2_BINARY=${CMAKE_CURRENT_BINARY_DIR} JOBNAME=test make")

add_test(NAME test_freedv_get_hash
COMMAND sh -c "${CMAKE_CURRENT_BINARY_DIR}/unittest/thash")

Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ We have standardized on C99 and develop and test using gcc on a Linux platform.
make
```

## Documentation

An algorithm description can be found in `doc/codec2.pdf`.

## Programs

+ See `demo` directory for simple examples of using Codec and the FreeDV API.
Expand Down Expand Up @@ -138,7 +142,7 @@ CTest is used as a test framework, with support from [GNU Octave](https://www.gn

1. Install GNU Octave and libraries on Ubuntu with:
```
sudo apt install octave octave-common octave-signal liboctave-dev gnuplot python3-numpy sox valgrind clang-format
sudo apt install octave octave-common octave-signal liboctave-dev gnuplot python3-numpy sox valgrind clang-format texmaker texlive-bibtex-extra texlive-science
```
1. To build and run the tests:
```
Expand Down Expand Up @@ -180,6 +184,7 @@ CTest is used as a test framework, with support from [GNU Octave](https://www.gn
```
cmake - cmake support files
demo - Simple Codec 2 and FreeDv API demo applications
doc - documentation
octave - Octave scripts used to support ctests
src - C source code for Codec 2, FDMDV modem, COHPSK modem, FreeDV API
raw - speech files in raw format (16 bits signed linear 8 kHz)
Expand Down
35 changes: 35 additions & 0 deletions doc/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Makefile for codec2.pdf
#
# usage:
# Build codec2 with -DUNITEST=1 (see README)
# cd ~/codec2/doc
# make

DOCNAME ?= codec2

# Set these externally to override defaults. JOBNAME sets the output file basename,
# and avoids over writing codec2.pdf (e.g. when we are running a doc build test, but don't actually
# want to change codec2.pdf in the repo)

CODEC2_SRC ?= $(HOME)/codec2
CODEC2_BINARY ?= $(HOME)/codec2/build_linux
JOBNAME ?= $(DOCNAME)

PATH := $(PATH):$(CODEC2_BINARY)/src

PLOT_FILES := hts2a_37_sn.tex hts2a_37_sw.tex hts2a_37_lpc_lsp.tex hts2a_37_lpc_pf.tex

$(DOCNAME).pdf: $(PLOT_FILES) $(DOCNAME).tex $(DOCNAME)_refs.bib
pdflatex -jobname=$(JOBNAME) $(DOCNAME).tex
bibtex $(JOBNAME).aux
pdflatex -jobname=$(JOBNAME) $(DOCNAME).tex
pdflatex -jobname=$(JOBNAME) $(DOCNAME).tex

$(PLOT_FILES):
echo $(PATH)
c2sim $(CODEC2_SRC)/raw/hts2a.raw --dump hts2a --lpc 10 --lsp --lpcpf
DISPLAY=""; printf "plamp('hts2a',f=37,epslatex=1)\nq\n" | octave-cli -qf -p $(CODEC2_SRC)/octave

.PHONY: clean
clean:
rm -f *.blg *.bbl *.aux *.log *.out hts2a*
Binary file added doc/codec2.pdf
Binary file not shown.
1,068 changes: 1,068 additions & 0 deletions doc/codec2.tex

Large diffs are not rendered by default.

84 changes: 84 additions & 0 deletions doc/codec2_refs.bib
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
@article{griffin1988multiband,
title={Multiband excitation vocoder},
author={Griffin, Daniel W and Lim, Jae S},
journal={IEEE Transactions on acoustics, speech, and signal processing},
volume={36},
number={8},
pages={1223--1235},
year={1988},
publisher={IEEE}
}
@book{rowe1997techniques,
title={Techniques for harmonic sinusoidal coding},
author={Rowe, David Grant},
year={1997},
publisher={Citeseer},
note = {\url{https://www.rowetel.com/downloads/1997_rowe_phd_thesis.pdf}}
}

@misc{ardc2023,
title = {{Enhancing HF Digital Voice with FreeDV}},
year = {2023},
note = {\url{https://www.ardc.net/apply/grants/2023-grants/enhancing-hf-digital-voice-with-freedv/}}
}

@article{mcaulay1986speech,
title={Speech analysis/synthesis based on a sinusoidal representation},
author={McAulay, Robert and Quatieri, Thomas},
journal={IEEE Transactions on Acoustics, Speech, and Signal Processing},
volume={34},
number={4},
pages={744--754},
year={1986},
publisher={IEEE}
}

@article{makhoul1975linear,
title={Linear prediction: A tutorial review},
author={Makhoul, John},
journal={Proceedings of the IEEE},
volume={63},
number={4},
pages={561--580},
year={1975},
publisher={IEEE}
}

@article{itakura1975line,
title={Line spectrum representation of linear predictor coefficients of speech signals},
author={Itakura, Fumitada},
journal={The Journal of the Acoustical Society of America},
volume={57},
number={S1},
pages={S35--S35},
year={1975},
publisher={AIP Publishing}
}


@book{o1997human,
title={Speech Communication - Human and machine},
author={O‘Shaughnessy, Douglas},
publisher={Addison-Wesley Publishing Company},
year={1997}
}

@misc{rowe2023ratek,
title = {{FreeDV-015 Codec 2 Rate K Resampler}},
year = {2023},
note = {\url{https://github.com/drowe67/misc/blob/master/ratek_resampler/ratek_resampler.pdf}}
}

@book{kondoz1994digital,
title={Digital speech: coding for low bit rate communication systems},
author={Kondoz, Ahmet M},
year={1994},
publisher={John Wiley \& Sons}
}

@book{kleijn1995speech,
title={Speech coding and synthesis},
author={Kleijn, W Bastiaan and Paliwal, Kuldip K},
year={1995},
publisher={Elsevier Science Inc.}
}
Binary file added doc/ratek_mel_fhz.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/warp_fhz_k.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
178 changes: 178 additions & 0 deletions octave/plamp.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
% plamp.m
% Plot ampltiude modelling information from c2sim dump files.

function plamp(samname, f, epslatex=0)

plot_sw = 1;

sn_name = strcat(samname,"_sn.txt");
Sn = load(sn_name);

sw_name = strcat(samname,"_sw.txt");
Sw = load(sw_name);

sw__name = strcat(samname,"_sw_.txt");
if (file_in_path(".",sw__name))
Sw_ = load(sw__name);
endif

ew_name = strcat(samname,"_ew.txt");
if (file_in_path(".",ew_name))
Ew = load(ew_name);
endif

E_name = strcat(samname,"_E.txt");
if (file_in_path(".",E_name))
E = load(E_name);
endif

rk_name = strcat(samname,"_rk.txt");
if (file_in_path(".",rk_name))
Rk = load(rk_name);
endif

model_name = strcat(samname,"_model.txt");
model = load(model_name);

modelq_name = strcat(samname,"_qmodel.txt");
if (file_in_path(".",modelq_name))
modelq = load(modelq_name);
endif

pw_name = strcat(samname,"_pw.txt");
if (file_in_path(".",pw_name))
Pw = load(pw_name);
endif
pwb_name = strcat(samname,"_pwb.txt");
if (file_in_path(".",pwb_name))
Pwb = load(pwb_name);
endif

lsp_name = strcat(samname,"_lsp.txt");
if (file_in_path(".",lsp_name))
lsp = load(lsp_name);
endif

phase_name = strcat(samname,"_phase.txt");
if (file_in_path(".",phase_name))
phase = load(phase_name);
endif

phase_name_ = strcat(samname,"_phase_.txt");
if (file_in_path(".",phase_name_))
phase_ = load(phase_name_);
endif

snr_name = strcat(samname,"_snr.txt");
if (file_in_path(".",snr_name))
snr = load(snr_name);
endif

if epslatex, [textfontsize linewidth] = set_fonts(); end

k = ' ';
do
figure(1); clf;
clf;
s = [ Sn(2*f-1,:) Sn(2*f,:) ];
plot(s,'b');
axis([1 length(s) -30000 30000]);
xlabel('Time (samples)'); ylabel('Amplitude');

figure(2); clf;
Wo = model(f,1);
L = model(f,2);
Am = model(f,3:(L+2));
plot((1:L)*Wo*4000/pi, 20*log10(Am),"+-r");
axis([1 4000 -10 80]);
hold on;
if plot_sw
plot((0:255)*4000/256, Sw(f,:),"b");
end
hold off; grid minor;
ylabel ('Amplitude (dB)'); xlabel('Frequency (Hz)');

figure(3); clf;
hold on;
plot((0:255)*4000/256, Sw(f,:),"b");
plot((1:L)*Wo*4000/pi, 20*log10(Am),"+-r");
plot((0:255)*4000/256, E(f)+10*log10(Pwb(f,:)),"g");
plot(lsp(f,:)*4000/pi, 75,"g+");
hold off; grid minor;
axis([1 4000 -10 80]);
ylabel ('Amplitude (dB)'); xlabel('Frequency (Hz)');

figure(4); clf;
hold on;
plot((0:255)*4000/256, E(f)+10*log10(Pwb(f,:)),"g");
plot((0:255)*4000/256, 10*log10(Pw(f,:)),"r");
hold off; grid minor;
axis([1 4000 -10 80]);
ylabel ('Amplitude (dB)'); xlabel('Frequency (Hz)');

% print EPS file

if epslatex
sz = "-S300,200";
figure(1);
fn = sprintf("%s_%d_sn.tex",samname,f);
print(fn,"-depslatex",sz); printf("\nprinting... %s\n", fn);

% file of points to plot in sinusoidal model
fn = sprintf("%s_%d_sn.txt",samname,f);
t_length = 4; s_max = 2; s=s*s_max/max(abs(s));
N = length(s); t = (0:N-1)*t_length/N;
s_save = [t' s']; size(s_save)
save("-ascii",fn,"s_save"); printf("printing... %s\n", fn);

figure(2);
fn = sprintf("%s_%d_sw.tex",samname,f);
print(fn,"-depslatex",sz); printf("printing... %s\n", fn);

figure(3);
fn = sprintf("%s_%d_lpc_lsp.tex",samname,f);
print(fn,"-depslatex",sz); printf("printing... %s\n", fn);

figure(4);
fn = sprintf("%s_%d_lpc_pf.tex",samname,f);
print(fn,"-depslatex",sz); printf("printing... %s\n", fn);

restore_fonts(textfontsize,linewidth);
endif

% interactive menu

printf("\rframe: %d menu: n-next b-back s-plot_sw q-quit", f);
fflush(stdout);
k = kbhit();
if k == 'n'; f = f + 1; endif
if k == 'b'; f = f - 1; endif
if k == 's'
if plot_sw; plot_sw = 0; else; plot_sw = 1; end
endif

until (k == 'q')
printf("\n");

endfunction

function [textfontsize linewidth] = set_fonts(font_size=12)
textfontsize = get(0,"defaulttextfontsize");
linewidth = get(0,"defaultlinelinewidth");
set(0, "defaulttextfontsize", font_size);
set(0, "defaultaxesfontsize", font_size);
set(0, "defaultlinelinewidth", 0.5);
end

function restore_fonts(textfontsize,linewidth)
set(0, "defaulttextfontsize", textfontsize);
set(0, "defaultaxesfontsize", textfontsize);
set(0, "defaultlinelinewidth", linewidth);
end

function print_eps_restore(fn,sz,textfontsize,linewidth)
print(fn,"-depslatex",sz);
printf("printing... %s\n", fn);
restore_fonts(textfontsize,linewidth);
end

Binary file added raw/hts2a.raw
Binary file not shown.
2 changes: 1 addition & 1 deletion src/c2sim.c
Original file line number Diff line number Diff line change
Expand Up @@ -1023,7 +1023,7 @@ int main(int argc, char *argv[]) {
if (lpc_model) {
lsp_to_lpc(&lsps_dec[i][0], &ak_dec[i][0], order);
aks_to_M2(fftr_fwd_cfg, &ak_dec[i][0], order, &model_dec[i], e_dec[i],
&snr, 0, simlpcpf, lpcpf, 1, LPCPF_BETA, LPCPF_GAMMA, Aw);
&snr, 1, simlpcpf, lpcpf, 1, LPCPF_BETA, LPCPF_GAMMA, Aw);
apply_lpc_correction(&model_dec[i]);
sum_snr += snr;
#ifdef DUMP
Expand Down
1 change: 0 additions & 1 deletion src/codec2.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
#include "lpc.h"
#include "lsp.h"
#include "machdep.h"
#include "newamp2.h"
#include "nlp.h"
#include "phase.h"
#include "postfilter.h"
Expand Down
8 changes: 0 additions & 8 deletions src/codec2_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@

#include "codec2_fft.h"
#include "newamp1.h"
#include "newamp2.h"

struct CODEC2 {
int mode;
Expand Down Expand Up @@ -87,13 +86,6 @@ struct CODEC2 {
float eq[NEWAMP1_K]; /* optional equaliser */
bool eq_en;

/*newamp2 states (also uses newamp1 states )*/
float energy_prev;
float n2_rate_K_sample_freqs_kHz[NEWAMP2_K];
float n2_prev_rate_K_vec_[NEWAMP2_K];
float n2_pwb_rate_K_sample_freqs_kHz[NEWAMP2_16K_K];
float n2_pwb_prev_rate_K_vec_[NEWAMP2_16K_K];

/* used to dump features for deep learning experiments */
FILE *fmlfeat, *fmlmodel;

Expand Down
Loading
Loading