1575 lines
39 KiB
C
1575 lines
39 KiB
C
/*---------------------------------------------------------------------------*\
|
|
|
|
FILE........: phaseexp.c
|
|
AUTHOR......: David Rowe
|
|
DATE CREATED: June 2012
|
|
|
|
Experimental functions for quantising, modelling and synthesising phase.
|
|
|
|
\*---------------------------------------------------------------------------*/
|
|
|
|
/*
|
|
Copyright (C) 2012 David Rowe
|
|
|
|
All rights reserved.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License version 2.1, as
|
|
published by the Free Software Foundation. This program is
|
|
distributed in the hope that it will be useful, but WITHOUT ANY
|
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
|
License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public License
|
|
along with this program; if not,see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "defines.h"
|
|
#include "phase.h"
|
|
#include "kiss_fft.h"
|
|
#include "comp.h"
|
|
|
|
#include <assert.h>
|
|
#include <ctype.h>
|
|
#include <math.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
/* Bruce Perens' funcs to load codebook files */
|
|
|
|
struct codebook {
|
|
unsigned int k;
|
|
unsigned int log2m;
|
|
unsigned int m;
|
|
COMP *cb;
|
|
unsigned int offset;
|
|
};
|
|
|
|
static const char format[] =
|
|
"The table format must be:\n"
|
|
"\tTwo integers describing the dimensions of the codebook.\n"
|
|
"\tThen, enough numbers to fill the specified dimensions.\n";
|
|
|
|
float get_float(FILE * in, const char * name, char * * cursor, char * buffer, int size)
|
|
{
|
|
for ( ; ; ) {
|
|
char * s = *cursor;
|
|
char c;
|
|
|
|
while ( (c = *s) != '\0' && !isdigit(c) && c != '-' && c != '.' )
|
|
s++;
|
|
|
|
/* Comments start with "#" and continue to the end of the line. */
|
|
if ( c != '\0' && c != '#' ) {
|
|
char * end = 0;
|
|
float f = 0;
|
|
|
|
f = strtod(s, &end);
|
|
|
|
if ( end != s )
|
|
*cursor = end;
|
|
return f;
|
|
}
|
|
|
|
if ( fgets(buffer, size, in) == NULL ) {
|
|
fprintf(stderr, "%s: Format error. %s\n", name, format);
|
|
exit(1);
|
|
}
|
|
*cursor = buffer;
|
|
}
|
|
}
|
|
|
|
static struct codebook *load(const char * name)
|
|
{
|
|
FILE *file;
|
|
char line[2048];
|
|
char *cursor = line;
|
|
struct codebook *b = malloc(sizeof(struct codebook));
|
|
int i;
|
|
int size;
|
|
float angle;
|
|
|
|
file = fopen(name, "rt");
|
|
assert(file != NULL);
|
|
|
|
*cursor = '\0';
|
|
|
|
b->k = (int)get_float(file, name, &cursor, line, sizeof(line));
|
|
b->m = (int)get_float(file, name ,&cursor, line, sizeof(line));
|
|
size = b->k * b->m;
|
|
|
|
b->cb = (COMP *)malloc(size * sizeof(COMP));
|
|
|
|
for ( i = 0; i < size; i++ ) {
|
|
angle = get_float(file, name, &cursor, line, sizeof(line));
|
|
b->cb[i].real = cos(angle);
|
|
b->cb[i].imag = sin(angle);
|
|
}
|
|
|
|
fclose(file);
|
|
|
|
return b;
|
|
}
|
|
|
|
|
|
/* states for phase experiments */
|
|
|
|
struct PEXP {
|
|
float phi1;
|
|
float phi_prev[MAX_AMP];
|
|
float Wo_prev;
|
|
int frames;
|
|
float snr;
|
|
float var;
|
|
int var_n;
|
|
struct codebook *vq1,*vq2,*vq3,*vq4,*vq5;
|
|
float vq_var;
|
|
int vq_var_n;
|
|
MODEL prev_model;
|
|
int state;
|
|
};
|
|
|
|
|
|
/*---------------------------------------------------------------------------* \
|
|
|
|
phase_experiment_create()
|
|
|
|
Inits states for phase quantisation experiments.
|
|
|
|
\*---------------------------------------------------------------------------*/
|
|
|
|
struct PEXP * phase_experiment_create() {
|
|
struct PEXP *pexp;
|
|
int i;
|
|
|
|
pexp = (struct PEXP *)malloc(sizeof(struct PEXP));
|
|
assert (pexp != NULL);
|
|
|
|
pexp->phi1 = 0;
|
|
for(i=0; i<MAX_AMP; i++)
|
|
pexp->phi_prev[i] = 0.0;
|
|
pexp->Wo_prev = 0.0;
|
|
pexp->frames = 0;
|
|
pexp->snr = 0.0;
|
|
pexp->var = 0.0;
|
|
pexp->var_n = 0;
|
|
|
|
/* smoothed 10th order for 1st 1 khz */
|
|
//pexp->vq1 = load("../unittest/ph1_10_1024.txt");
|
|
//pexp->vq1->offset = 0;
|
|
|
|
/* load experimental phase VQ */
|
|
|
|
//pexp->vq1 = load("../unittest/testn1_20_1024.txt");
|
|
pexp->vq1 = load("../unittest/test.txt");
|
|
//pexp->vq2 = load("../unittest/testn21_40_1024.txt");
|
|
pexp->vq2 = load("../unittest/test11_20_1024.txt");
|
|
pexp->vq3 = load("../unittest/test21_30_1024.txt");
|
|
pexp->vq4 = load("../unittest/test31_40_1024.txt");
|
|
pexp->vq5 = load("../unittest/test41_60_1024.txt");
|
|
pexp->vq1->offset = 0;
|
|
pexp->vq2->offset = 10;
|
|
pexp->vq3->offset = 20;
|
|
pexp->vq4->offset = 30;
|
|
pexp->vq5->offset = 40;
|
|
|
|
pexp->vq_var = 0.0;
|
|
pexp->vq_var_n = 0;
|
|
|
|
pexp->state = 0;
|
|
|
|
return pexp;
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------* \
|
|
|
|
phase_experiment_destroy()
|
|
|
|
\*---------------------------------------------------------------------------*/
|
|
|
|
void phase_experiment_destroy(struct PEXP *pexp) {
|
|
assert(pexp != NULL);
|
|
if (pexp->snr != 0.0)
|
|
printf("snr: %4.2f dB\n", pexp->snr/pexp->frames);
|
|
if (pexp->var != 0.0)
|
|
printf("var...: %4.3f std dev...: %4.3f (%d non zero phases)\n",
|
|
pexp->var/pexp->var_n, sqrt(pexp->var/pexp->var_n), pexp->var_n);
|
|
if (pexp->vq_var != 0.0)
|
|
printf("vq var: %4.3f vq std dev: %4.3f (%d non zero phases)\n",
|
|
pexp->vq_var/pexp->vq_var_n, sqrt(pexp->vq_var/pexp->vq_var_n), pexp->vq_var_n);
|
|
free(pexp);
|
|
}
|
|
|
|
|
|
/*---------------------------------------------------------------------------* \
|
|
|
|
Various test and experimental functions ................
|
|
|
|
\*---------------------------------------------------------------------------*/
|
|
|
|
/* Bubblesort to find highest amplitude harmonics */
|
|
|
|
struct AMPINDEX {
|
|
float amp;
|
|
int index;
|
|
};
|
|
|
|
static void bubbleSort(struct AMPINDEX numbers[], int array_size)
|
|
{
|
|
int i, j;
|
|
struct AMPINDEX temp;
|
|
|
|
for (i = (array_size - 1); i > 0; i--)
|
|
{
|
|
for (j = 1; j <= i; j++)
|
|
{
|
|
//printf("i %d j %d %f %f \n", i, j, numbers[j-1].amp, numbers[j].amp);
|
|
if (numbers[j-1].amp < numbers[j].amp)
|
|
{
|
|
temp = numbers[j-1];
|
|
numbers[j-1] = numbers[j];
|
|
numbers[j] = temp;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void print_pred_error(struct PEXP *pexp, MODEL *model, int start, int end, float mag_thresh) {
|
|
int i;
|
|
float mag;
|
|
|
|
mag = 0.0;
|
|
for(i=start; i<=end; i++)
|
|
mag += model->A[i]*model->A[i];
|
|
mag = 10*log10(mag/(end-start));
|
|
|
|
if (mag > mag_thresh) {
|
|
for(i=start; i<=end; i++) {
|
|
float pred = pexp->phi_prev[i] + N*i*(model->Wo + pexp->Wo_prev)/2.0;
|
|
float err = pred - model->phi[i];
|
|
err = atan2(sin(err),cos(err));
|
|
printf("%f\n",err);
|
|
}
|
|
//printf("\n");
|
|
}
|
|
|
|
}
|
|
|
|
|
|
static void predict_phases(struct PEXP *pexp, MODEL *model, int start, int end) {
|
|
int i;
|
|
|
|
for(i=start; i<=end; i++) {
|
|
model->phi[i] = pexp->phi_prev[i] + N*i*model->Wo;
|
|
}
|
|
|
|
}
|
|
static float refine_Wo(struct PEXP *pexp,
|
|
MODEL *model,
|
|
int start,
|
|
int end);
|
|
|
|
/* Fancy state based phase prediction. Actually works OK on most utterances,
|
|
but could use some tuning. Breaks down a bit on mmt1. */
|
|
|
|
static void predict_phases_state(struct PEXP *pexp, MODEL *model, int start, int end) {
|
|
int i, next_state;
|
|
float best_Wo, dWo;
|
|
|
|
//best_Wo = refine_Wo(pexp, model, start, end);
|
|
//best_Wo = (model->Wo + pexp->Wo_prev)/2.0;
|
|
best_Wo = model->Wo;
|
|
|
|
dWo = fabs(model->Wo - pexp->Wo_prev)/model->Wo;
|
|
next_state = pexp->state;
|
|
switch(pexp->state) {
|
|
case 0:
|
|
if (dWo < 0.1) {
|
|
/* UV -> V transition, so start with phases in lock. They will
|
|
drift a bit over voiced track which is kinda what we want, so
|
|
we don't get clicky speech.
|
|
*/
|
|
next_state = 1;
|
|
for(i=start; i<=end; i++)
|
|
pexp->phi_prev[i] = i*pexp->phi1;
|
|
}
|
|
|
|
break;
|
|
case 1:
|
|
if (dWo > 0.1)
|
|
next_state = 0;
|
|
break;
|
|
}
|
|
pexp->state = next_state;
|
|
|
|
if (pexp->state == 0)
|
|
for(i=start; i<=end; i++) {
|
|
model->phi[i] = PI*(1.0 - 2.0*rand()/RAND_MAX);
|
|
}
|
|
else
|
|
for(i=start; i<=end; i++) {
|
|
model->phi[i] = pexp->phi_prev[i] + N*i*best_Wo;
|
|
}
|
|
printf("state %d\n", pexp->state);
|
|
}
|
|
|
|
static void struct_phases(struct PEXP *pexp, MODEL *model, int start, int end) {
|
|
int i;
|
|
|
|
for(i=start; i<=end; i++)
|
|
model->phi[i] = pexp->phi1*i;
|
|
|
|
}
|
|
|
|
|
|
static void predict_phases2(struct PEXP *pexp, MODEL *model, int start, int end) {
|
|
int i;
|
|
float pred, str, diff;
|
|
|
|
for(i=start; i<=end; i++) {
|
|
pred = pexp->phi_prev[i] + N*i*model->Wo;
|
|
str = pexp->phi1*i;
|
|
diff = str - pred;
|
|
diff = atan2(sin(diff), cos(diff));
|
|
if (diff > 0)
|
|
pred += PI/16;
|
|
else
|
|
pred -= PI/16;
|
|
model->phi[i] = pred;
|
|
}
|
|
|
|
}
|
|
|
|
static void skip_phases(struct PEXP *pexp, MODEL *model, int start, int end) {
|
|
int i;
|
|
|
|
for(i=start; i<=end; i+=2)
|
|
model->phi[i] = model->phi[i-1] - model->phi[i-2];
|
|
|
|
}
|
|
|
|
static void rand_phases(MODEL *model, int start, int end) {
|
|
int i;
|
|
|
|
for(i=start; i<=end; i++)
|
|
model->phi[i] = PI*(1.0 - 2.0*(float)rand()/RAND_MAX);
|
|
|
|
}
|
|
|
|
static void quant_phase(float *phase, float min, float max, int bits) {
|
|
int levels = 1 << bits;
|
|
int index;
|
|
float norm, step;
|
|
|
|
norm = (*phase - min)/(max - min);
|
|
index = floor(levels*norm);
|
|
|
|
//printf("phase %f norm %f index %d ", *phase, norm, index);
|
|
if (index < 0 ) index = 0;
|
|
if (index > (levels-1)) index = levels-1;
|
|
//printf("index %d ", index);
|
|
step = (max - min)/levels;
|
|
*phase = min + step*index + 0.5*step;
|
|
//printf("step %f phase %f\n", step, *phase);
|
|
}
|
|
|
|
static void quant_phases(MODEL *model, int start, int end, int bits) {
|
|
int i;
|
|
|
|
for(i=start; i<=end; i++) {
|
|
quant_phase(&model->phi[i], -PI, PI, bits);
|
|
}
|
|
}
|
|
|
|
static void fixed_bits_per_frame(struct PEXP *pexp, MODEL *model, int m, int budget) {
|
|
int res, finished;
|
|
|
|
res = 3;
|
|
finished = 0;
|
|
|
|
while(!finished) {
|
|
if (m > model->L/2)
|
|
res = 2;
|
|
if (((budget - res) < 0) || (m > model->L))
|
|
finished = 1;
|
|
else {
|
|
quant_phase(&model->phi[m], -PI, PI, res);
|
|
budget -= res;
|
|
m++;
|
|
}
|
|
}
|
|
printf("m: %d L: %d budget: %d\n", m, model->L, budget);
|
|
predict_phases(pexp, model, m, model->L);
|
|
//rand_phases(model, m, model->L);
|
|
}
|
|
|
|
/* used to plot histogram of quantisation error, for 3 bits, 8 levels,
|
|
should be uniform between +/- PI/8 */
|
|
|
|
static void check_phase_quant(MODEL *model, float tol)
|
|
{
|
|
int m;
|
|
float phi_before[MAX_AMP];
|
|
|
|
for(m=1; m<=model->L; m++)
|
|
phi_before[m] = model->phi[m];
|
|
|
|
quant_phases(model, 1, model->L, 3);
|
|
|
|
for(m=1; m<=model->L; m++) {
|
|
float err = phi_before[m] - model->phi[m];
|
|
printf("%f\n", err);
|
|
if (fabs(err) > tol)
|
|
exit(0);
|
|
}
|
|
}
|
|
|
|
|
|
static float est_phi1(MODEL *model, int start, int end)
|
|
{
|
|
int m;
|
|
float delta, s, c, phi1_est;
|
|
|
|
if (end > model->L)
|
|
end = model->L;
|
|
|
|
s = c = 0.0;
|
|
for(m=start; m<end; m++) {
|
|
delta = model->phi[m+1] - model->phi[m];
|
|
s += sin(delta);
|
|
c += cos(delta);
|
|
}
|
|
|
|
phi1_est = atan2(s,c);
|
|
|
|
return phi1_est;
|
|
}
|
|
|
|
static void print_phi1_pred_error(MODEL *model, int start, int end)
|
|
{
|
|
int m;
|
|
float phi1_est;
|
|
|
|
phi1_est = est_phi1(model, start, end);
|
|
|
|
for(m=start; m<end; m++) {
|
|
float err = model->phi[m+1] - model->phi[m] - phi1_est;
|
|
err = atan2(sin(err),cos(err));
|
|
printf("%f\n", err);
|
|
}
|
|
}
|
|
|
|
|
|
static void first_order_band(MODEL *model, int start, int end, float phi1_est)
|
|
{
|
|
int m;
|
|
float pred_err, av_pred_err;
|
|
float c,s;
|
|
|
|
s = c = 0.0;
|
|
for(m=start; m<end; m++) {
|
|
pred_err = model->phi[m] - phi1_est*m;
|
|
s += sin(pred_err);
|
|
c += cos(pred_err);
|
|
}
|
|
|
|
av_pred_err = atan2(s,c);
|
|
for(m=start; m<end; m++) {
|
|
model->phi[m] = av_pred_err + phi1_est*m;
|
|
model->phi[m] = atan2(sin(model->phi[m]), cos(model->phi[m]));
|
|
}
|
|
|
|
}
|
|
|
|
|
|
static void sub_linear(MODEL *model, int start, int end, float phi1_est)
|
|
{
|
|
int m;
|
|
|
|
for(m=start; m<end; m++) {
|
|
model->phi[m] = m*phi1_est;
|
|
}
|
|
}
|
|
|
|
|
|
static void top_amp(struct PEXP *pexp, MODEL *model, int start, int end, int n_harm, int pred)
|
|
{
|
|
int removed = 0, not_removed = 0;
|
|
int top, i, j;
|
|
struct AMPINDEX sorted[MAX_AMP];
|
|
|
|
/* sort into ascending order of amplitude */
|
|
|
|
printf("\n");
|
|
for(i=start,j=0; i<end; i++,j++) {
|
|
sorted[j].amp = model->A[i];
|
|
sorted[j].index = i;
|
|
printf("%f ", model->A[i]);
|
|
}
|
|
bubbleSort(sorted, end-start);
|
|
|
|
printf("\n");
|
|
for(j=0; j<n_harm; j++)
|
|
printf("%d %f\n", j, sorted[j].amp);
|
|
|
|
/* keep phase of top n_harm, predict others */
|
|
|
|
for(i=start; i<end; i++) {
|
|
top = 0;
|
|
for(j=0; j<n_harm; j++) {
|
|
if (model->A[i] == sorted[j].amp) {
|
|
top = 1;
|
|
assert(i == sorted[j].index);
|
|
}
|
|
}
|
|
|
|
#define ALTTOP
|
|
#ifdef ALTTOP
|
|
model->phi[i] = 0.0; /* make sure */
|
|
if (top) {
|
|
model->phi[i] = i*pexp->phi1;
|
|
removed++;
|
|
}
|
|
else {
|
|
model->phi[i] = PI*(1.0 - 2.0*(float)rand()/RAND_MAX); // note: try rand for higher harms
|
|
removed++;
|
|
}
|
|
#else
|
|
if (!top) {
|
|
model->phi[i] = 0.0; /* make sure */
|
|
if (pred) {
|
|
//model->phi[i] = pexp->phi_prev[i] + i*N*(model->Wo + pexp->Wo_prev)/2.0;
|
|
model->phi[i] = i*model->phi[1];
|
|
}
|
|
else
|
|
model->phi[i] = PI*(1.0 - 2.0*(float)rand()/RAND_MAX); // note: try rand for higher harms
|
|
removed++;
|
|
}
|
|
else {
|
|
/* need to make this work thru budget of bits */
|
|
quant_phase(&model->phi[i], -PI, PI, 3);
|
|
not_removed++;
|
|
}
|
|
#endif
|
|
}
|
|
printf("dim: %d rem %d not_rem %d\n", end-start, removed, not_removed);
|
|
|
|
}
|
|
|
|
|
|
static void limit_prediction_error(struct PEXP *pexp, MODEL *model, int start, int end, float limit)
|
|
{
|
|
int i;
|
|
float pred, pred_error, error;
|
|
|
|
for(i=start; i<=end; i++) {
|
|
pred = pexp->phi_prev[i] + N*i*(model->Wo + pexp->Wo_prev)/2.0;
|
|
pred_error = pred - model->phi[i];
|
|
pred_error -= TWO_PI*floor((pred_error+PI)/TWO_PI);
|
|
quant_phase(&pred_error, -limit, limit, 2);
|
|
|
|
error = pred - pred_error - model->phi[i];
|
|
error -= TWO_PI*floor((error+PI)/TWO_PI);
|
|
printf("%f\n", pred_error);
|
|
model->phi[i] = pred - pred_error;
|
|
}
|
|
}
|
|
|
|
|
|
static void quant_prediction_error(struct PEXP *pexp, MODEL *model, int start, int end, float limit)
|
|
{
|
|
int i;
|
|
float pred, pred_error;
|
|
|
|
for(i=start; i<=end; i++) {
|
|
pred = pexp->phi_prev[i] + N*i*(model->Wo + pexp->Wo_prev)/2.0;
|
|
pred_error = pred - model->phi[i];
|
|
pred_error -= TWO_PI*floor((pred_error+PI)/TWO_PI);
|
|
|
|
printf("%f\n", pred_error);
|
|
model->phi[i] = pred - pred_error;
|
|
}
|
|
}
|
|
|
|
|
|
static void print_sparse_pred_error(struct PEXP *pexp, MODEL *model, int start, int end, float mag_thresh)
|
|
{
|
|
int i, index;
|
|
float mag, pred, error;
|
|
float sparse_pe[MAX_AMP];
|
|
|
|
mag = 0.0;
|
|
for(i=start; i<=end; i++)
|
|
mag += model->A[i]*model->A[i];
|
|
mag = 10*log10(mag/(end-start));
|
|
|
|
if (mag > mag_thresh) {
|
|
for(i=0; i<MAX_AMP; i++) {
|
|
sparse_pe[i] = 0.0;
|
|
}
|
|
|
|
for(i=start; i<=end; i++) {
|
|
pred = pexp->phi_prev[i] + N*i*(model->Wo + pexp->Wo_prev)/2.0;
|
|
error = pred - model->phi[i];
|
|
error = atan2(sin(error),cos(error));
|
|
|
|
index = MAX_AMP*i*model->Wo/PI;
|
|
assert(index < MAX_AMP);
|
|
sparse_pe[index] = error;
|
|
}
|
|
|
|
/* dump spare phase vector in polar format */
|
|
|
|
for(i=0; i<MAX_AMP; i++)
|
|
printf("%f ", sparse_pe[i]);
|
|
printf("\n");
|
|
}
|
|
}
|
|
|
|
|
|
static void update_snr_calc(struct PEXP *pexp, MODEL *model, float before[])
|
|
{
|
|
int m;
|
|
float signal, noise, diff;
|
|
|
|
signal = 0.0; noise = 0.0;
|
|
for(m=1; m<=model->L; m++) {
|
|
signal += model->A[m]*model->A[m];
|
|
diff = cos(model->phi[m]) - cos(before[m]);
|
|
noise += pow(model->A[m]*diff, 2.0);
|
|
diff = sin(model->phi[m]) - sin(before[m]);
|
|
noise += pow(model->A[m]*diff, 2.0);
|
|
//printf("%f %f\n", before[m], model->phi[m]);
|
|
}
|
|
//printf("%f %f snr = %f\n", signal, noise, 10.0*log10(signal/noise));
|
|
pexp->snr += 10.0*log10(signal/noise);
|
|
}
|
|
|
|
|
|
static void update_variance_calc(struct PEXP *pexp, MODEL *model, float before[])
|
|
{
|
|
int m;
|
|
float diff;
|
|
|
|
for(m=1; m<model->L; m++) {
|
|
diff = model->phi[m] - before[m];
|
|
diff = atan2(sin(diff), cos(diff));
|
|
pexp->var += diff*diff;
|
|
}
|
|
pexp->var_n += model->L;
|
|
}
|
|
|
|
void print_vec(COMP cb[], int d, int e)
|
|
{
|
|
int i,j;
|
|
|
|
for(j=0; j<e; j++) {
|
|
for(i=0; i<d; i++)
|
|
printf("%f %f ", cb[j*d+i].real, cb[j*d+i].imag);
|
|
printf("\n");
|
|
}
|
|
}
|
|
|
|
static COMP cconj(COMP a)
|
|
{
|
|
COMP res;
|
|
|
|
res.real = a.real;
|
|
res.imag = -a.imag;
|
|
|
|
return res;
|
|
}
|
|
|
|
static COMP cadd(COMP a, COMP b)
|
|
{
|
|
COMP res;
|
|
|
|
res.real = a.real + b.real;
|
|
res.imag = a.imag + b.imag;
|
|
|
|
return res;
|
|
}
|
|
|
|
static COMP cmult(COMP a, COMP b)
|
|
{
|
|
COMP res;
|
|
|
|
res.real = a.real*b.real - a.imag*b.imag;
|
|
res.imag = a.real*b.imag + a.imag*b.real;
|
|
|
|
return res;
|
|
}
|
|
|
|
static int vq_phase(COMP cb[], COMP vec[], float weights[], int d, int e, float *se)
|
|
{
|
|
float error; /* current error */
|
|
int besti; /* best index so far */
|
|
float best_error; /* best error so far */
|
|
int i,j;
|
|
int ignore;
|
|
COMP diffr;
|
|
float diffp, metric, best_metric;
|
|
|
|
besti = 0;
|
|
best_metric = best_error = 1E32;
|
|
for(j=0; j<e; j++) {
|
|
error = 0.0;
|
|
metric = 0.0;
|
|
for(i=0; i<d; i++) {
|
|
ignore = (vec[i].real == 0.0) && (vec[i].imag == 0.0);
|
|
if (!ignore) {
|
|
diffr = cmult(cb[j*d+i], cconj(vec[i]));
|
|
diffp = atan2(diffr.imag, diffr.real);
|
|
error += diffp*diffp;
|
|
metric += weights[i]*weights[i]*diffp*diffp;
|
|
//metric += weights[i]*diffp*diffp;
|
|
//metric = log10(weights[i]*fabs(diffp));
|
|
//printf("diffp %f metric %f\n", diffp, metric);
|
|
//if (metric < log10(PI/(8.0*sqrt(3.0))))
|
|
// metric = log10(PI/(8.0*sqrt(3.0)));
|
|
}
|
|
}
|
|
if (metric < best_metric) {
|
|
best_metric = metric;
|
|
best_error = error;
|
|
besti = j;
|
|
}
|
|
}
|
|
|
|
*se += best_error;
|
|
|
|
return(besti);
|
|
}
|
|
|
|
|
|
static float refine_Wo(struct PEXP *pexp,
|
|
MODEL *model,
|
|
int start,
|
|
int end)
|
|
|
|
{
|
|
int i;
|
|
float Wo_est, best_var, Wo, var, pred, error, best_Wo;
|
|
|
|
/* test variance over a range of Wo values */
|
|
|
|
Wo_est = (model->Wo + pexp->Wo_prev)/2.0;
|
|
best_var = 1E32;
|
|
for(Wo=0.97*Wo_est; Wo<=1.03*Wo_est; Wo+=0.001*Wo_est) {
|
|
|
|
/* predict phase and sum differences between harmonics */
|
|
|
|
var = 0.0;
|
|
for(i=start; i<=end; i++) {
|
|
pred = pexp->phi_prev[i] + N*i*Wo;
|
|
error = pred - model->phi[i];
|
|
error = atan2(sin(error),cos(error));
|
|
var += error*error;
|
|
}
|
|
|
|
if (var < best_var) {
|
|
best_var = var;
|
|
best_Wo = Wo;
|
|
}
|
|
}
|
|
|
|
return best_Wo;
|
|
}
|
|
|
|
|
|
static void split_vq(COMP sparse_pe_out[], struct PEXP *pexp, struct codebook *vq, float weights[], COMP sparse_pe_in[])
|
|
{
|
|
int i, j, non_zero, vq_ind;
|
|
|
|
//printf("\n offset %d k %d m %d j: ", vq->offset, vq->k, vq->m);
|
|
vq_ind = vq_phase(vq->cb, &sparse_pe_in[vq->offset], &weights[vq->offset], vq->k, vq->m, &pexp->vq_var);
|
|
|
|
non_zero = 0;
|
|
for(i=0, j=vq->offset; i<vq->k; i++,j++) {
|
|
//printf("%f ", atan2(sparse_pe[i].imag, sparse_pe[i].real));
|
|
if ((sparse_pe_in[j].real != 0.0) && (sparse_pe_in[j].imag != 0.0)) {
|
|
//printf("%d ", j);
|
|
sparse_pe_out[j] = vq->cb[vq->k * vq_ind + i];
|
|
non_zero++;
|
|
}
|
|
}
|
|
pexp->vq_var_n += non_zero;
|
|
}
|
|
|
|
|
|
static void sparse_vq_pred_error(struct PEXP *pexp,
|
|
MODEL *model
|
|
)
|
|
{
|
|
int i, index;
|
|
float pred, error, error_q_angle, best_Wo;
|
|
COMP sparse_pe_in[MAX_AMP], sparse_pe_out[MAX_AMP];
|
|
float weights[MAX_AMP];
|
|
COMP error_q_rect;
|
|
|
|
best_Wo = refine_Wo(pexp, model, 1, model->L);
|
|
//best_Wo = (model->Wo + pexp->Wo_prev)/2.0;
|
|
|
|
/* transform to sparse pred error vector */
|
|
|
|
for(i=0; i<MAX_AMP; i++) {
|
|
sparse_pe_in[i].real = 0.0;
|
|
sparse_pe_in[i].imag = 0.0;
|
|
sparse_pe_out[i].real = 0.0;
|
|
sparse_pe_out[i].imag = 0.0;
|
|
}
|
|
|
|
//printf("\n");
|
|
for(i=1; i<=model->L; i++) {
|
|
pred = pexp->phi_prev[i] + N*i*best_Wo;
|
|
error = pred - model->phi[i];
|
|
|
|
index = MAX_AMP*i*model->Wo/PI;
|
|
assert(index < MAX_AMP);
|
|
sparse_pe_in[index].real = cos(error);
|
|
sparse_pe_in[index].imag = sin(error);
|
|
sparse_pe_out[index] = sparse_pe_in[index];
|
|
weights[index] = model->A[i];
|
|
//printf("%d ", index);
|
|
}
|
|
|
|
/* vector quantise */
|
|
|
|
split_vq(sparse_pe_out, pexp, pexp->vq1, weights, sparse_pe_in);
|
|
split_vq(sparse_pe_out, pexp, pexp->vq2, weights, sparse_pe_in);
|
|
split_vq(sparse_pe_out, pexp, pexp->vq3, weights, sparse_pe_in);
|
|
split_vq(sparse_pe_out, pexp, pexp->vq4, weights, sparse_pe_in);
|
|
split_vq(sparse_pe_out, pexp, pexp->vq5, weights, sparse_pe_in);
|
|
|
|
/* transform quantised phases back */
|
|
|
|
for(i=1; i<=model->L; i++) {
|
|
pred = pexp->phi_prev[i] + N*i*best_Wo;
|
|
|
|
index = MAX_AMP*i*model->Wo/PI;
|
|
assert(index < MAX_AMP);
|
|
error_q_rect = sparse_pe_out[index];
|
|
error_q_angle = atan2(error_q_rect.imag, error_q_rect.real);
|
|
model->phi[i] = pred - error_q_angle;
|
|
model->phi[i] = atan2(sin(model->phi[i]), cos(model->phi[i]));
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
est delta (in Wo)
|
|
see if this gives us a better (smaller variance) prediction error
|
|
*/
|
|
|
|
static void print_pred_error_sparse_wo_correction(struct PEXP *pexp,
|
|
MODEL *model,
|
|
int start, int end,
|
|
float mag_thresh)
|
|
{
|
|
int i, index;
|
|
float mag, pred, error[MAX_AMP], diff, c, s, delta, err;
|
|
float sparse_pe[MAX_AMP];
|
|
|
|
mag = 0.0;
|
|
for(i=start; i<=end; i++)
|
|
mag += model->A[i]*model->A[i];
|
|
mag = 10*log10(mag/(end-start));
|
|
|
|
if (mag > mag_thresh) {
|
|
for(i=0; i<MAX_AMP; i++) {
|
|
sparse_pe[i] = 0.0;
|
|
}
|
|
|
|
/* predict phase and sum differences between harmonics */
|
|
|
|
for(i=start; i<=end; i++) {
|
|
//model->phi[i] = pexp->phi_prev[i] + N*i*(model->Wo + pexp->Wo_prev)/2.0 + 0.01*N*i;
|
|
pred = pexp->phi_prev[i] + N*i*(model->Wo + pexp->Wo_prev)/2.0;
|
|
error[i] = pred - model->phi[i];
|
|
}
|
|
|
|
/* estimate delta Wo */
|
|
|
|
c = s = 0.0;
|
|
for(i=start+1; i<=end; i++) {
|
|
diff = error[i] - error[i-1];
|
|
c += log(model->A[i])*cos(diff);
|
|
s += log(model->A[i])*sin(diff);
|
|
}
|
|
delta = atan2(s,c)/N;
|
|
//printf("delta %f\n",delta);
|
|
delta = 0;
|
|
/* now predict phases using corrected Wo */
|
|
|
|
for(i=start; i<=end; i++) {
|
|
pred = pexp->phi_prev[i] + N*i*(model->Wo + pexp->Wo_prev)/2.0 - N*i*delta;
|
|
err = pred - model->phi[i];
|
|
err = atan2(sin(err),cos(err));
|
|
|
|
index = MAX_AMP*i*model->Wo/PI;
|
|
assert(index < MAX_AMP);
|
|
sparse_pe[index] = err;
|
|
}
|
|
|
|
/* dump spare phase vector in polar format */
|
|
|
|
for(i=0; i<MAX_AMP; i++)
|
|
printf("%f ", sparse_pe[i]);
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
static void print_pred_error_sparse_wo_correction1(struct PEXP *pexp,
|
|
MODEL *model,
|
|
int start, int end,
|
|
float mag_thresh)
|
|
{
|
|
int i, index;
|
|
float mag, pred, best_Wo, err;
|
|
float sparse_pe[MAX_AMP];
|
|
|
|
mag = 0.0;
|
|
for(i=start; i<=end; i++)
|
|
mag += model->A[i]*model->A[i];
|
|
mag = 10*log10(mag/(end-start));
|
|
|
|
if (mag > mag_thresh) {
|
|
|
|
best_Wo = refine_Wo(pexp, model, start, end);
|
|
|
|
/* now predict phases using corrected Wo */
|
|
|
|
for(i=0; i<MAX_AMP; i++) {
|
|
sparse_pe[i] = 0.0;
|
|
}
|
|
|
|
for(i=start; i<=end; i++) {
|
|
pred = pexp->phi_prev[i] + N*i*best_Wo;
|
|
err = pred - model->phi[i];
|
|
err = atan2(sin(err),cos(err));
|
|
|
|
index = MAX_AMP*i*model->Wo/PI;
|
|
assert(index < MAX_AMP);
|
|
sparse_pe[index] = err;
|
|
}
|
|
|
|
/* dump spare phase vector in polar format */
|
|
|
|
for(i=0; i<MAX_AMP; i++)
|
|
printf("%f ", sparse_pe[i]);
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
static void predict_phases1(struct PEXP *pexp, MODEL *model, int start, int end) {
|
|
int i;
|
|
float best_Wo;
|
|
|
|
best_Wo = refine_Wo(pexp, model, 1, model->L);
|
|
|
|
for(i=start; i<=end; i++) {
|
|
model->phi[i] = pexp->phi_prev[i] + N*i*best_Wo;
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
This functions tests theory that some bands can be combined together
|
|
due to less frequency resolution at higher frequencies. This will
|
|
reduce the amount of information we need to encode.
|
|
*/
|
|
|
|
void smooth_phase(struct PEXP *pexp, MODEL *model, int mode)
|
|
{
|
|
int m, i, j, index, step, v, en, nav, st;
|
|
COMP sparse_pe_in[MAX_AMP], av;
|
|
COMP sparse_pe_out[MAX_AMP];
|
|
COMP smoothed[MAX_AMP];
|
|
float best_Wo, pred, err;
|
|
float weights[MAX_AMP];
|
|
float avw, smoothed_weights[MAX_AMP];
|
|
COMP smoothed_in[MAX_AMP], smoothed_out[MAX_AMP];
|
|
|
|
best_Wo = refine_Wo(pexp, model, 1, model->L);
|
|
|
|
for(m=0; m<MAX_AMP; m++) {
|
|
sparse_pe_in[m].real = sparse_pe_in[m].imag = 0.0;
|
|
sparse_pe_out[m].real = sparse_pe_out[m].imag = 0.0;
|
|
}
|
|
|
|
/* set up sparse array */
|
|
|
|
for(m=1; m<=model->L; m++) {
|
|
pred = pexp->phi_prev[m] + N*m*best_Wo;
|
|
err = model->phi[m] - pred;
|
|
err = atan2(sin(err),cos(err));
|
|
|
|
index = MAX_AMP*m*model->Wo/PI;
|
|
assert(index < MAX_AMP);
|
|
sparse_pe_in[index].real = model->A[m]*cos(err);
|
|
sparse_pe_in[index].imag = model->A[m]*sin(err);
|
|
sparse_pe_out[index] = sparse_pe_in[index];
|
|
weights[index] = model->A[m];
|
|
}
|
|
|
|
/* now combine samples at high frequencies to reduce dimension */
|
|
|
|
step = 2;
|
|
st = 0;
|
|
for(i=st,v=0; i<MAX_AMP; i+=step,v++) {
|
|
|
|
/* average over one band */
|
|
|
|
av.real = 0.0; av.imag = 0.0; avw = 0.0; nav = 0;
|
|
en = i+step;
|
|
if (en > (MAX_AMP-1))
|
|
en = MAX_AMP-1;
|
|
for(j=i; j<en; j++) {
|
|
if ((sparse_pe_in[j].real != 0.0) &&(sparse_pe_in[j].imag != 0.0) ) {
|
|
av = cadd(av, sparse_pe_in[j]);
|
|
avw += weights[j];
|
|
nav++;
|
|
}
|
|
}
|
|
if (nav) {
|
|
smoothed[v] = av;
|
|
smoothed_weights[v] = avw/nav;
|
|
}
|
|
else
|
|
smoothed[v].real = smoothed[v].imag = 0.0;
|
|
}
|
|
|
|
if (mode == 2) {
|
|
for(i=0; i<MAX_AMP; i++) {
|
|
smoothed_in[i] = smoothed[i];
|
|
smoothed_out[i] = smoothed_in[i];
|
|
}
|
|
split_vq(smoothed_out, pexp, pexp->vq1, smoothed_weights, smoothed_in);
|
|
for(i=0; i<MAX_AMP; i++)
|
|
smoothed[i] = smoothed_out[i];
|
|
}
|
|
|
|
/* set all samples to smoothed average */
|
|
|
|
for(i=st,v=0; i<MAX_AMP; i+=step,v++) {
|
|
en = i+step;
|
|
if (en > (MAX_AMP-1))
|
|
en = MAX_AMP-1;
|
|
for(j=i; j<en; j++)
|
|
sparse_pe_out[j] = smoothed[v];
|
|
if (mode == 1)
|
|
printf("%f ", atan2(smoothed[v].imag, smoothed[v].real));
|
|
}
|
|
if (mode == 1)
|
|
printf("\n");
|
|
|
|
/* convert back to Am */
|
|
|
|
for(m=1; m<=model->L; m++) {
|
|
index = MAX_AMP*m*model->Wo/PI;
|
|
assert(index < MAX_AMP);
|
|
pred = pexp->phi_prev[m] + N*m*best_Wo;
|
|
err = atan2(sparse_pe_out[index].imag, sparse_pe_out[index].real);
|
|
model->phi[m] = pred + err;
|
|
}
|
|
|
|
}
|
|
|
|
/*
|
|
Another version of a functions that tests the theory that some bands
|
|
can be combined together due to less frequency resolution at higher
|
|
frequencies. This will reduce the amount of information we need to
|
|
encode.
|
|
*/
|
|
|
|
void smooth_phase2(struct PEXP *pexp, MODEL *model) {
|
|
float m;
|
|
float step;
|
|
int a,b,h,i;
|
|
float best_Wo, pred, err, s,c, phi1_;
|
|
|
|
best_Wo = refine_Wo(pexp, model, 1, model->L);
|
|
|
|
step = (float)model->L/30;
|
|
printf("\nL: %d step: %3.2f am,bm: ", model->L, step);
|
|
for(m=(float)model->L/4; m<=model->L; m+=step) {
|
|
a = floor(m);
|
|
b = floor(m+step);
|
|
if (b > model->L) b = model->L;
|
|
h = b-a;
|
|
|
|
printf("%d,%d,(%d) ", a, b, h);
|
|
c = s = 0.0;
|
|
if (h>1) {
|
|
for(i=a; i<b; i++) {
|
|
pred = pexp->phi_prev[i] + N*i*best_Wo;
|
|
err = model->phi[i] - pred;
|
|
c += cos(err); s += sin(err);
|
|
}
|
|
phi1_ = atan2(s,c);
|
|
for(i=a; i<b; i++) {
|
|
pred = pexp->phi_prev[i] + N*i*best_Wo;
|
|
printf("%d: %4.3f -> ", i, model->phi[i]);
|
|
model->phi[i] = pred + phi1_;
|
|
model->phi[i] = atan2(sin(model->phi[i]),cos(model->phi[i]));
|
|
printf("%4.3f ", model->phi[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
#define MAX_BINS 40
|
|
//static float bins[] = {2600.0, 2800.0, 3000.0, 3200.0, 3400.0, 3600.0, 3800.0, 4000.0};
|
|
static float bins[] = {/*
|
|
|
|
1000.0, 1100.0, 1200.0, 1300.0, 1400.0,
|
|
1500.0, 1600.0, 1700.0, 1800.0, 1900.0,*/
|
|
|
|
2000.0, 2400.0, 2800.0,
|
|
3000.0, 3400.0, 3600.0, 4000.0};
|
|
|
|
void smooth_phase3(struct PEXP *pexp, MODEL *model) {
|
|
int m, i;
|
|
int nbins;
|
|
int b;
|
|
float f, best_Wo, pred, err;
|
|
COMP av[MAX_BINS];
|
|
|
|
nbins = sizeof(bins)/sizeof(float);
|
|
best_Wo = refine_Wo(pexp, model, 1, model->L);
|
|
|
|
/* clear all bins */
|
|
|
|
for(i=0; i<MAX_BINS; i++) {
|
|
av[i].real = 0.0;
|
|
av[i].imag = 0.0;
|
|
}
|
|
|
|
/* add phases into each bin */
|
|
|
|
for(m=1; m<=model->L; m++) {
|
|
f = m*model->Wo*FS/TWO_PI;
|
|
if (f > bins[0]) {
|
|
|
|
/* find bin */
|
|
|
|
for(i=0; i<nbins; i++)
|
|
if ((f > bins[i]) && (f <= bins[i+1]))
|
|
b = i;
|
|
assert(b < MAX_BINS);
|
|
|
|
/* est predicted phase from average */
|
|
|
|
pred = pexp->phi_prev[m] + N*m*best_Wo;
|
|
err = model->phi[m] - pred;
|
|
av[b].real += cos(err); av[b].imag += sin(err);
|
|
}
|
|
|
|
}
|
|
|
|
/* use averages to est phases */
|
|
|
|
for(m=1; m<=model->L; m++) {
|
|
f = m*model->Wo*FS/TWO_PI;
|
|
if (f > bins[0]) {
|
|
|
|
/* find bin */
|
|
|
|
for(i=0; i<nbins; i++)
|
|
if ((f > bins[i]) && (f <= bins[i+1]))
|
|
b = i;
|
|
assert(b < MAX_BINS);
|
|
|
|
/* add predicted phase error to this bin */
|
|
|
|
printf("L %d m %d f %4.f b %d\n", model->L, m, f, b);
|
|
|
|
pred = pexp->phi_prev[m] + N*m*best_Wo;
|
|
err = atan2(av[b].imag, av[b].real);
|
|
printf(" %d: %4.3f -> ", m, model->phi[m]);
|
|
model->phi[m] = pred + err;
|
|
model->phi[m] = atan2(sin(model->phi[m]),cos(model->phi[m]));
|
|
printf("%4.3f\n", model->phi[m]);
|
|
}
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
|
|
/*
|
|
Try to code the phase of the largest amplitude in each band. Randomise the
|
|
phase of the other harmonics. The theory is that only the largest harmonic
|
|
will be audible.
|
|
*/
|
|
|
|
void cb_phase1(struct PEXP *pexp, MODEL *model) {
|
|
int m, i;
|
|
int nbins;
|
|
int b;
|
|
float f, best_Wo;
|
|
float max_val[MAX_BINS];
|
|
int max_ind[MAX_BINS];
|
|
|
|
nbins = sizeof(bins)/sizeof(float);
|
|
best_Wo = refine_Wo(pexp, model, 1, model->L);
|
|
|
|
for(i=0; i<nbins; i++)
|
|
max_val[i] = 0.0;
|
|
|
|
/* determine max amplitude for each bin */
|
|
|
|
for(m=1; m<=model->L; m++) {
|
|
f = m*model->Wo*FS/TWO_PI;
|
|
if (f > bins[0]) {
|
|
|
|
/* find bin */
|
|
|
|
for(i=0; i<nbins; i++)
|
|
if ((f > bins[i]) && (f <= bins[i+1]))
|
|
b = i;
|
|
assert(b < MAX_BINS);
|
|
|
|
if (model->A[m] > max_val[b]) {
|
|
max_val[b] = model->A[m];
|
|
max_ind[b] = m;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/* randomise phase of other harmonics */
|
|
|
|
for(m=1; m<=model->L; m++) {
|
|
f = m*model->Wo*FS/TWO_PI;
|
|
if (f > bins[0]) {
|
|
|
|
/* find bin */
|
|
|
|
for(i=0; i<nbins; i++)
|
|
if ((f > bins[i]) && (f <= bins[i+1]))
|
|
b = i;
|
|
assert(b < MAX_BINS);
|
|
|
|
if (m != max_ind[b])
|
|
model->phi[m] = pexp->phi_prev[m] + N*m*best_Wo;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
Theory is only the phase of the envelope of signal matters within a
|
|
Critical Band. So we estimate the position of an impulse that
|
|
approximates the envelope of the signal.
|
|
*/
|
|
|
|
void cb_phase2(struct PEXP *pexp, MODEL *model) {
|
|
int st, m, i, a, b, step;
|
|
float diff,w,c,s,phi1_;
|
|
float A[MAX_AMP];
|
|
|
|
for(m=1; m<=model->L; m++) {
|
|
A[m] = model->A[m];
|
|
model->A[m] = 0;
|
|
}
|
|
|
|
st = 2*model->L/4;
|
|
step = 3;
|
|
model->phi[1] = pexp->phi_prev[1] + (pexp->Wo_prev+model->Wo)*N/2.0;
|
|
|
|
printf("L=%d ", model->L);
|
|
for(m=st; m<st+step*2; m+=step) {
|
|
a = m; b=a+step;
|
|
if (b > model->L)
|
|
b = model->L;
|
|
|
|
c = s = 0;
|
|
for(i=a; i<b-1; i++) {
|
|
printf("diff %d,%d ", i, i+1);
|
|
diff = model->phi[i+1] - model->phi[i];
|
|
//w = (model->A[i+1] + model->A[i])/2;
|
|
w = 1.0;
|
|
c += w*cos(diff); s += w*sin(diff);
|
|
}
|
|
phi1_ = atan2(s,c);
|
|
printf("replacing: ");
|
|
for(i=a; i<b; i++) {
|
|
//model->phi[i] = i*phi1_;
|
|
//model->phi[i] = i*model->phi[1];
|
|
//model->phi[i] = m*(pexp->Wo_prev+model->Wo)*N/2.0;
|
|
model->A[m] = A[m];
|
|
printf("%d ", i);
|
|
}
|
|
printf(" . ");
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
|
|
static void smooth_phase4(MODEL *model) {
|
|
int m;
|
|
float phi_m, phi_m_1;
|
|
|
|
if (model->L > 25) {
|
|
printf("\nL %d\n", model->L);
|
|
for(m=model->L/2; m<=model->L; m+=2) {
|
|
if ((m+1) <= model->L) {
|
|
phi_m = (model->phi[m] - model->phi[m+1])/2.0;
|
|
phi_m_1 = (model->phi[m+1] - model->phi[m])/2.0;
|
|
model->phi[m] = phi_m;
|
|
model->phi[m+1] = phi_m_1;
|
|
printf("%d %4.3f %4.3f ", m, phi_m, phi_m_1);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/* try repeating last frame, just advance phases to account for time shift */
|
|
|
|
static void repeat_phases(struct PEXP *pexp, MODEL *model) {
|
|
int m;
|
|
|
|
*model = pexp->prev_model;
|
|
for(m=1; m<=model->L; m++)
|
|
model->phi[m] += N*m*model->Wo;
|
|
|
|
}
|
|
|
|
/*---------------------------------------------------------------------------*\
|
|
|
|
phase_experiment()
|
|
|
|
Phase quantisation experiments.
|
|
|
|
\*---------------------------------------------------------------------------*/
|
|
|
|
void phase_experiment(struct PEXP *pexp, MODEL *model, char *arg) {
|
|
int m;
|
|
float before[MAX_AMP], best_Wo;
|
|
|
|
assert(pexp != NULL);
|
|
memcpy(before, &model->phi[0], sizeof(float)*MAX_AMP);
|
|
|
|
if (strcmp(arg,"q3") == 0) {
|
|
quant_phases(model, 1, model->L, 3);
|
|
update_snr_calc(pexp, model, before);
|
|
update_variance_calc(pexp, model, before);
|
|
}
|
|
|
|
if (strcmp(arg,"dec2") == 0) {
|
|
if ((pexp->frames % 2) != 0) {
|
|
predict_phases(pexp, model, 1, model->L);
|
|
update_snr_calc(pexp, model, before);
|
|
update_variance_calc(pexp, model, before);
|
|
}
|
|
}
|
|
|
|
if (strcmp(arg,"repeat") == 0) {
|
|
if ((pexp->frames % 2) != 0) {
|
|
repeat_phases(pexp, model);
|
|
update_snr_calc(pexp, model, before);
|
|
update_variance_calc(pexp, model, before);
|
|
}
|
|
}
|
|
|
|
if (strcmp(arg,"vq") == 0) {
|
|
sparse_vq_pred_error(pexp, model);
|
|
update_snr_calc(pexp, model, before);
|
|
update_variance_calc(pexp, model, before);
|
|
}
|
|
|
|
if (strcmp(arg,"pred") == 0)
|
|
predict_phases_state(pexp, model, 1, model->L);
|
|
|
|
if (strcmp(arg,"pred1k") == 0)
|
|
predict_phases(pexp, model, 1, model->L/4);
|
|
|
|
if (strcmp(arg,"smooth") == 0) {
|
|
smooth_phase(pexp, model,0);
|
|
update_snr_calc(pexp, model, before);
|
|
}
|
|
if (strcmp(arg,"smoothtrain") == 0)
|
|
smooth_phase(pexp, model,1);
|
|
if (strcmp(arg,"smoothvq") == 0) {
|
|
smooth_phase(pexp, model,2);
|
|
update_snr_calc(pexp, model, before);
|
|
}
|
|
|
|
if (strcmp(arg,"smooth2") == 0)
|
|
smooth_phase2(pexp, model);
|
|
if (strcmp(arg,"smooth3") == 0)
|
|
smooth_phase3(pexp, model);
|
|
if (strcmp(arg,"smooth4") == 0)
|
|
smooth_phase4(model);
|
|
if (strcmp(arg,"vqsmooth3") == 0) {
|
|
sparse_vq_pred_error(pexp, model);
|
|
smooth_phase3(pexp, model);
|
|
}
|
|
|
|
if (strcmp(arg,"cb1") == 0) {
|
|
cb_phase1(pexp, model);
|
|
update_snr_calc(pexp, model, before);
|
|
}
|
|
|
|
if (strcmp(arg,"top") == 0) {
|
|
//top_amp(pexp, model, 1, model->L/4, 4, 1);
|
|
//top_amp(pexp, model, model->L/4, model->L/3, 4, 1);
|
|
//top_amp(pexp, model, model->L/3+1, model->L/2, 4, 1);
|
|
//top_amp(pexp, model, model->L/2, model->L, 6, 1);
|
|
//rand_phases(model, model->L/2, 3*model->L/4);
|
|
//struct_phases(pexp, model, model->L/2, 3*model->L/4);
|
|
//update_snr_calc(pexp, model, before);
|
|
}
|
|
|
|
if (strcmp(arg,"pred23") == 0) {
|
|
predict_phases2(pexp, model, model->L/2, model->L);
|
|
update_snr_calc(pexp, model, before);
|
|
}
|
|
|
|
if (strcmp(arg,"struct23") == 0) {
|
|
struct_phases(pexp, model, model->L/2, 3*model->L/4 );
|
|
update_snr_calc(pexp, model, before);
|
|
}
|
|
|
|
if (strcmp(arg,"addnoise") == 0) {
|
|
int m;
|
|
float max;
|
|
|
|
max = 0;
|
|
for(m=1; m<=model->L; m++)
|
|
if (model->A[m] > max)
|
|
max = model->A[m];
|
|
max = 20.0*log10(max);
|
|
for(m=1; m<=model->L; m++)
|
|
if (20.0*log10(model->A[m]) < (max-20)) {
|
|
model->phi[m] += (PI/4)*(1.0 -2.0*rand()/RAND_MAX);
|
|
//printf("m %d\n", m);
|
|
}
|
|
}
|
|
|
|
/* normalise phases */
|
|
|
|
for(m=1; m<=model->L; m++)
|
|
model->phi[m] = atan2(sin(model->phi[m]), cos(model->phi[m]));
|
|
|
|
/* update states */
|
|
|
|
//best_Wo = refine_Wo(pexp, model, model->L/2, model->L);
|
|
pexp->phi1 += N*model->Wo;
|
|
|
|
for(m=1; m<=model->L; m++)
|
|
pexp->phi_prev[m] = model->phi[m];
|
|
pexp->Wo_prev = model->Wo;
|
|
pexp->frames++;
|
|
pexp->prev_model = *model;
|
|
}
|
|
|
|
#ifdef OLD_STUFF
|
|
//quant_phases(model, 1, model->L, 3);
|
|
//update_variance_calc(pexp, model, before);
|
|
//print_sparse_pred_error(pexp, model, 1, model->L, 40.0);
|
|
|
|
//sparse_vq_pred_error(pexp, model);
|
|
|
|
//quant_phases(model, model->L/4+1, model->L, 3);
|
|
|
|
//predict_phases1(pexp, model, 1, model->L/4);
|
|
//quant_phases(model, model->L/4+1, model->L, 3);
|
|
|
|
//quant_phases(model, 1, model->L/8, 3);
|
|
|
|
//update_snr_calc(pexp, model, before);
|
|
//update_variance_calc(pexp, model, before);
|
|
|
|
//fixed_bits_per_frame(pexp, model, 40);
|
|
//struct_phases(pexp, model, 1, model->L/4);
|
|
//rand_phases(model, 10, model->L);
|
|
//for(m=1; m<=model->L; m++)
|
|
// model->A[m] = 0.0;
|
|
//model->A[model->L/2] = 1000;
|
|
//repeat_phases(model, 20);
|
|
//predict_phases(pexp, model, 1, model->L/4);
|
|
//quant_phases(model, 1, 10, 3);
|
|
//quant_phases(model, 10, 20, 2);
|
|
//repeat_phases(model, 20);
|
|
//rand_phases(model, 3*model->L/4, model->L);
|
|
// print_phi1_pred_error(model, 1, model->L);
|
|
//predict_phases(pexp, model, 1, model->L/4);
|
|
//first_order_band(model, model->L/4, model->L/2);
|
|
//first_order_band(model, model->L/2, 3*model->L/4);
|
|
//if (fabs(model->Wo - pexp->Wo_prev)< 0.1*model->Wo)
|
|
|
|
//print_pred_error(pexp, model, 1, model->L, 40.0);
|
|
//print_sparse_pred_error(pexp, model, 1, model->L, 40.0);
|
|
|
|
//phi1_est = est_phi1(model, 1, model->L/4);
|
|
//print_phi1_pred_error(model, 1, model->L/4);
|
|
|
|
//first_order_band(model, 1, model->L/4, phi1_est);
|
|
//sub_linear(model, 1, model->L/4, phi1_est);
|
|
|
|
//top_amp(pexp, model, 1, model->L/4, 4);
|
|
//top_amp(pexp, model, model->L/4, model->L/2, 4);
|
|
|
|
//first_order_band(model, 1, model->L/4, phi1_est);
|
|
//first_order_band(model, model->L/4, model->L/2, phi1_est);
|
|
|
|
//if (fabs(model->Wo - pexp->Wo_prev) > 0.2*model->Wo)
|
|
// rand_phases(model, model->L/2, model->L);
|
|
|
|
//top_amp(pexp, model, 1, model->L/4, 4);
|
|
//top_amp(pexp, model, model->L/4, model->L/2, 8);
|
|
//top_amp(pexp, model, model->L/4+1, model->L/2, 10, 1);
|
|
//top_amp(pexp, model, 1, model->L/4, 10, 1);
|
|
//top_amp(pexp, model, model->L/4+1, 3*model->L/4, 10, 1);
|
|
//top_amp(pexp, model, 1, 3*model->L/4, 20, 1);
|
|
|
|
#ifdef REAS_CAND1
|
|
predict_phases(pexp, model, 1, model->L/4);
|
|
top_amp(pexp, model, model->L/4+1, 3*model->L/4, 10, 1);
|
|
rand_phases(model, 3*model->L/4+1, model->L);
|
|
#endif
|
|
|
|
#ifdef REAS_CAND2
|
|
if ((pexp->frames % 2) == 0) {
|
|
//printf("quant\n");
|
|
predict_phases(pexp, model, 1, model->L/4);
|
|
//top_amp(pexp, model, model->L/4+1, 3*model->L/4, 20, 1);
|
|
top_amp(pexp, model, model->L/4+1, 7*model->L/8, 20, 1);
|
|
rand_phases(model, 7*model->L/8+1, model->L);
|
|
}
|
|
else {
|
|
//printf("predict\n");
|
|
predict_phases(pexp, model, 1, model->L);
|
|
}
|
|
#endif
|
|
|
|
//#define REAS_CAND3
|
|
#ifdef REAS_CAND3
|
|
if ((pexp->frames % 3) != 0) {
|
|
printf("pred\n");
|
|
predict_phases(pexp, model, 1, model->L);
|
|
}
|
|
else {
|
|
predict_phases(pexp, model, 1, model->L/4);
|
|
fixed_bits_per_frame(pexp, model, model->L/4+1, 60);
|
|
}
|
|
#endif
|
|
//predict_phases(pexp, model, model->L/4, model->L);
|
|
|
|
|
|
//print_pred_error(pexp, model, 1, model->L);
|
|
//limit_prediction_error(pexp, model, model->L/2, model->L, PI/2);
|
|
#endif
|