--- /dev/null
+% melstats.m
+% David Rowe April 2015
+%
+% plots some stats of mel/lsp quantisers
+
+function melstats(filename)
+
+ mel = load(filename);
+ [m n] = size(mel);
+ nbins = 10;
+
+ % histograms of each value
+
+ figure(1)
+ clf
+ subplot(211)
+ [h x] = hist(mel(:,1),nbins);
+ plot(x,h,"1");
+ hold on
+
+ for i=2:n
+ [h x] = hist(mel(:,i),nbins);
+ colour = sprintf("%d",i);
+ plot(x,h,colour);
+ end
+ hold off
+
+ % histograms differences
+
+ subplot(212)
+ [h x] = hist(mel(:,1),nbins);
+ plot(x,h,"1");
+ hold on
+
+ for i=2:n
+ [h x] = hist(mel(:,i)-mel(:,i-1),nbins);
+ colour = sprintf("%d",i);
+ plot(x,h, colour);
+ end
+ hold off
+
+ figure(2)
+ plot(mel(:,1),mel(:,2),'r+')
+ hold on;
+ plot(mel(:,3),mel(:,4),'g+')
+ plot(mel(:,5),mel(:,6),'b+')
+ hold off;
+
+endfunction
plot(s);
subplot(212)
plot(sd);
+ axis([1 frames 0 10])
lsp1_filename = sprintf("%s_lsp.txt", dump_file_prefix);
lsp2_filename = sprintf("%s_lsp_.txt", dump_file_prefix);
${D}/lspvqanssi4.txt
)
+set(CODEBOOKSMEL
+ ${D}/mel1.txt
+ ${D}/mel2.txt
+ ${D}/mel3.txt
+ ${D}/mel4.txt
+ ${D}/mel5.txt
+ ${D}/mel6.txt
+)
+
set(CODEBOOKSGE ${D}/gecb.txt)
# when crosscompiling import the executable targets from a file
DEPENDS generate_codebook ${CODEBOOKSVQANSSI}
)
+# codebookmel.c
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/codebookmel.c
+ COMMAND generate_codebook mel_cb ${CODEBOOKSMEL} > ${CMAKE_CURRENT_BINARY_DIR}/codebookmel.c
+ DEPENDS generate_codebook ${CODEBOOKSMEL}
+)
+
# codebookge.c
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/codebookge.c
codebookjvm.c
codebookvqanssi.c
codebookdt.c
+ codebookmel.c
codebookge.c
golay23.c
freedv_api.c
*/
if (lspmel) {
- float f, f_;
- int mel[LPC_ORD];
+ float f, f_, dmel;
+ float mel[LPC_ORD];
+ int mel_indexes[LPC_ORD];
- for(i=0; i<LPC_ORD; i++) {
+ for(i=0; i<order; i++) {
f = (4000.0/PI)*lsps[i];
- mel[i] = floor(100.0*log10(1.0 + f/700.0) + 0.5);
+ mel[i] = floor(2595.0*log10(1.0 + f/700.0) + 0.5);
}
- for(i=1; i<LPC_ORD; i++) {
+ for(i=1; i<order; i++) {
if (mel[i] == mel[i-1])
mel[i]++;
}
+ encode_mels_scalar(mel_indexes, mel, 6);
+ decode_mels_scalar(mel, mel_indexes, 6);
+
#ifdef DUMP
- dump_mel(mel);
+ dump_mel(mel, order);
#endif
for(i=0; i<LPC_ORD; i++) {
- f_ = 700.0*( pow(10.0, (float)mel[i]/100.0) - 1.0);
+ f_ = 700.0*( pow(10.0, (float)mel[i]/2595.0) - 1.0);
lsps_[i] = f_*(PI/4000.0);
}
- /*
- for(i=5; i<10; i++) {
- lsps_[i] = lsps[i];
- }
- */
-
- lsp_to_lpc(lsps_, ak, LPC_ORD);
+
+ lsp_to_lpc(lsps_, ak, order);
}
/* we need lsp__prev[] for lspdt and decimate. If no
--- /dev/null
+1 8
+550
+600
+650
+700
+750
+800
+850
+900
--- /dev/null
+1 4
+50
+100
+200
+300
--- /dev/null
+1 16
+800
+850
+900
+950
+1000
+1050
+1100
+1150
+1200
+1250
+1300
+1350
+1400
+1450
+1500
+1650
--- /dev/null
+1 8
+25
+50
+75
+100
+125
+150
+175
+250
--- /dev/null
+1 8
+1350
+1400
+1450
+1500
+1550
+1600
+1650
+1700
--- /dev/null
+1 4
+25
+50
+100
+150
+
extern const struct lsp_codebook lsp_cbdt[];
extern const struct lsp_codebook lsp_cbjvm[];
extern const struct lsp_codebook lsp_cbvqanssi[];
+extern const struct lsp_codebook mel_cb[];
extern const struct lsp_codebook ge_cb[];
#endif
fprintf(flsp_,"\n");
}
-void dump_mel(int mel[]) {
+void dump_mel(float mel[], int order) {
int i;
char s[MAX_STR];
assert(fmel != NULL);
}
- for(i=0; i<10; i++)
- fprintf(fmel,"%d\t",mel[i]);
+ for(i=0; i<order; i++)
+ fprintf(fmel,"%f\t",mel[i]);
fprintf(fmel,"\n");
}
void dump_lsp(float lsp[]);
void dump_weights(float w[], int ndim);
void dump_lsp_(float lsp_[]);
-void dump_mel(int mel[]);
+void dump_mel(float mel[], int order);
void dump_ak(float ak[], int order);
void dump_ak_(float ak[], int order);
void dump_E(float E);
}
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: encode_mels_scalar()
+ AUTHOR......: David Rowe
+ DATE CREATED: April 2015
+
+ Low bit rate mel coeff encoder.
+
+\*---------------------------------------------------------------------------*/
+
+void encode_mels_scalar(int indexes[], float mels[], int order)
+{
+ int i,m;
+ float wt[1];
+ const float * cb;
+ float se, mel_, dmel;
+
+ /* scalar quantisers */
+
+ wt[0] = 1.0;
+ for(i=0; i<order; i++) {
+ m = mel_cb[i].m;
+ cb = mel_cb[i].cb;
+ if (i%2) {
+ /* on odd mels quantise difference */
+ mel_ = mel_cb[i-1].cb[indexes[i-1]];
+ dmel = mels[i] - mel_;
+ indexes[i] = quantise(cb, &dmel, wt, 1, m, &se);
+ //printf("%d mel: %f mel_: %f dmel: %f index: %d\n", i, mels[i], mel_, dmel, indexes[i]);
+ }
+ else {
+ indexes[i] = quantise(cb, &mels[i], wt, 1, m, &se);
+ //printf("%d mel: %f dmel: %f index: %d\n", i, mels[i], 0.0, indexes[i]);
+ }
+
+ }
+}
+
+
+/*---------------------------------------------------------------------------*\
+
+ FUNCTION....: decode_mels_scalar()
+ AUTHOR......: David Rowe
+ DATE CREATED: April 2015
+
+ From a vector of quantised mel indexes, returns the quantised
+ (floating point) mels.
+
+\*---------------------------------------------------------------------------*/
+
+void decode_mels_scalar(float mels[], int indexes[], int order)
+{
+ int i;
+ const float * cb;
+
+ for(i=0; i<order; i++) {
+ cb = mel_cb[i].cb;
+ if (i%2) {
+ /* on odd mels quantise difference */
+ mels[i] = mels[i-1] + cb[indexes[i]];
+ }
+ else
+ mels[i] = cb[indexes[i]];
+ }
+
+}
+
+
#ifdef __EXPERIMENTAL__
/*---------------------------------------------------------------------------*\
void lspjvm_quantise(float lsps[], float lsps_[], int order);
void lspanssi_quantise(float lsps[], float lsps_[], int order, int mbest_entries);
+void encode_mels_scalar(int mel_indexes[], float mels[], int order);
+void decode_mels_scalar(float mels[], int mel_indexes[], int order);
+
void quantise_WoE(MODEL *model, float *e, float xq[]);
int encode_WoE(MODEL *model, float e, float xq[]);
void decode_WoE(MODEL *model, float *e, float xq[], int n1);