There are no tabs in source code.
There is also no trailing whitespace.
This commit is contained in:
parent
020a0a48d5
commit
554b349cdb
@ -9,12 +9,12 @@ in the Makefile.
|
||||
An up-to-date implementation conforming to this standard is available in a
|
||||
Git repository at git://git.xiph.org/opus.git or on a website at:
|
||||
http://opus-codec.org/
|
||||
However, although that implementation is expected to remain conformant
|
||||
with the standard, it is the code in this RFC that shall remain normative.
|
||||
However, although that implementation is expected to remain conformant
|
||||
with the standard, it is the code in this RFC that shall remain normative.
|
||||
To build from the git repository instead of using this RFC, follow these
|
||||
steps:
|
||||
|
||||
1) Clone the repository (latest implementation of this standard at the time
|
||||
1) Clone the repository (latest implementation of this standard at the time
|
||||
of publication)
|
||||
|
||||
% git clone git://git.opus-codec.org/opus.git
|
||||
|
||||
@ -4,7 +4,7 @@ INCLUDES=-I. -I../ -I../.. -I../../include
|
||||
all: dump_modes
|
||||
|
||||
dump_modes:
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -DCUSTOM_MODES_ONLY -DCUSTOM_MODES dump_modes.c ../modes.c ../cwrs.c ../rate.c ../entenc.c ../entdec.c ../mathops.c ../mdct.c ../kiss_fft.c -o dump_modes -lm
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -DCUSTOM_MODES_ONLY -DCUSTOM_MODES dump_modes.c ../modes.c ../cwrs.c ../rate.c ../entenc.c ../entdec.c ../mathops.c ../mdct.c ../kiss_fft.c -o dump_modes -lm
|
||||
|
||||
clean:
|
||||
rm -f dump_modes
|
||||
|
||||
@ -171,18 +171,18 @@ void dump_modes(FILE *file, CELTMode **modes, int nb_modes)
|
||||
fprintf(file, "#define FFT_STATE%d_%d_%d\n", mode->Fs, mdctSize, k);
|
||||
fprintf (file, "static const kiss_fft_state fft_state%d_%d_%d = {\n",
|
||||
mode->Fs, mdctSize, k);
|
||||
fprintf (file, "%d,\t/* nfft */\n", mode->mdct.kfft[k]->nfft);
|
||||
fprintf (file, WORD16 ",\t/* scale */\n", mode->mdct.kfft[k]->scale);
|
||||
fprintf (file, "%d, /* nfft */\n", mode->mdct.kfft[k]->nfft);
|
||||
fprintf (file, WORD16 ", /* scale */\n", mode->mdct.kfft[k]->scale);
|
||||
#ifdef FIXED_POINT
|
||||
fprintf (file, "%d,\t/* scale_shift */\n", mode->mdct.kfft[k]->scale_shift);
|
||||
fprintf (file, "%d, /* scale_shift */\n", mode->mdct.kfft[k]->scale_shift);
|
||||
#endif
|
||||
fprintf (file, "%d,\t/* shift */\n", mode->mdct.kfft[k]->shift);
|
||||
fprintf (file, "%d, /* shift */\n", mode->mdct.kfft[k]->shift);
|
||||
fprintf (file, "{");
|
||||
for (j=0;j<2*MAXFACTORS;j++)
|
||||
fprintf (file, "%d, ", mode->mdct.kfft[k]->factors[j]);
|
||||
fprintf (file, "},\t/* factors */\n");
|
||||
fprintf (file, "fft_bitrev%d,\t/* bitrev */\n", mode->mdct.kfft[k]->nfft);
|
||||
fprintf (file, "fft_twiddles%d_%d,\t/* bitrev */\n", mode->Fs, mdctSize);
|
||||
fprintf (file, "}, /* factors */\n");
|
||||
fprintf (file, "fft_bitrev%d, /* bitrev */\n", mode->mdct.kfft[k]->nfft);
|
||||
fprintf (file, "fft_twiddles%d_%d, /* bitrev */\n", mode->Fs, mdctSize);
|
||||
fprintf (file, "};\n");
|
||||
|
||||
fprintf(file, "#endif\n");
|
||||
@ -208,37 +208,37 @@ void dump_modes(FILE *file, CELTMode **modes, int nb_modes)
|
||||
|
||||
/* Print the actual mode data */
|
||||
fprintf(file, "static const CELTMode mode%d_%d_%d = {\n", mode->Fs, mdctSize, mode->overlap);
|
||||
fprintf(file, INT32 ",\t/* Fs */\n", mode->Fs);
|
||||
fprintf(file, "%d,\t/* overlap */\n", mode->overlap);
|
||||
fprintf(file, "%d,\t/* nbEBands */\n", mode->nbEBands);
|
||||
fprintf(file, "%d,\t/* effEBands */\n", mode->effEBands);
|
||||
fprintf(file, INT32 ", /* Fs */\n", mode->Fs);
|
||||
fprintf(file, "%d, /* overlap */\n", mode->overlap);
|
||||
fprintf(file, "%d, /* nbEBands */\n", mode->nbEBands);
|
||||
fprintf(file, "%d, /* effEBands */\n", mode->effEBands);
|
||||
fprintf(file, "{");
|
||||
for (j=0;j<4;j++)
|
||||
fprintf(file, WORD16 ", ", mode->preemph[j]);
|
||||
fprintf(file, "},\t/* preemph */\n");
|
||||
fprintf(file, "}, /* preemph */\n");
|
||||
if (standard)
|
||||
fprintf(file, "eband5ms,\t/* eBands */\n");
|
||||
fprintf(file, "eband5ms, /* eBands */\n");
|
||||
else
|
||||
fprintf(file, "eBands%d_%d,\t/* eBands */\n", mode->Fs, mdctSize);
|
||||
fprintf(file, "eBands%d_%d, /* eBands */\n", mode->Fs, mdctSize);
|
||||
|
||||
fprintf(file, "%d,\t/* maxLM */\n", mode->maxLM);
|
||||
fprintf(file, "%d,\t/* nbShortMdcts */\n", mode->nbShortMdcts);
|
||||
fprintf(file, "%d,\t/* shortMdctSize */\n", mode->shortMdctSize);
|
||||
fprintf(file, "%d, /* maxLM */\n", mode->maxLM);
|
||||
fprintf(file, "%d, /* nbShortMdcts */\n", mode->nbShortMdcts);
|
||||
fprintf(file, "%d, /* shortMdctSize */\n", mode->shortMdctSize);
|
||||
|
||||
fprintf(file, "%d,\t/* nbAllocVectors */\n", mode->nbAllocVectors);
|
||||
fprintf(file, "%d, /* nbAllocVectors */\n", mode->nbAllocVectors);
|
||||
if (standard)
|
||||
fprintf(file, "band_allocation,\t/* allocVectors */\n");
|
||||
fprintf(file, "band_allocation, /* allocVectors */\n");
|
||||
else
|
||||
fprintf(file, "allocVectors%d_%d,\t/* allocVectors */\n", mode->Fs, mdctSize);
|
||||
fprintf(file, "allocVectors%d_%d, /* allocVectors */\n", mode->Fs, mdctSize);
|
||||
|
||||
fprintf(file, "logN%d,\t/* logN */\n", framerate);
|
||||
fprintf(file, "window%d,\t/* window */\n", mode->overlap);
|
||||
fprintf(file, "logN%d, /* logN */\n", framerate);
|
||||
fprintf(file, "window%d, /* window */\n", mode->overlap);
|
||||
fprintf(file, "{%d, %d, {", mode->mdct.n, mode->mdct.maxshift);
|
||||
for (k=0;k<=mode->mdct.maxshift;k++)
|
||||
fprintf(file, "&fft_state%d_%d_%d, ", mode->Fs, mdctSize, k);
|
||||
fprintf (file, "}, mdct_twiddles%d},\t/* mdct */\n", mdctSize);
|
||||
fprintf (file, "}, mdct_twiddles%d}, /* mdct */\n", mdctSize);
|
||||
|
||||
fprintf(file, "{%d, cache_index%d, cache_bits%d, cache_caps%d},\t/* cache */\n",
|
||||
fprintf(file, "{%d, cache_index%d, cache_bits%d, cache_caps%d}, /* cache */\n",
|
||||
mode->cache.size, mode->Fs/mdctSize, mode->Fs/mdctSize, mode->Fs/mdctSize);
|
||||
fprintf(file, "};\n");
|
||||
}
|
||||
|
||||
@ -35,38 +35,38 @@
|
||||
|
||||
#undef MULT16_32_Q15_ADD
|
||||
static inline int MULT16_32_Q15_ADD(int a, int b, int c, int d) {
|
||||
int m;
|
||||
asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b));
|
||||
asm volatile("madd $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d));
|
||||
asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15));
|
||||
return m;
|
||||
int m;
|
||||
asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b));
|
||||
asm volatile("madd $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d));
|
||||
asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15));
|
||||
return m;
|
||||
}
|
||||
|
||||
#undef MULT16_32_Q15_SUB
|
||||
static inline int MULT16_32_Q15_SUB(int a, int b, int c, int d) {
|
||||
int m;
|
||||
asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b));
|
||||
asm volatile("msub $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d));
|
||||
asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15));
|
||||
return m;
|
||||
int m;
|
||||
asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b));
|
||||
asm volatile("msub $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d));
|
||||
asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15));
|
||||
return m;
|
||||
}
|
||||
|
||||
#undef MULT16_16_Q15_ADD
|
||||
static inline int MULT16_16_Q15_ADD(int a, int b, int c, int d) {
|
||||
int m;
|
||||
asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b));
|
||||
asm volatile("madd $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d));
|
||||
asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15));
|
||||
return m;
|
||||
int m;
|
||||
asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b));
|
||||
asm volatile("madd $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d));
|
||||
asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15));
|
||||
return m;
|
||||
}
|
||||
|
||||
#undef MULT16_16_Q15_SUB
|
||||
static inline int MULT16_16_Q15_SUB(int a, int b, int c, int d) {
|
||||
int m;
|
||||
asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b));
|
||||
asm volatile("msub $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d));
|
||||
asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15));
|
||||
return m;
|
||||
int m;
|
||||
asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b));
|
||||
asm volatile("msub $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d));
|
||||
asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15));
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -37,20 +37,20 @@
|
||||
|
||||
#undef S_MUL_ADD
|
||||
static inline int S_MUL_ADD(int a, int b, int c, int d) {
|
||||
int m;
|
||||
asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b));
|
||||
asm volatile("madd $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d));
|
||||
asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15));
|
||||
return m;
|
||||
int m;
|
||||
asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b));
|
||||
asm volatile("madd $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d));
|
||||
asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15));
|
||||
return m;
|
||||
}
|
||||
|
||||
#undef S_MUL_SUB
|
||||
static inline int S_MUL_SUB(int a, int b, int c, int d) {
|
||||
int m;
|
||||
asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b));
|
||||
asm volatile("msub $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d));
|
||||
asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15));
|
||||
return m;
|
||||
int m;
|
||||
asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b));
|
||||
asm volatile("msub $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d));
|
||||
asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15));
|
||||
return m;
|
||||
}
|
||||
|
||||
#undef C_MUL
|
||||
|
||||
@ -46,11 +46,11 @@ static inline void dual_inner_prod(const opus_val16 *x, const opus_val16 *y01, c
|
||||
/* Compute the norm of X+Y and X-Y as |X|^2 + |Y|^2 +/- sum(xy) */
|
||||
for (j=0;j<N;j++)
|
||||
{
|
||||
asm volatile("MADD $ac1, %0, %1" : : "r" ((int)x[j]), "r" ((int)y01[j]));
|
||||
asm volatile("MADD $ac2, %0, %1" : : "r" ((int)x[j]), "r" ((int)y02[j]));
|
||||
++j;
|
||||
asm volatile("MADD $ac1, %0, %1" : : "r" ((int)x[j]), "r" ((int)y01[j]));
|
||||
asm volatile("MADD $ac2, %0, %1" : : "r" ((int)x[j]), "r" ((int)y02[j]));
|
||||
asm volatile("MADD $ac1, %0, %1" : : "r" ((int)x[j]), "r" ((int)y01[j]));
|
||||
asm volatile("MADD $ac2, %0, %1" : : "r" ((int)x[j]), "r" ((int)y02[j]));
|
||||
++j;
|
||||
asm volatile("MADD $ac1, %0, %1" : : "r" ((int)x[j]), "r" ((int)y01[j]));
|
||||
asm volatile("MADD $ac2, %0, %1" : : "r" ((int)x[j]), "r" ((int)y02[j]));
|
||||
}
|
||||
asm volatile ("mflo %0, $ac1": "=r"(xy01));
|
||||
asm volatile ("mflo %0, $ac2": "=r"(xy02));
|
||||
|
||||
@ -426,10 +426,10 @@ static const opus_int16 fft_bitrev60[60] = {
|
||||
#define FFT_STATE48000_960_0
|
||||
static const kiss_fft_state fft_state48000_960_0 = {
|
||||
480, /* nfft */
|
||||
17476, /* scale */
|
||||
17476, /* scale */
|
||||
8, /* scale_shift */
|
||||
-1, /* shift */
|
||||
{5, 96, 3, 32, 4, 8, 2, 4, 4, 1, 0, 0, 0, 0, 0, 0, }, /* factors */
|
||||
{5, 96, 3, 32, 4, 8, 2, 4, 4, 1, 0, 0, 0, 0, 0, 0, }, /* factors */
|
||||
fft_bitrev480, /* bitrev */
|
||||
fft_twiddles48000_960, /* bitrev */
|
||||
};
|
||||
@ -439,10 +439,10 @@ fft_twiddles48000_960, /* bitrev */
|
||||
#define FFT_STATE48000_960_1
|
||||
static const kiss_fft_state fft_state48000_960_1 = {
|
||||
240, /* nfft */
|
||||
17476, /* scale */
|
||||
17476, /* scale */
|
||||
7, /* scale_shift */
|
||||
1, /* shift */
|
||||
{5, 48, 3, 16, 4, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
|
||||
{5, 48, 3, 16, 4, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
|
||||
fft_bitrev240, /* bitrev */
|
||||
fft_twiddles48000_960, /* bitrev */
|
||||
};
|
||||
@ -452,10 +452,10 @@ fft_twiddles48000_960, /* bitrev */
|
||||
#define FFT_STATE48000_960_2
|
||||
static const kiss_fft_state fft_state48000_960_2 = {
|
||||
120, /* nfft */
|
||||
17476, /* scale */
|
||||
17476, /* scale */
|
||||
6, /* scale_shift */
|
||||
2, /* shift */
|
||||
{5, 24, 3, 8, 2, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
|
||||
{5, 24, 3, 8, 2, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
|
||||
fft_bitrev120, /* bitrev */
|
||||
fft_twiddles48000_960, /* bitrev */
|
||||
};
|
||||
@ -465,10 +465,10 @@ fft_twiddles48000_960, /* bitrev */
|
||||
#define FFT_STATE48000_960_3
|
||||
static const kiss_fft_state fft_state48000_960_3 = {
|
||||
60, /* nfft */
|
||||
17476, /* scale */
|
||||
17476, /* scale */
|
||||
5, /* scale_shift */
|
||||
3, /* shift */
|
||||
{5, 12, 3, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
|
||||
{5, 12, 3, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
|
||||
fft_bitrev60, /* bitrev */
|
||||
fft_twiddles48000_960, /* bitrev */
|
||||
};
|
||||
|
||||
@ -440,7 +440,7 @@ static const kiss_fft_state fft_state48000_960_1 = {
|
||||
240, /* nfft */
|
||||
0.004166667f, /* scale */
|
||||
1, /* shift */
|
||||
{5, 48, 3, 16, 4, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
|
||||
{5, 48, 3, 16, 4, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
|
||||
fft_bitrev240, /* bitrev */
|
||||
fft_twiddles48000_960, /* bitrev */
|
||||
};
|
||||
@ -452,7 +452,7 @@ static const kiss_fft_state fft_state48000_960_2 = {
|
||||
120, /* nfft */
|
||||
0.008333333f, /* scale */
|
||||
2, /* shift */
|
||||
{5, 24, 3, 8, 2, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
|
||||
{5, 24, 3, 8, 2, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
|
||||
fft_bitrev120, /* bitrev */
|
||||
fft_twiddles48000_960, /* bitrev */
|
||||
};
|
||||
@ -464,7 +464,7 @@ static const kiss_fft_state fft_state48000_960_3 = {
|
||||
60, /* nfft */
|
||||
0.016666667f, /* scale */
|
||||
3, /* shift */
|
||||
{5, 12, 3, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
|
||||
{5, 12, 3, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
|
||||
fft_bitrev60, /* bitrev */
|
||||
fft_twiddles48000_960, /* bitrev */
|
||||
};
|
||||
|
||||
@ -66,10 +66,10 @@ int main(int _argc,char **_argv){
|
||||
const char *env_seed;
|
||||
ret=0;
|
||||
entropy=0;
|
||||
if (_argc > 2) {
|
||||
fprintf(stderr, "Usage: %s [<seed>]\n", _argv[0]);
|
||||
return 1;
|
||||
}
|
||||
if (_argc > 2) {
|
||||
fprintf(stderr, "Usage: %s [<seed>]\n", _argv[0]);
|
||||
return 1;
|
||||
}
|
||||
env_seed = getenv("SEED");
|
||||
if (_argc > 1)
|
||||
seed = atoi(_argv[1]);
|
||||
|
||||
@ -224,7 +224,7 @@ void testexp2(void)
|
||||
float error2 = fabs(exp(0.6931471805599453094*x/1024.0)-celt_exp2(x)/65536.0);
|
||||
if (error1>0.0002&&error2>0.00004)
|
||||
{
|
||||
fprintf (stderr, "celt_exp2 failed: x = "WORD", error1 = %f, error2 = %f\n", x,error1,error2);
|
||||
fprintf (stderr, "celt_exp2 failed: x = "WORD", error1 = %f, error2 = %f\n", x,error1,error2);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -611,7 +611,7 @@ WARN_LOGFILE =
|
||||
# with spaces.
|
||||
|
||||
INPUT = @top_srcdir@/include/opus.h \
|
||||
@top_srcdir@/include/opus_types.h \
|
||||
@top_srcdir@/include/opus_types.h \
|
||||
@top_srcdir@/include/opus_defines.h \
|
||||
@top_srcdir@/include/opus_multistream.h \
|
||||
@top_srcdir@/include/opus_custom.h
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -58,7 +58,7 @@
|
||||
<middle>
|
||||
<section title="Introduction">
|
||||
<t>This document addresses minor issues that were discovered in the reference
|
||||
implementation of the Opus codec that serves as the specification in
|
||||
implementation of the Opus codec that serves as the specification in
|
||||
<xref target="RFC6716">RFC 6716</xref>. Only issues affecting the decoder are
|
||||
listed here. An up-to-date implementation of the Opus encoder can be found at
|
||||
http://opus-codec.org/. The updated specification remains fully compatible with
|
||||
@ -84,7 +84,7 @@
|
||||
for( n = 0; n < DECODER_NUM_CHANNELS; n++ ) {
|
||||
ret = silk_init_decoder( &channel_state[ n ] );
|
||||
}
|
||||
+ silk_memset(&((silk_decoder *)decState)->sStereo, 0,
|
||||
+ silk_memset(&((silk_decoder *)decState)->sStereo, 0,
|
||||
+ sizeof(((silk_decoder *)decState)->sStereo));
|
||||
+ /* Not strictly needed, but it's cleaner that way */
|
||||
+ ((silk_decoder *)decState)->prev_decode_only_middle = 0;
|
||||
@ -218,16 +218,16 @@ RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) );
|
||||
in the patch above are split using a backslash character. The backslashes
|
||||
at the end of a line and the white space at the beginning
|
||||
of the following line are not part of the patch. A properly formatted patch
|
||||
including the three changes above is available at
|
||||
including the three changes above is available at
|
||||
<eref target="http://jmvalin.ca/misc_stuff/opus_update.patch"/>.
|
||||
</t>
|
||||
</section>
|
||||
|
||||
|
||||
<section title="Downmix to Mono">
|
||||
<t>The last issue is not strictly a bug, but it is an issue that has been reported
|
||||
when downmixing an Opus decoded stream to mono, whether this is done inside the decoder
|
||||
or as a post-processing step on the stereo decoder output. Opus intensity stereo allows
|
||||
optionally coding the two channels 180-degrees out of phase on a per-band basis.
|
||||
optionally coding the two channels 180-degrees out of phase on a per-band basis.
|
||||
This provides better stereo quality than forcing the two channels to be in phase,
|
||||
but when the output is downmixed to mono, the energy in the affected bands is cancelled
|
||||
sometimes resulting in audible artefacts.
|
||||
|
||||
@ -419,7 +419,7 @@
|
||||
</figure>
|
||||
|
||||
<t>
|
||||
<xref target='opus-packetization'/> shows supported frame sizes in
|
||||
<xref target='opus-packetization'/> shows supported frame sizes in
|
||||
milliseconds of encoded speech or audio data for the speech and audio modes
|
||||
(Mode) and sampling rates (fs) of Opus and shows how the timestamp is
|
||||
incremented for packetization (ts incr). If the Opus encoder
|
||||
@ -427,7 +427,7 @@
|
||||
increment is the sum of the increments for the individual frames.
|
||||
</t>
|
||||
|
||||
<texttable anchor='opus-packetization' title="Supported Opus frame
|
||||
<texttable anchor='opus-packetization' title="Supported Opus frame
|
||||
sizes and timestamp increments">
|
||||
<ttcol align='center'>Mode</ttcol>
|
||||
<ttcol align='center'>fs</ttcol>
|
||||
@ -517,7 +517,7 @@
|
||||
usage and encoding complexity, so an encoder SHOULD NOT encode
|
||||
frequencies above the audio bandwidth specified by maxplaybackrate.
|
||||
This parameter can take any value between 8000 and 48000, although
|
||||
commonly the value will match one of the Opus bandwidths
|
||||
commonly the value will match one of the Opus bandwidths
|
||||
(<xref target="bandwidth_definitions"/>).
|
||||
By default, the receiver is assumed to have no limitations, i.e. 48000.
|
||||
<vspace blankLines='1'/>
|
||||
@ -531,7 +531,7 @@
|
||||
This parameter is useful to avoid wasting receiver resources by operating the audio
|
||||
processing pipeline (e.g. echo cancellation) at a higher rate than necessary.
|
||||
This parameter can take any value between 8000 and 48000, although
|
||||
commonly the value will match one of the Opus bandwidths
|
||||
commonly the value will match one of the Opus bandwidths
|
||||
(<xref target="bandwidth_definitions"/>).
|
||||
By default, the sender is assumed to have no limitations, i.e. 48000.
|
||||
<vspace blankLines='1'/>
|
||||
@ -708,9 +708,9 @@
|
||||
mapped to "a=ptime" and "a=maxptime" attributes, respectively, in the
|
||||
SDP.</t>
|
||||
|
||||
<t>The OPTIONAL media type parameters "maxaveragebitrate",
|
||||
"maxplaybackrate", "minptime", "stereo", "cbr", "useinbandfec", and
|
||||
"usedtx", when present, MUST be included in the "a=fmtp" attribute
|
||||
<t>The OPTIONAL media type parameters "maxaveragebitrate",
|
||||
"maxplaybackrate", "minptime", "stereo", "cbr", "useinbandfec", and
|
||||
"usedtx", when present, MUST be included in the "a=fmtp" attribute
|
||||
in the SDP, expressed as a media type string in the form of a
|
||||
semicolon-separated list of parameter=value pairs (e.g.,
|
||||
maxaveragebitrate=20000). They MUST NOT be specified in an
|
||||
@ -838,7 +838,7 @@
|
||||
of the other side MUST NOT send with an average bitrate higher than
|
||||
"maxaveragebitrate" as it might overload the network and/or
|
||||
receiver. The "maxaveragebitrate" parameter typically will not
|
||||
compromise interoperability; however, some values might cause
|
||||
compromise interoperability; however, some values might cause
|
||||
application performance to suffer, and ought to be set with
|
||||
care.</t>
|
||||
|
||||
|
||||
@ -11,13 +11,13 @@
|
||||
/* Boxes */
|
||||
.pre
|
||||
{
|
||||
white-space: pre; /* CSS 2.0 */
|
||||
white-space: pre-wrap; /* CSS 2.1 */
|
||||
white-space: -pre-wrap; /* Opera 4-6 */
|
||||
white-space: -o-pre-wrap; /* Opera 7 */
|
||||
white-space: -moz-pre-wrap; /* Mozilla */
|
||||
white-space: -hp-pre-wrap; /* HP Printers */
|
||||
word-wrap : break-word; /* IE 5+ */
|
||||
white-space: pre; /* CSS 2.0 */
|
||||
white-space: pre-wrap; /* CSS 2.1 */
|
||||
white-space: -pre-wrap; /* Opera 4-6 */
|
||||
white-space: -o-pre-wrap; /* Opera 7 */
|
||||
white-space: -moz-pre-wrap; /* Mozilla */
|
||||
white-space: -hp-pre-wrap; /* HP Printers */
|
||||
word-wrap : break-word; /* IE 5+ */
|
||||
}
|
||||
|
||||
.title_box
|
||||
|
||||
@ -59,11 +59,11 @@
|
||||
y1="95.107399"
|
||||
x2="194.53169"
|
||||
y2="9.9475983e-14">
|
||||
<stop
|
||||
<stop
|
||||
offset="0.0056"
|
||||
style="stop-color:#8E8E8E"
|
||||
id="stop7" />
|
||||
<stop
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#B5B5B5"
|
||||
id="stop9" />
|
||||
@ -76,11 +76,11 @@
|
||||
y1="116.208"
|
||||
x2="229.61819"
|
||||
y2="164.46291">
|
||||
<stop
|
||||
<stop
|
||||
offset="0.0056"
|
||||
style="stop-color:#494748"
|
||||
id="stop14" />
|
||||
<stop
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#000000"
|
||||
id="stop16" />
|
||||
@ -93,11 +93,11 @@
|
||||
y1="115.4395"
|
||||
x2="43.9897"
|
||||
y2="165.2314">
|
||||
<stop
|
||||
<stop
|
||||
offset="0.0056"
|
||||
style="stop-color:#494748"
|
||||
id="stop21" />
|
||||
<stop
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#000000"
|
||||
id="stop23" />
|
||||
@ -110,11 +110,11 @@
|
||||
y1="115.7188"
|
||||
x2="311.2847"
|
||||
y2="165.2822">
|
||||
<stop
|
||||
<stop
|
||||
offset="0.0056"
|
||||
style="stop-color:#494748"
|
||||
id="stop28" />
|
||||
<stop
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#000000"
|
||||
id="stop30" />
|
||||
@ -127,11 +127,11 @@
|
||||
y1="115.5791"
|
||||
x2="129.1987"
|
||||
y2="204.4863">
|
||||
<stop
|
||||
<stop
|
||||
offset="0.0056"
|
||||
style="stop-color:#494748"
|
||||
id="stop35" />
|
||||
<stop
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#000000"
|
||||
id="stop37" />
|
||||
|
||||
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 8.5 KiB |
@ -10,7 +10,7 @@
|
||||
- Verify 'make distcheck' produces a tarball with
|
||||
the desired name.
|
||||
- Push tag to public repo.
|
||||
- Upload source package 'opus-${version}.tar.gz'
|
||||
- Upload source package 'opus-${version}.tar.gz'
|
||||
- Add to https://svn.xiph.org/releases/opus/
|
||||
- Update checksum files
|
||||
- svn commit
|
||||
|
||||
20
silk/CNG.c
20
silk/CNG.c
@ -128,16 +128,16 @@ void silk_CNG(
|
||||
ALLOC( CNG_sig_Q10, length + MAX_LPC_ORDER, opus_int32 );
|
||||
|
||||
/* Generate CNG excitation */
|
||||
gain_Q16 = silk_SMULWW( psDec->sPLC.randScale_Q14, psDec->sPLC.prevGain_Q16[1] );
|
||||
if( gain_Q16 >= (1 << 21) || psCNG->CNG_smth_Gain_Q16 > (1 << 23) ) {
|
||||
gain_Q16 = silk_SMULTT( gain_Q16, gain_Q16 );
|
||||
gain_Q16 = silk_SUB_LSHIFT32(silk_SMULTT( psCNG->CNG_smth_Gain_Q16, psCNG->CNG_smth_Gain_Q16 ), gain_Q16, 5 );
|
||||
gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 16 );
|
||||
} else {
|
||||
gain_Q16 = silk_SMULWW( gain_Q16, gain_Q16 );
|
||||
gain_Q16 = silk_SUB_LSHIFT32(silk_SMULWW( psCNG->CNG_smth_Gain_Q16, psCNG->CNG_smth_Gain_Q16 ), gain_Q16, 5 );
|
||||
gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 8 );
|
||||
}
|
||||
gain_Q16 = silk_SMULWW( psDec->sPLC.randScale_Q14, psDec->sPLC.prevGain_Q16[1] );
|
||||
if( gain_Q16 >= (1 << 21) || psCNG->CNG_smth_Gain_Q16 > (1 << 23) ) {
|
||||
gain_Q16 = silk_SMULTT( gain_Q16, gain_Q16 );
|
||||
gain_Q16 = silk_SUB_LSHIFT32(silk_SMULTT( psCNG->CNG_smth_Gain_Q16, psCNG->CNG_smth_Gain_Q16 ), gain_Q16, 5 );
|
||||
gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 16 );
|
||||
} else {
|
||||
gain_Q16 = silk_SMULWW( gain_Q16, gain_Q16 );
|
||||
gain_Q16 = silk_SUB_LSHIFT32(silk_SMULWW( psCNG->CNG_smth_Gain_Q16, psCNG->CNG_smth_Gain_Q16 ), gain_Q16, 5 );
|
||||
gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 8 );
|
||||
}
|
||||
silk_CNG_exc( CNG_sig_Q10 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q14, gain_Q16, length, &psCNG->rand_seed );
|
||||
|
||||
/* Convert CNG NLSF to filter representation */
|
||||
|
||||
@ -55,7 +55,7 @@ void silk_VQ_WMat_EC_c(
|
||||
*rate_dist_Q14 = silk_int32_MAX;
|
||||
cb_row_Q7 = cb_Q7;
|
||||
for( k = 0; k < L; k++ ) {
|
||||
gain_tmp_Q7 = cb_gain_Q7[k];
|
||||
gain_tmp_Q7 = cb_gain_Q7[k];
|
||||
|
||||
diff_Q14[ 0 ] = in_Q14[ 0 ] - silk_LSHIFT( cb_row_Q7[ 0 ], 7 );
|
||||
diff_Q14[ 1 ] = in_Q14[ 1 ] - silk_LSHIFT( cb_row_Q7[ 1 ], 7 );
|
||||
@ -66,8 +66,8 @@ void silk_VQ_WMat_EC_c(
|
||||
/* Weighted rate */
|
||||
sum1_Q14 = silk_SMULBB( mu_Q9, cl_Q5[ k ] );
|
||||
|
||||
/* Penalty for too large gain */
|
||||
sum1_Q14 = silk_ADD_LSHIFT32( sum1_Q14, silk_max( silk_SUB32( gain_tmp_Q7, max_gain_Q7 ), 0 ), 10 );
|
||||
/* Penalty for too large gain */
|
||||
sum1_Q14 = silk_ADD_LSHIFT32( sum1_Q14, silk_max( silk_SUB32( gain_tmp_Q7, max_gain_Q7 ), 0 ), 10 );
|
||||
|
||||
silk_assert( sum1_Q14 >= 0 );
|
||||
|
||||
@ -111,7 +111,7 @@ void silk_VQ_WMat_EC_c(
|
||||
if( sum1_Q14 < *rate_dist_Q14 ) {
|
||||
*rate_dist_Q14 = sum1_Q14;
|
||||
*ind = (opus_int8)k;
|
||||
*gain_Q7 = gain_tmp_Q7;
|
||||
*gain_Q7 = gain_tmp_Q7;
|
||||
}
|
||||
|
||||
/* Go to next cbk vector */
|
||||
|
||||
@ -73,13 +73,13 @@ void silk_burg_modified_c(
|
||||
rshifts = 32 + 1 + N_BITS_HEAD_ROOM - lz;
|
||||
if (rshifts > MAX_RSHIFTS) rshifts = MAX_RSHIFTS;
|
||||
if (rshifts < MIN_RSHIFTS) rshifts = MIN_RSHIFTS;
|
||||
|
||||
|
||||
if (rshifts > 0) {
|
||||
C0 = (opus_int32)silk_RSHIFT64(C0_64, rshifts );
|
||||
C0 = (opus_int32)silk_RSHIFT64(C0_64, rshifts );
|
||||
} else {
|
||||
C0 = silk_LSHIFT32((opus_int32)C0_64, -rshifts );
|
||||
}
|
||||
|
||||
|
||||
CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */
|
||||
silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );
|
||||
if( rshifts > 0 ) {
|
||||
|
||||
@ -289,7 +289,7 @@ opus_int silk_encode_frame_FIX(
|
||||
for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
|
||||
sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], gainMult_Q8 ), 8 );
|
||||
}
|
||||
|
||||
|
||||
/* Quantize gains */
|
||||
psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
|
||||
silk_gains_quant( psEnc->sCmn.indices.GainsIndices, sEncCtrl.Gains_Q16,
|
||||
|
||||
@ -119,16 +119,16 @@ void silk_find_pred_coefs_FIX(
|
||||
|
||||
silk_memset( psEncCtrl->LTPCoef_Q14, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( opus_int16 ) );
|
||||
psEncCtrl->LTPredCodGain_Q7 = 0;
|
||||
psEnc->sCmn.sum_log_gain_Q7 = 0;
|
||||
psEnc->sCmn.sum_log_gain_Q7 = 0;
|
||||
}
|
||||
|
||||
/* Limit on total predictive coding gain */
|
||||
if( psEnc->sCmn.first_frame_after_reset ) {
|
||||
minInvGain_Q30 = SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN_AFTER_RESET, 30 );
|
||||
} else {
|
||||
} else {
|
||||
minInvGain_Q30 = silk_log2lin( silk_SMLAWB( 16 << 7, (opus_int32)psEncCtrl->LTPredCodGain_Q7, SILK_FIX_CONST( 1.0 / 3, 16 ) ) ); /* Q16 */
|
||||
minInvGain_Q30 = silk_DIV32_varQ( minInvGain_Q30,
|
||||
silk_SMULWW( SILK_FIX_CONST( MAX_PREDICTION_POWER_GAIN, 0 ),
|
||||
minInvGain_Q30 = silk_DIV32_varQ( minInvGain_Q30,
|
||||
silk_SMULWW( SILK_FIX_CONST( MAX_PREDICTION_POWER_GAIN, 0 ),
|
||||
silk_SMLAWB( SILK_FIX_CONST( 0.25, 18 ), SILK_FIX_CONST( 0.75, 18 ), psEncCtrl->coding_quality_Q14 ) ), 14 );
|
||||
}
|
||||
|
||||
|
||||
@ -99,6 +99,6 @@ void silk_find_LPC_FLP(
|
||||
silk_A2NLSF_FLP( NLSF_Q15, a, psEncC->predictLPCOrder );
|
||||
}
|
||||
|
||||
silk_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 ||
|
||||
silk_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 ||
|
||||
( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) );
|
||||
}
|
||||
|
||||
@ -91,13 +91,13 @@ void silk_find_pred_coefs_FLP(
|
||||
}
|
||||
silk_memset( psEncCtrl->LTPCoef, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( silk_float ) );
|
||||
psEncCtrl->LTPredCodGain = 0.0f;
|
||||
psEnc->sCmn.sum_log_gain_Q7 = 0;
|
||||
psEnc->sCmn.sum_log_gain_Q7 = 0;
|
||||
}
|
||||
|
||||
/* Limit on total predictive coding gain */
|
||||
if( psEnc->sCmn.first_frame_after_reset ) {
|
||||
minInvGain = 1.0f / MAX_PREDICTION_POWER_GAIN_AFTER_RESET;
|
||||
} else {
|
||||
} else {
|
||||
minInvGain = (silk_float)pow( 2, psEncCtrl->LTPredCodGain / 3 ) / MAX_PREDICTION_POWER_GAIN;
|
||||
minInvGain /= 0.25f + 0.75f * psEncCtrl->coding_quality;
|
||||
}
|
||||
|
||||
@ -182,8 +182,8 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced,
|
||||
|
||||
/* Calculate first vector products before loop */
|
||||
cross_corr = xcorr[ max_lag_4kHz - min_lag_4kHz ];
|
||||
normalizer = silk_energy_FLP( target_ptr, sf_length_8kHz ) +
|
||||
silk_energy_FLP( basis_ptr, sf_length_8kHz ) +
|
||||
normalizer = silk_energy_FLP( target_ptr, sf_length_8kHz ) +
|
||||
silk_energy_FLP( basis_ptr, sf_length_8kHz ) +
|
||||
sf_length_8kHz * 4000.0f;
|
||||
|
||||
C[ 0 ][ min_lag_4kHz ] += (silk_float)( 2 * cross_corr / normalizer );
|
||||
|
||||
@ -33,7 +33,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/* Approximation of 2^() (very close inverse of silk_lin2log()) */
|
||||
/* Convert input to a linear scale */
|
||||
opus_int32 silk_log2lin(
|
||||
opus_int32 silk_log2lin(
|
||||
const opus_int32 inLog_Q7 /* I input on log scale */
|
||||
)
|
||||
{
|
||||
@ -42,8 +42,8 @@ opus_int32 silk_log2lin(
|
||||
if( inLog_Q7 < 0 ) {
|
||||
return 0;
|
||||
} else if ( inLog_Q7 >= 3967 ) {
|
||||
return silk_int32_MAX;
|
||||
}
|
||||
return silk_int32_MAX;
|
||||
}
|
||||
|
||||
out = silk_LSHIFT( 1, silk_RSHIFT( inLog_Q7, 7 ) );
|
||||
frac_Q7 = inLog_Q7 & 0x7F;
|
||||
|
||||
@ -208,7 +208,7 @@ void silk_quant_LTP_gains(
|
||||
opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (un)quantized LTP gains */
|
||||
opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook Index */
|
||||
opus_int8 *periodicity_index, /* O Periodicity Index */
|
||||
opus_int32 *sum_gain_dB_Q7, /* I/O Cumulative max prediction gain */
|
||||
opus_int32 *sum_gain_dB_Q7, /* I/O Cumulative max prediction gain */
|
||||
const opus_int32 W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I Error Weights in Q18 */
|
||||
opus_int mu_Q9, /* I Mu value (R/D tradeoff) */
|
||||
opus_int lowComplexity, /* I Flag for low complexity */
|
||||
|
||||
@ -127,7 +127,7 @@ static inline void silk_noise_shape_quantizer_del_dec(
|
||||
temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -2 ], b_Q14_2 );
|
||||
temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -3 ], b_Q14_3 );
|
||||
temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -4 ], b_Q14_4 );
|
||||
temp64 += 32768;
|
||||
temp64 += 32768;
|
||||
LTP_pred_Q14 = __builtin_mips_extr_w(temp64, 16);
|
||||
LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */
|
||||
pred_lag_ptr++;
|
||||
|
||||
@ -36,7 +36,7 @@ void silk_quant_LTP_gains(
|
||||
opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (un)quantized LTP gains */
|
||||
opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook Index */
|
||||
opus_int8 *periodicity_index, /* O Periodicity Index */
|
||||
opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */
|
||||
opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */
|
||||
const opus_int32 W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I Error Weights in Q18 */
|
||||
opus_int mu_Q9, /* I Mu value (R/D tradeoff) */
|
||||
opus_int lowComplexity, /* I Flag for low complexity */
|
||||
@ -52,7 +52,7 @@ void silk_quant_LTP_gains(
|
||||
const opus_int16 *b_Q14_ptr;
|
||||
const opus_int32 *W_Q18_ptr;
|
||||
opus_int32 rate_dist_Q14_subfr, rate_dist_Q14, min_rate_dist_Q14;
|
||||
opus_int32 sum_log_gain_tmp_Q7, best_sum_log_gain_Q7, max_gain_Q7, gain_Q7;
|
||||
opus_int32 sum_log_gain_tmp_Q7, best_sum_log_gain_Q7, max_gain_Q7, gain_Q7;
|
||||
|
||||
/***************************************************/
|
||||
/* iterate over different codebooks with different */
|
||||
@ -75,22 +75,22 @@ void silk_quant_LTP_gains(
|
||||
b_Q14_ptr = B_Q14;
|
||||
|
||||
rate_dist_Q14 = 0;
|
||||
sum_log_gain_tmp_Q7 = *sum_log_gain_Q7;
|
||||
sum_log_gain_tmp_Q7 = *sum_log_gain_Q7;
|
||||
for( j = 0; j < nb_subfr; j++ ) {
|
||||
max_gain_Q7 = silk_log2lin( ( SILK_FIX_CONST( MAX_SUM_LOG_GAIN_DB / 6.0, 7 ) - sum_log_gain_tmp_Q7 )
|
||||
+ SILK_FIX_CONST( 7, 7 ) ) - gain_safety;
|
||||
max_gain_Q7 = silk_log2lin( ( SILK_FIX_CONST( MAX_SUM_LOG_GAIN_DB / 6.0, 7 ) - sum_log_gain_tmp_Q7 )
|
||||
+ SILK_FIX_CONST( 7, 7 ) ) - gain_safety;
|
||||
|
||||
silk_VQ_WMat_EC(
|
||||
&temp_idx[ j ], /* O index of best codebook vector */
|
||||
&rate_dist_Q14_subfr, /* O best weighted quantization error + mu * rate */
|
||||
&gain_Q7, /* O sum of absolute LTP coefficients */
|
||||
&gain_Q7, /* O sum of absolute LTP coefficients */
|
||||
b_Q14_ptr, /* I input vector to be quantized */
|
||||
W_Q18_ptr, /* I weighting matrix */
|
||||
cbk_ptr_Q7, /* I codebook */
|
||||
cbk_gain_ptr_Q7, /* I codebook effective gains */
|
||||
cl_ptr_Q5, /* I code length for each codebook vector */
|
||||
mu_Q9, /* I tradeoff between weighted error and rate */
|
||||
max_gain_Q7, /* I maximum sum of absolute LTP coefficients */
|
||||
max_gain_Q7, /* I maximum sum of absolute LTP coefficients */
|
||||
cbk_size, /* I number of vectors in codebook */
|
||||
arch /* I Run-time architecture */
|
||||
);
|
||||
@ -110,7 +110,7 @@ void silk_quant_LTP_gains(
|
||||
min_rate_dist_Q14 = rate_dist_Q14;
|
||||
*periodicity_index = (opus_int8)k;
|
||||
silk_memcpy( cbk_index, temp_idx, nb_subfr * sizeof( opus_int8 ) );
|
||||
best_sum_log_gain_Q7 = sum_log_gain_tmp_Q7;
|
||||
best_sum_log_gain_Q7 = sum_log_gain_tmp_Q7;
|
||||
}
|
||||
|
||||
/* Break early in low-complexity mode if rate distortion is below threshold */
|
||||
@ -125,6 +125,5 @@ void silk_quant_LTP_gains(
|
||||
B_Q14[ j * LTP_ORDER + k ] = silk_LSHIFT( cbk_ptr_Q7[ cbk_index[ j ] * LTP_ORDER + k ], 7 );
|
||||
}
|
||||
}
|
||||
*sum_log_gain_Q7 = best_sum_log_gain_Q7;
|
||||
*sum_log_gain_Q7 = best_sum_log_gain_Q7;
|
||||
}
|
||||
|
||||
|
||||
@ -41,36 +41,36 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
/* Tables with IIR and FIR coefficients for fractional downsamplers (123 Words) */
|
||||
silk_DWORD_ALIGN const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = {
|
||||
-20694, -13867,
|
||||
-49, 64, 17, -157, 353, -496, 163, 11047, 22205,
|
||||
-39, 6, 91, -170, 186, 23, -896, 6336, 19928,
|
||||
-19, -36, 102, -89, -24, 328, -951, 2568, 15909,
|
||||
-20694, -13867,
|
||||
-49, 64, 17, -157, 353, -496, 163, 11047, 22205,
|
||||
-39, 6, 91, -170, 186, 23, -896, 6336, 19928,
|
||||
-19, -36, 102, -89, -24, 328, -951, 2568, 15909,
|
||||
};
|
||||
|
||||
silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = {
|
||||
-14457, -14019,
|
||||
64, 128, -122, 36, 310, -768, 584, 9267, 17733,
|
||||
12, 128, 18, -142, 288, -117, -865, 4123, 14459,
|
||||
-14457, -14019,
|
||||
64, 128, -122, 36, 310, -768, 584, 9267, 17733,
|
||||
12, 128, 18, -142, 288, -117, -865, 4123, 14459,
|
||||
};
|
||||
|
||||
silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_2_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR1 / 2 ] = {
|
||||
616, -14323,
|
||||
-10, 39, 58, -46, -84, 120, 184, -315, -541, 1284, 5380, 9024,
|
||||
616, -14323,
|
||||
-10, 39, 58, -46, -84, 120, 184, -315, -541, 1284, 5380, 9024,
|
||||
};
|
||||
|
||||
silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_3_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = {
|
||||
16102, -15162,
|
||||
-13, 0, 20, 26, 5, -31, -43, -4, 65, 90, 7, -157, -248, -44, 593, 1583, 2612, 3271,
|
||||
16102, -15162,
|
||||
-13, 0, 20, 26, 5, -31, -43, -4, 65, 90, 7, -157, -248, -44, 593, 1583, 2612, 3271,
|
||||
};
|
||||
|
||||
silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_4_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = {
|
||||
22500, -15099,
|
||||
3, -14, -20, -15, 2, 25, 37, 25, -16, -71, -107, -79, 50, 292, 623, 982, 1288, 1464,
|
||||
22500, -15099,
|
||||
3, -14, -20, -15, 2, 25, 37, 25, -16, -71, -107, -79, 50, 292, 623, 982, 1288, 1464,
|
||||
};
|
||||
|
||||
silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_6_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = {
|
||||
27540, -15257,
|
||||
17, 12, 8, 1, -10, -22, -30, -32, -22, 3, 44, 100, 168, 243, 317, 381, 429, 455,
|
||||
27540, -15257,
|
||||
17, 12, 8, 1, -10, -22, -30, -32, -22, 3, 44, 100, 168, 243, 317, 381, 429, 455,
|
||||
};
|
||||
|
||||
silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ] = {
|
||||
@ -81,16 +81,16 @@ silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ] = {
|
||||
|
||||
/* Table with interplation fractions of 1/24, 3/24, 5/24, ... , 23/24 : 23/24 (46 Words) */
|
||||
silk_DWORD_ALIGN const opus_int16 silk_resampler_frac_FIR_12[ 12 ][ RESAMPLER_ORDER_FIR_12 / 2 ] = {
|
||||
{ 189, -600, 617, 30567 },
|
||||
{ 117, -159, -1070, 29704 },
|
||||
{ 52, 221, -2392, 28276 },
|
||||
{ -4, 529, -3350, 26341 },
|
||||
{ -48, 758, -3956, 23973 },
|
||||
{ -80, 905, -4235, 21254 },
|
||||
{ -99, 972, -4222, 18278 },
|
||||
{ -107, 967, -3957, 15143 },
|
||||
{ -103, 896, -3487, 11950 },
|
||||
{ -91, 773, -2865, 8798 },
|
||||
{ -71, 611, -2143, 5784 },
|
||||
{ -46, 425, -1375, 2996 },
|
||||
{ 189, -600, 617, 30567 },
|
||||
{ 117, -159, -1070, 29704 },
|
||||
{ 52, 221, -2392, 28276 },
|
||||
{ -4, 529, -3350, 26341 },
|
||||
{ -48, 758, -3956, 23973 },
|
||||
{ -80, 905, -4235, 21254 },
|
||||
{ -99, 972, -4222, 18278 },
|
||||
{ -107, 967, -3957, 15143 },
|
||||
{ -103, 896, -3487, 11950 },
|
||||
{ -91, 773, -2865, 8798 },
|
||||
{ -71, 611, -2143, 5784 },
|
||||
{ -46, 425, -1375, 2996 },
|
||||
};
|
||||
|
||||
@ -171,7 +171,7 @@ typedef struct {
|
||||
opus_int32 pitchEstimationThreshold_Q16; /* Threshold for pitch estimator */
|
||||
opus_int LTPQuantLowComplexity; /* Flag for low complexity LTP quantization */
|
||||
opus_int mu_LTP_Q9; /* Rate-distortion tradeoff in LTP quantization */
|
||||
opus_int32 sum_log_gain_Q7; /* Cumulative max prediction gain */
|
||||
opus_int32 sum_log_gain_Q7; /* Cumulative max prediction gain */
|
||||
opus_int NLSF_MSVQ_Survivors; /* Number of survivors in NLSF MSVQ */
|
||||
opus_int first_frame_after_reset; /* Flag for deactivating NLSF interpolation, pitch prediction */
|
||||
opus_int controlled_since_last_payload; /* Flag for ensuring codec_control only runs once per packet */
|
||||
|
||||
@ -64,7 +64,7 @@ extern "C"
|
||||
#define MU_LTP_QUANT_WB 0.02f
|
||||
|
||||
/* Max cumulative LTP gain */
|
||||
#define MAX_SUM_LOG_GAIN_DB 250.0f
|
||||
#define MAX_SUM_LOG_GAIN_DB 250.0f
|
||||
|
||||
/***********************/
|
||||
/* High pass filtering */
|
||||
|
||||
112
src/mlp.c
112
src/mlp.c
@ -41,36 +41,36 @@
|
||||
#if 0
|
||||
static OPUS_INLINE opus_val16 tansig_approx(opus_val32 _x) /* Q19 */
|
||||
{
|
||||
int i;
|
||||
opus_val16 xx; /* Q11 */
|
||||
/*double x, y;*/
|
||||
opus_val16 dy, yy; /* Q14 */
|
||||
/*x = 1.9073e-06*_x;*/
|
||||
if (_x>=QCONST32(8,19))
|
||||
return QCONST32(1.,14);
|
||||
if (_x<=-QCONST32(8,19))
|
||||
return -QCONST32(1.,14);
|
||||
xx = EXTRACT16(SHR32(_x, 8));
|
||||
/*i = lrint(25*x);*/
|
||||
i = SHR32(ADD32(1024,MULT16_16(25, xx)),11);
|
||||
/*x -= .04*i;*/
|
||||
xx -= EXTRACT16(SHR32(MULT16_16(20972,i),8));
|
||||
/*x = xx*(1./2048);*/
|
||||
/*y = tansig_table[250+i];*/
|
||||
yy = tansig_table[250+i];
|
||||
/*y = yy*(1./16384);*/
|
||||
dy = 16384-MULT16_16_Q14(yy,yy);
|
||||
yy = yy + MULT16_16_Q14(MULT16_16_Q11(xx,dy),(16384 - MULT16_16_Q11(yy,xx)));
|
||||
return yy;
|
||||
int i;
|
||||
opus_val16 xx; /* Q11 */
|
||||
/*double x, y;*/
|
||||
opus_val16 dy, yy; /* Q14 */
|
||||
/*x = 1.9073e-06*_x;*/
|
||||
if (_x>=QCONST32(8,19))
|
||||
return QCONST32(1.,14);
|
||||
if (_x<=-QCONST32(8,19))
|
||||
return -QCONST32(1.,14);
|
||||
xx = EXTRACT16(SHR32(_x, 8));
|
||||
/*i = lrint(25*x);*/
|
||||
i = SHR32(ADD32(1024,MULT16_16(25, xx)),11);
|
||||
/*x -= .04*i;*/
|
||||
xx -= EXTRACT16(SHR32(MULT16_16(20972,i),8));
|
||||
/*x = xx*(1./2048);*/
|
||||
/*y = tansig_table[250+i];*/
|
||||
yy = tansig_table[250+i];
|
||||
/*y = yy*(1./16384);*/
|
||||
dy = 16384-MULT16_16_Q14(yy,yy);
|
||||
yy = yy + MULT16_16_Q14(MULT16_16_Q11(xx,dy),(16384 - MULT16_16_Q11(yy,xx)));
|
||||
return yy;
|
||||
}
|
||||
#else
|
||||
/*extern const float tansig_table[501];*/
|
||||
static OPUS_INLINE float tansig_approx(float x)
|
||||
{
|
||||
int i;
|
||||
float y, dy;
|
||||
float sign=1;
|
||||
/* Tests are reversed to catch NaNs */
|
||||
int i;
|
||||
float y, dy;
|
||||
float sign=1;
|
||||
/* Tests are reversed to catch NaNs */
|
||||
if (!(x<8))
|
||||
return 1;
|
||||
if (!(x>-8))
|
||||
@ -80,43 +80,43 @@ static OPUS_INLINE float tansig_approx(float x)
|
||||
if (celt_isnan(x))
|
||||
return 0;
|
||||
#endif
|
||||
if (x<0)
|
||||
{
|
||||
x=-x;
|
||||
sign=-1;
|
||||
}
|
||||
i = (int)floor(.5f+25*x);
|
||||
x -= .04f*i;
|
||||
y = tansig_table[i];
|
||||
dy = 1-y*y;
|
||||
y = y + x*dy*(1 - y*x);
|
||||
return sign*y;
|
||||
if (x<0)
|
||||
{
|
||||
x=-x;
|
||||
sign=-1;
|
||||
}
|
||||
i = (int)floor(.5f+25*x);
|
||||
x -= .04f*i;
|
||||
y = tansig_table[i];
|
||||
dy = 1-y*y;
|
||||
y = y + x*dy*(1 - y*x);
|
||||
return sign*y;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
void mlp_process(const MLP *m, const opus_val16 *in, opus_val16 *out)
|
||||
{
|
||||
int j;
|
||||
opus_val16 hidden[MAX_NEURONS];
|
||||
const opus_val16 *W = m->weights;
|
||||
/* Copy to tmp_in */
|
||||
for (j=0;j<m->topo[1];j++)
|
||||
{
|
||||
int k;
|
||||
opus_val32 sum = SHL32(EXTEND32(*W++),8);
|
||||
for (k=0;k<m->topo[0];k++)
|
||||
sum = MAC16_16(sum, in[k],*W++);
|
||||
hidden[j] = tansig_approx(sum);
|
||||
}
|
||||
for (j=0;j<m->topo[2];j++)
|
||||
{
|
||||
int k;
|
||||
opus_val32 sum = SHL32(EXTEND32(*W++),14);
|
||||
for (k=0;k<m->topo[1];k++)
|
||||
sum = MAC16_16(sum, hidden[k], *W++);
|
||||
out[j] = tansig_approx(EXTRACT16(PSHR32(sum,17)));
|
||||
}
|
||||
int j;
|
||||
opus_val16 hidden[MAX_NEURONS];
|
||||
const opus_val16 *W = m->weights;
|
||||
/* Copy to tmp_in */
|
||||
for (j=0;j<m->topo[1];j++)
|
||||
{
|
||||
int k;
|
||||
opus_val32 sum = SHL32(EXTEND32(*W++),8);
|
||||
for (k=0;k<m->topo[0];k++)
|
||||
sum = MAC16_16(sum, in[k],*W++);
|
||||
hidden[j] = tansig_approx(sum);
|
||||
}
|
||||
for (j=0;j<m->topo[2];j++)
|
||||
{
|
||||
int k;
|
||||
opus_val32 sum = SHL32(EXTEND32(*W++),14);
|
||||
for (k=0;k<m->topo[1];k++)
|
||||
sum = MAC16_16(sum, hidden[k], *W++);
|
||||
out[j] = tansig_approx(EXTRACT16(PSHR32(sum,17)));
|
||||
}
|
||||
}
|
||||
#else
|
||||
void mlp_process(const MLP *m, const float *in, float *out)
|
||||
|
||||
@ -31,9 +31,9 @@
|
||||
#include "arch.h"
|
||||
|
||||
typedef struct {
|
||||
int layers;
|
||||
const int *topo;
|
||||
const float *weights;
|
||||
int layers;
|
||||
const int *topo;
|
||||
const float *weights;
|
||||
} MLP;
|
||||
|
||||
void mlp_process(const MLP *m, const float *in, float *out);
|
||||
|
||||
844
src/mlp_train.c
844
src/mlp_train.c
@ -39,70 +39,70 @@ int stopped = 0;
|
||||
|
||||
void handler(int sig)
|
||||
{
|
||||
stopped = 1;
|
||||
signal(sig, handler);
|
||||
stopped = 1;
|
||||
signal(sig, handler);
|
||||
}
|
||||
|
||||
MLPTrain * mlp_init(int *topo, int nbLayers, float *inputs, float *outputs, int nbSamples)
|
||||
{
|
||||
int i, j, k;
|
||||
MLPTrain *net;
|
||||
int inDim, outDim;
|
||||
net = malloc(sizeof(*net));
|
||||
net->topo = malloc(nbLayers*sizeof(net->topo[0]));
|
||||
for (i=0;i<nbLayers;i++)
|
||||
net->topo[i] = topo[i];
|
||||
inDim = topo[0];
|
||||
outDim = topo[nbLayers-1];
|
||||
net->in_rate = malloc((inDim+1)*sizeof(net->in_rate[0]));
|
||||
net->weights = malloc((nbLayers-1)*sizeof(net->weights));
|
||||
net->best_weights = malloc((nbLayers-1)*sizeof(net->weights));
|
||||
for (i=0;i<nbLayers-1;i++)
|
||||
{
|
||||
net->weights[i] = malloc((topo[i]+1)*topo[i+1]*sizeof(net->weights[0][0]));
|
||||
net->best_weights[i] = malloc((topo[i]+1)*topo[i+1]*sizeof(net->weights[0][0]));
|
||||
}
|
||||
double inMean[inDim];
|
||||
for (j=0;j<inDim;j++)
|
||||
{
|
||||
double std=0;
|
||||
inMean[j] = 0;
|
||||
for (i=0;i<nbSamples;i++)
|
||||
{
|
||||
inMean[j] += inputs[i*inDim+j];
|
||||
std += inputs[i*inDim+j]*inputs[i*inDim+j];
|
||||
}
|
||||
inMean[j] /= nbSamples;
|
||||
std /= nbSamples;
|
||||
net->in_rate[1+j] = .5/(.0001+std);
|
||||
std = std-inMean[j]*inMean[j];
|
||||
if (std<.001)
|
||||
std = .001;
|
||||
std = 1/sqrt(inDim*std);
|
||||
for (k=0;k<topo[1];k++)
|
||||
net->weights[0][k*(topo[0]+1)+j+1] = randn(std);
|
||||
}
|
||||
net->in_rate[0] = 1;
|
||||
for (j=0;j<topo[1];j++)
|
||||
{
|
||||
double sum = 0;
|
||||
for (k=0;k<inDim;k++)
|
||||
sum += inMean[k]*net->weights[0][j*(topo[0]+1)+k+1];
|
||||
net->weights[0][j*(topo[0]+1)] = -sum;
|
||||
}
|
||||
for (j=0;j<outDim;j++)
|
||||
{
|
||||
double mean = 0;
|
||||
double std;
|
||||
for (i=0;i<nbSamples;i++)
|
||||
mean += outputs[i*outDim+j];
|
||||
mean /= nbSamples;
|
||||
std = 1/sqrt(topo[nbLayers-2]);
|
||||
net->weights[nbLayers-2][j*(topo[nbLayers-2]+1)] = mean;
|
||||
for (k=0;k<topo[nbLayers-2];k++)
|
||||
net->weights[nbLayers-2][j*(topo[nbLayers-2]+1)+k+1] = randn(std);
|
||||
}
|
||||
return net;
|
||||
int i, j, k;
|
||||
MLPTrain *net;
|
||||
int inDim, outDim;
|
||||
net = malloc(sizeof(*net));
|
||||
net->topo = malloc(nbLayers*sizeof(net->topo[0]));
|
||||
for (i=0;i<nbLayers;i++)
|
||||
net->topo[i] = topo[i];
|
||||
inDim = topo[0];
|
||||
outDim = topo[nbLayers-1];
|
||||
net->in_rate = malloc((inDim+1)*sizeof(net->in_rate[0]));
|
||||
net->weights = malloc((nbLayers-1)*sizeof(net->weights));
|
||||
net->best_weights = malloc((nbLayers-1)*sizeof(net->weights));
|
||||
for (i=0;i<nbLayers-1;i++)
|
||||
{
|
||||
net->weights[i] = malloc((topo[i]+1)*topo[i+1]*sizeof(net->weights[0][0]));
|
||||
net->best_weights[i] = malloc((topo[i]+1)*topo[i+1]*sizeof(net->weights[0][0]));
|
||||
}
|
||||
double inMean[inDim];
|
||||
for (j=0;j<inDim;j++)
|
||||
{
|
||||
double std=0;
|
||||
inMean[j] = 0;
|
||||
for (i=0;i<nbSamples;i++)
|
||||
{
|
||||
inMean[j] += inputs[i*inDim+j];
|
||||
std += inputs[i*inDim+j]*inputs[i*inDim+j];
|
||||
}
|
||||
inMean[j] /= nbSamples;
|
||||
std /= nbSamples;
|
||||
net->in_rate[1+j] = .5/(.0001+std);
|
||||
std = std-inMean[j]*inMean[j];
|
||||
if (std<.001)
|
||||
std = .001;
|
||||
std = 1/sqrt(inDim*std);
|
||||
for (k=0;k<topo[1];k++)
|
||||
net->weights[0][k*(topo[0]+1)+j+1] = randn(std);
|
||||
}
|
||||
net->in_rate[0] = 1;
|
||||
for (j=0;j<topo[1];j++)
|
||||
{
|
||||
double sum = 0;
|
||||
for (k=0;k<inDim;k++)
|
||||
sum += inMean[k]*net->weights[0][j*(topo[0]+1)+k+1];
|
||||
net->weights[0][j*(topo[0]+1)] = -sum;
|
||||
}
|
||||
for (j=0;j<outDim;j++)
|
||||
{
|
||||
double mean = 0;
|
||||
double std;
|
||||
for (i=0;i<nbSamples;i++)
|
||||
mean += outputs[i*outDim+j];
|
||||
mean /= nbSamples;
|
||||
std = 1/sqrt(topo[nbLayers-2]);
|
||||
net->weights[nbLayers-2][j*(topo[nbLayers-2]+1)] = mean;
|
||||
for (k=0;k<topo[nbLayers-2];k++)
|
||||
net->weights[nbLayers-2][j*(topo[nbLayers-2]+1)+k+1] = randn(std);
|
||||
}
|
||||
return net;
|
||||
}
|
||||
|
||||
#define MAX_NEURONS 100
|
||||
@ -110,75 +110,75 @@ MLPTrain * mlp_init(int *topo, int nbLayers, float *inputs, float *outputs, int
|
||||
|
||||
double compute_gradient(MLPTrain *net, float *inputs, float *outputs, int nbSamples, double *W0_grad, double *W1_grad, double *error_rate)
|
||||
{
|
||||
int i,j;
|
||||
int s;
|
||||
int inDim, outDim, hiddenDim;
|
||||
int *topo;
|
||||
double *W0, *W1;
|
||||
double rms=0;
|
||||
int W0_size, W1_size;
|
||||
double hidden[MAX_NEURONS];
|
||||
double netOut[MAX_NEURONS];
|
||||
double error[MAX_NEURONS];
|
||||
int i,j;
|
||||
int s;
|
||||
int inDim, outDim, hiddenDim;
|
||||
int *topo;
|
||||
double *W0, *W1;
|
||||
double rms=0;
|
||||
int W0_size, W1_size;
|
||||
double hidden[MAX_NEURONS];
|
||||
double netOut[MAX_NEURONS];
|
||||
double error[MAX_NEURONS];
|
||||
|
||||
topo = net->topo;
|
||||
inDim = net->topo[0];
|
||||
hiddenDim = net->topo[1];
|
||||
outDim = net->topo[2];
|
||||
W0_size = (topo[0]+1)*topo[1];
|
||||
W1_size = (topo[1]+1)*topo[2];
|
||||
W0 = net->weights[0];
|
||||
W1 = net->weights[1];
|
||||
memset(W0_grad, 0, W0_size*sizeof(double));
|
||||
memset(W1_grad, 0, W1_size*sizeof(double));
|
||||
for (i=0;i<outDim;i++)
|
||||
netOut[i] = outputs[i];
|
||||
for (i=0;i<outDim;i++)
|
||||
error_rate[i] = 0;
|
||||
for (s=0;s<nbSamples;s++)
|
||||
{
|
||||
float *in, *out;
|
||||
in = inputs+s*inDim;
|
||||
out = outputs + s*outDim;
|
||||
for (i=0;i<hiddenDim;i++)
|
||||
{
|
||||
double sum = W0[i*(inDim+1)];
|
||||
for (j=0;j<inDim;j++)
|
||||
sum += W0[i*(inDim+1)+j+1]*in[j];
|
||||
hidden[i] = tansig_approx(sum);
|
||||
}
|
||||
for (i=0;i<outDim;i++)
|
||||
{
|
||||
double sum = W1[i*(hiddenDim+1)];
|
||||
for (j=0;j<hiddenDim;j++)
|
||||
sum += W1[i*(hiddenDim+1)+j+1]*hidden[j];
|
||||
netOut[i] = tansig_approx(sum);
|
||||
error[i] = out[i] - netOut[i];
|
||||
rms += error[i]*error[i];
|
||||
error_rate[i] += fabs(error[i])>1;
|
||||
/*error[i] = error[i]/(1+fabs(error[i]));*/
|
||||
}
|
||||
/* Back-propagate error */
|
||||
for (i=0;i<outDim;i++)
|
||||
{
|
||||
float grad = 1-netOut[i]*netOut[i];
|
||||
W1_grad[i*(hiddenDim+1)] += error[i]*grad;
|
||||
for (j=0;j<hiddenDim;j++)
|
||||
W1_grad[i*(hiddenDim+1)+j+1] += grad*error[i]*hidden[j];
|
||||
}
|
||||
for (i=0;i<hiddenDim;i++)
|
||||
{
|
||||
double grad;
|
||||
grad = 0;
|
||||
for (j=0;j<outDim;j++)
|
||||
grad += error[j]*W1[j*(hiddenDim+1)+i+1];
|
||||
grad *= 1-hidden[i]*hidden[i];
|
||||
W0_grad[i*(inDim+1)] += grad;
|
||||
for (j=0;j<inDim;j++)
|
||||
W0_grad[i*(inDim+1)+j+1] += grad*in[j];
|
||||
}
|
||||
}
|
||||
return rms;
|
||||
topo = net->topo;
|
||||
inDim = net->topo[0];
|
||||
hiddenDim = net->topo[1];
|
||||
outDim = net->topo[2];
|
||||
W0_size = (topo[0]+1)*topo[1];
|
||||
W1_size = (topo[1]+1)*topo[2];
|
||||
W0 = net->weights[0];
|
||||
W1 = net->weights[1];
|
||||
memset(W0_grad, 0, W0_size*sizeof(double));
|
||||
memset(W1_grad, 0, W1_size*sizeof(double));
|
||||
for (i=0;i<outDim;i++)
|
||||
netOut[i] = outputs[i];
|
||||
for (i=0;i<outDim;i++)
|
||||
error_rate[i] = 0;
|
||||
for (s=0;s<nbSamples;s++)
|
||||
{
|
||||
float *in, *out;
|
||||
in = inputs+s*inDim;
|
||||
out = outputs + s*outDim;
|
||||
for (i=0;i<hiddenDim;i++)
|
||||
{
|
||||
double sum = W0[i*(inDim+1)];
|
||||
for (j=0;j<inDim;j++)
|
||||
sum += W0[i*(inDim+1)+j+1]*in[j];
|
||||
hidden[i] = tansig_approx(sum);
|
||||
}
|
||||
for (i=0;i<outDim;i++)
|
||||
{
|
||||
double sum = W1[i*(hiddenDim+1)];
|
||||
for (j=0;j<hiddenDim;j++)
|
||||
sum += W1[i*(hiddenDim+1)+j+1]*hidden[j];
|
||||
netOut[i] = tansig_approx(sum);
|
||||
error[i] = out[i] - netOut[i];
|
||||
rms += error[i]*error[i];
|
||||
error_rate[i] += fabs(error[i])>1;
|
||||
/*error[i] = error[i]/(1+fabs(error[i]));*/
|
||||
}
|
||||
/* Back-propagate error */
|
||||
for (i=0;i<outDim;i++)
|
||||
{
|
||||
float grad = 1-netOut[i]*netOut[i];
|
||||
W1_grad[i*(hiddenDim+1)] += error[i]*grad;
|
||||
for (j=0;j<hiddenDim;j++)
|
||||
W1_grad[i*(hiddenDim+1)+j+1] += grad*error[i]*hidden[j];
|
||||
}
|
||||
for (i=0;i<hiddenDim;i++)
|
||||
{
|
||||
double grad;
|
||||
grad = 0;
|
||||
for (j=0;j<outDim;j++)
|
||||
grad += error[j]*W1[j*(hiddenDim+1)+i+1];
|
||||
grad *= 1-hidden[i]*hidden[i];
|
||||
W0_grad[i*(inDim+1)] += grad;
|
||||
for (j=0;j<inDim;j++)
|
||||
W0_grad[i*(inDim+1)+j+1] += grad*in[j];
|
||||
}
|
||||
}
|
||||
return rms;
|
||||
}
|
||||
|
||||
#define NB_THREADS 8
|
||||
@ -187,315 +187,315 @@ sem_t sem_begin[NB_THREADS];
|
||||
sem_t sem_end[NB_THREADS];
|
||||
|
||||
struct GradientArg {
|
||||
int id;
|
||||
int done;
|
||||
MLPTrain *net;
|
||||
float *inputs;
|
||||
float *outputs;
|
||||
int nbSamples;
|
||||
double *W0_grad;
|
||||
double *W1_grad;
|
||||
double rms;
|
||||
double error_rate[MAX_OUT];
|
||||
int id;
|
||||
int done;
|
||||
MLPTrain *net;
|
||||
float *inputs;
|
||||
float *outputs;
|
||||
int nbSamples;
|
||||
double *W0_grad;
|
||||
double *W1_grad;
|
||||
double rms;
|
||||
double error_rate[MAX_OUT];
|
||||
};
|
||||
|
||||
void *gradient_thread_process(void *_arg)
|
||||
{
|
||||
int W0_size, W1_size;
|
||||
struct GradientArg *arg = _arg;
|
||||
int *topo = arg->net->topo;
|
||||
W0_size = (topo[0]+1)*topo[1];
|
||||
W1_size = (topo[1]+1)*topo[2];
|
||||
double W0_grad[W0_size];
|
||||
double W1_grad[W1_size];
|
||||
arg->W0_grad = W0_grad;
|
||||
arg->W1_grad = W1_grad;
|
||||
while (1)
|
||||
{
|
||||
sem_wait(&sem_begin[arg->id]);
|
||||
if (arg->done)
|
||||
break;
|
||||
arg->rms = compute_gradient(arg->net, arg->inputs, arg->outputs, arg->nbSamples, arg->W0_grad, arg->W1_grad, arg->error_rate);
|
||||
sem_post(&sem_end[arg->id]);
|
||||
}
|
||||
fprintf(stderr, "done\n");
|
||||
return NULL;
|
||||
int W0_size, W1_size;
|
||||
struct GradientArg *arg = _arg;
|
||||
int *topo = arg->net->topo;
|
||||
W0_size = (topo[0]+1)*topo[1];
|
||||
W1_size = (topo[1]+1)*topo[2];
|
||||
double W0_grad[W0_size];
|
||||
double W1_grad[W1_size];
|
||||
arg->W0_grad = W0_grad;
|
||||
arg->W1_grad = W1_grad;
|
||||
while (1)
|
||||
{
|
||||
sem_wait(&sem_begin[arg->id]);
|
||||
if (arg->done)
|
||||
break;
|
||||
arg->rms = compute_gradient(arg->net, arg->inputs, arg->outputs, arg->nbSamples, arg->W0_grad, arg->W1_grad, arg->error_rate);
|
||||
sem_post(&sem_end[arg->id]);
|
||||
}
|
||||
fprintf(stderr, "done\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
float mlp_train_backprop(MLPTrain *net, float *inputs, float *outputs, int nbSamples, int nbEpoch, float rate)
|
||||
{
|
||||
int i, j;
|
||||
int e;
|
||||
float best_rms = 1e10;
|
||||
int inDim, outDim, hiddenDim;
|
||||
int *topo;
|
||||
double *W0, *W1, *best_W0, *best_W1;
|
||||
double *W0_old, *W1_old;
|
||||
double *W0_old2, *W1_old2;
|
||||
double *W0_grad, *W1_grad;
|
||||
double *W0_oldgrad, *W1_oldgrad;
|
||||
double *W0_rate, *W1_rate;
|
||||
double *best_W0_rate, *best_W1_rate;
|
||||
int W0_size, W1_size;
|
||||
topo = net->topo;
|
||||
W0_size = (topo[0]+1)*topo[1];
|
||||
W1_size = (topo[1]+1)*topo[2];
|
||||
struct GradientArg args[NB_THREADS];
|
||||
pthread_t thread[NB_THREADS];
|
||||
int samplePerPart = nbSamples/NB_THREADS;
|
||||
int count_worse=0;
|
||||
int count_retries=0;
|
||||
int i, j;
|
||||
int e;
|
||||
float best_rms = 1e10;
|
||||
int inDim, outDim, hiddenDim;
|
||||
int *topo;
|
||||
double *W0, *W1, *best_W0, *best_W1;
|
||||
double *W0_old, *W1_old;
|
||||
double *W0_old2, *W1_old2;
|
||||
double *W0_grad, *W1_grad;
|
||||
double *W0_oldgrad, *W1_oldgrad;
|
||||
double *W0_rate, *W1_rate;
|
||||
double *best_W0_rate, *best_W1_rate;
|
||||
int W0_size, W1_size;
|
||||
topo = net->topo;
|
||||
W0_size = (topo[0]+1)*topo[1];
|
||||
W1_size = (topo[1]+1)*topo[2];
|
||||
struct GradientArg args[NB_THREADS];
|
||||
pthread_t thread[NB_THREADS];
|
||||
int samplePerPart = nbSamples/NB_THREADS;
|
||||
int count_worse=0;
|
||||
int count_retries=0;
|
||||
|
||||
topo = net->topo;
|
||||
inDim = net->topo[0];
|
||||
hiddenDim = net->topo[1];
|
||||
outDim = net->topo[2];
|
||||
W0 = net->weights[0];
|
||||
W1 = net->weights[1];
|
||||
best_W0 = net->best_weights[0];
|
||||
best_W1 = net->best_weights[1];
|
||||
W0_old = malloc(W0_size*sizeof(double));
|
||||
W1_old = malloc(W1_size*sizeof(double));
|
||||
W0_old2 = malloc(W0_size*sizeof(double));
|
||||
W1_old2 = malloc(W1_size*sizeof(double));
|
||||
W0_grad = malloc(W0_size*sizeof(double));
|
||||
W1_grad = malloc(W1_size*sizeof(double));
|
||||
W0_oldgrad = malloc(W0_size*sizeof(double));
|
||||
W1_oldgrad = malloc(W1_size*sizeof(double));
|
||||
W0_rate = malloc(W0_size*sizeof(double));
|
||||
W1_rate = malloc(W1_size*sizeof(double));
|
||||
best_W0_rate = malloc(W0_size*sizeof(double));
|
||||
best_W1_rate = malloc(W1_size*sizeof(double));
|
||||
memcpy(W0_old, W0, W0_size*sizeof(double));
|
||||
memcpy(W0_old2, W0, W0_size*sizeof(double));
|
||||
memset(W0_grad, 0, W0_size*sizeof(double));
|
||||
memset(W0_oldgrad, 0, W0_size*sizeof(double));
|
||||
memcpy(W1_old, W1, W1_size*sizeof(double));
|
||||
memcpy(W1_old2, W1, W1_size*sizeof(double));
|
||||
memset(W1_grad, 0, W1_size*sizeof(double));
|
||||
memset(W1_oldgrad, 0, W1_size*sizeof(double));
|
||||
|
||||
rate /= nbSamples;
|
||||
for (i=0;i<hiddenDim;i++)
|
||||
for (j=0;j<inDim+1;j++)
|
||||
W0_rate[i*(inDim+1)+j] = rate*net->in_rate[j];
|
||||
for (i=0;i<W1_size;i++)
|
||||
W1_rate[i] = rate;
|
||||
|
||||
for (i=0;i<NB_THREADS;i++)
|
||||
{
|
||||
args[i].net = net;
|
||||
args[i].inputs = inputs+i*samplePerPart*inDim;
|
||||
args[i].outputs = outputs+i*samplePerPart*outDim;
|
||||
args[i].nbSamples = samplePerPart;
|
||||
args[i].id = i;
|
||||
args[i].done = 0;
|
||||
sem_init(&sem_begin[i], 0, 0);
|
||||
sem_init(&sem_end[i], 0, 0);
|
||||
pthread_create(&thread[i], NULL, gradient_thread_process, &args[i]);
|
||||
}
|
||||
for (e=0;e<nbEpoch;e++)
|
||||
{
|
||||
double rms=0;
|
||||
double error_rate[2] = {0,0};
|
||||
for (i=0;i<NB_THREADS;i++)
|
||||
{
|
||||
sem_post(&sem_begin[i]);
|
||||
}
|
||||
memset(W0_grad, 0, W0_size*sizeof(double));
|
||||
memset(W1_grad, 0, W1_size*sizeof(double));
|
||||
for (i=0;i<NB_THREADS;i++)
|
||||
{
|
||||
sem_wait(&sem_end[i]);
|
||||
rms += args[i].rms;
|
||||
error_rate[0] += args[i].error_rate[0];
|
||||
topo = net->topo;
|
||||
inDim = net->topo[0];
|
||||
hiddenDim = net->topo[1];
|
||||
outDim = net->topo[2];
|
||||
W0 = net->weights[0];
|
||||
W1 = net->weights[1];
|
||||
best_W0 = net->best_weights[0];
|
||||
best_W1 = net->best_weights[1];
|
||||
W0_old = malloc(W0_size*sizeof(double));
|
||||
W1_old = malloc(W1_size*sizeof(double));
|
||||
W0_old2 = malloc(W0_size*sizeof(double));
|
||||
W1_old2 = malloc(W1_size*sizeof(double));
|
||||
W0_grad = malloc(W0_size*sizeof(double));
|
||||
W1_grad = malloc(W1_size*sizeof(double));
|
||||
W0_oldgrad = malloc(W0_size*sizeof(double));
|
||||
W1_oldgrad = malloc(W1_size*sizeof(double));
|
||||
W0_rate = malloc(W0_size*sizeof(double));
|
||||
W1_rate = malloc(W1_size*sizeof(double));
|
||||
best_W0_rate = malloc(W0_size*sizeof(double));
|
||||
best_W1_rate = malloc(W1_size*sizeof(double));
|
||||
memcpy(W0_old, W0, W0_size*sizeof(double));
|
||||
memcpy(W0_old2, W0, W0_size*sizeof(double));
|
||||
memset(W0_grad, 0, W0_size*sizeof(double));
|
||||
memset(W0_oldgrad, 0, W0_size*sizeof(double));
|
||||
memcpy(W1_old, W1, W1_size*sizeof(double));
|
||||
memcpy(W1_old2, W1, W1_size*sizeof(double));
|
||||
memset(W1_grad, 0, W1_size*sizeof(double));
|
||||
memset(W1_oldgrad, 0, W1_size*sizeof(double));
|
||||
|
||||
rate /= nbSamples;
|
||||
for (i=0;i<hiddenDim;i++)
|
||||
for (j=0;j<inDim+1;j++)
|
||||
W0_rate[i*(inDim+1)+j] = rate*net->in_rate[j];
|
||||
for (i=0;i<W1_size;i++)
|
||||
W1_rate[i] = rate;
|
||||
|
||||
for (i=0;i<NB_THREADS;i++)
|
||||
{
|
||||
args[i].net = net;
|
||||
args[i].inputs = inputs+i*samplePerPart*inDim;
|
||||
args[i].outputs = outputs+i*samplePerPart*outDim;
|
||||
args[i].nbSamples = samplePerPart;
|
||||
args[i].id = i;
|
||||
args[i].done = 0;
|
||||
sem_init(&sem_begin[i], 0, 0);
|
||||
sem_init(&sem_end[i], 0, 0);
|
||||
pthread_create(&thread[i], NULL, gradient_thread_process, &args[i]);
|
||||
}
|
||||
for (e=0;e<nbEpoch;e++)
|
||||
{
|
||||
double rms=0;
|
||||
double error_rate[2] = {0,0};
|
||||
for (i=0;i<NB_THREADS;i++)
|
||||
{
|
||||
sem_post(&sem_begin[i]);
|
||||
}
|
||||
memset(W0_grad, 0, W0_size*sizeof(double));
|
||||
memset(W1_grad, 0, W1_size*sizeof(double));
|
||||
for (i=0;i<NB_THREADS;i++)
|
||||
{
|
||||
sem_wait(&sem_end[i]);
|
||||
rms += args[i].rms;
|
||||
error_rate[0] += args[i].error_rate[0];
|
||||
error_rate[1] += args[i].error_rate[1];
|
||||
for (j=0;j<W0_size;j++)
|
||||
W0_grad[j] += args[i].W0_grad[j];
|
||||
for (j=0;j<W1_size;j++)
|
||||
W1_grad[j] += args[i].W1_grad[j];
|
||||
}
|
||||
for (j=0;j<W0_size;j++)
|
||||
W0_grad[j] += args[i].W0_grad[j];
|
||||
for (j=0;j<W1_size;j++)
|
||||
W1_grad[j] += args[i].W1_grad[j];
|
||||
}
|
||||
|
||||
float mean_rate = 0, min_rate = 1e10;
|
||||
rms = (rms/(outDim*nbSamples));
|
||||
error_rate[0] = (error_rate[0]/(nbSamples));
|
||||
float mean_rate = 0, min_rate = 1e10;
|
||||
rms = (rms/(outDim*nbSamples));
|
||||
error_rate[0] = (error_rate[0]/(nbSamples));
|
||||
error_rate[1] = (error_rate[1]/(nbSamples));
|
||||
fprintf (stderr, "%f %f (%f %f) ", error_rate[0], error_rate[1], rms, best_rms);
|
||||
if (rms < best_rms)
|
||||
{
|
||||
best_rms = rms;
|
||||
for (i=0;i<W0_size;i++)
|
||||
{
|
||||
best_W0[i] = W0[i];
|
||||
best_W0_rate[i] = W0_rate[i];
|
||||
}
|
||||
for (i=0;i<W1_size;i++)
|
||||
{
|
||||
best_W1[i] = W1[i];
|
||||
best_W1_rate[i] = W1_rate[i];
|
||||
}
|
||||
count_worse=0;
|
||||
count_retries=0;
|
||||
} else {
|
||||
count_worse++;
|
||||
if (count_worse>30)
|
||||
{
|
||||
count_retries++;
|
||||
count_worse=0;
|
||||
for (i=0;i<W0_size;i++)
|
||||
{
|
||||
W0[i] = best_W0[i];
|
||||
best_W0_rate[i] *= .7;
|
||||
if (best_W0_rate[i]<1e-15) best_W0_rate[i]=1e-15;
|
||||
W0_rate[i] = best_W0_rate[i];
|
||||
W0_grad[i] = 0;
|
||||
}
|
||||
for (i=0;i<W1_size;i++)
|
||||
{
|
||||
W1[i] = best_W1[i];
|
||||
best_W1_rate[i] *= .8;
|
||||
if (best_W1_rate[i]<1e-15) best_W1_rate[i]=1e-15;
|
||||
W1_rate[i] = best_W1_rate[i];
|
||||
W1_grad[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count_retries>10)
|
||||
break;
|
||||
for (i=0;i<W0_size;i++)
|
||||
{
|
||||
if (W0_oldgrad[i]*W0_grad[i] > 0)
|
||||
W0_rate[i] *= 1.01;
|
||||
else if (W0_oldgrad[i]*W0_grad[i] < 0)
|
||||
W0_rate[i] *= .9;
|
||||
mean_rate += W0_rate[i];
|
||||
if (W0_rate[i] < min_rate)
|
||||
min_rate = W0_rate[i];
|
||||
if (W0_rate[i] < 1e-15)
|
||||
W0_rate[i] = 1e-15;
|
||||
/*if (W0_rate[i] > .01)
|
||||
W0_rate[i] = .01;*/
|
||||
W0_oldgrad[i] = W0_grad[i];
|
||||
W0_old2[i] = W0_old[i];
|
||||
W0_old[i] = W0[i];
|
||||
W0[i] += W0_grad[i]*W0_rate[i];
|
||||
}
|
||||
for (i=0;i<W1_size;i++)
|
||||
{
|
||||
if (W1_oldgrad[i]*W1_grad[i] > 0)
|
||||
W1_rate[i] *= 1.01;
|
||||
else if (W1_oldgrad[i]*W1_grad[i] < 0)
|
||||
W1_rate[i] *= .9;
|
||||
mean_rate += W1_rate[i];
|
||||
if (W1_rate[i] < min_rate)
|
||||
min_rate = W1_rate[i];
|
||||
if (W1_rate[i] < 1e-15)
|
||||
W1_rate[i] = 1e-15;
|
||||
W1_oldgrad[i] = W1_grad[i];
|
||||
W1_old2[i] = W1_old[i];
|
||||
W1_old[i] = W1[i];
|
||||
W1[i] += W1_grad[i]*W1_rate[i];
|
||||
}
|
||||
mean_rate /= (topo[0]+1)*topo[1] + (topo[1]+1)*topo[2];
|
||||
fprintf (stderr, "%g %d", mean_rate, e);
|
||||
if (count_retries)
|
||||
fprintf(stderr, " %d", count_retries);
|
||||
fprintf(stderr, "\n");
|
||||
if (stopped)
|
||||
break;
|
||||
}
|
||||
for (i=0;i<NB_THREADS;i++)
|
||||
{
|
||||
args[i].done = 1;
|
||||
sem_post(&sem_begin[i]);
|
||||
pthread_join(thread[i], NULL);
|
||||
fprintf (stderr, "joined %d\n", i);
|
||||
}
|
||||
free(W0_old);
|
||||
free(W1_old);
|
||||
free(W0_grad);
|
||||
free(W1_grad);
|
||||
free(W0_rate);
|
||||
free(W1_rate);
|
||||
return best_rms;
|
||||
fprintf (stderr, "%f %f (%f %f) ", error_rate[0], error_rate[1], rms, best_rms);
|
||||
if (rms < best_rms)
|
||||
{
|
||||
best_rms = rms;
|
||||
for (i=0;i<W0_size;i++)
|
||||
{
|
||||
best_W0[i] = W0[i];
|
||||
best_W0_rate[i] = W0_rate[i];
|
||||
}
|
||||
for (i=0;i<W1_size;i++)
|
||||
{
|
||||
best_W1[i] = W1[i];
|
||||
best_W1_rate[i] = W1_rate[i];
|
||||
}
|
||||
count_worse=0;
|
||||
count_retries=0;
|
||||
} else {
|
||||
count_worse++;
|
||||
if (count_worse>30)
|
||||
{
|
||||
count_retries++;
|
||||
count_worse=0;
|
||||
for (i=0;i<W0_size;i++)
|
||||
{
|
||||
W0[i] = best_W0[i];
|
||||
best_W0_rate[i] *= .7;
|
||||
if (best_W0_rate[i]<1e-15) best_W0_rate[i]=1e-15;
|
||||
W0_rate[i] = best_W0_rate[i];
|
||||
W0_grad[i] = 0;
|
||||
}
|
||||
for (i=0;i<W1_size;i++)
|
||||
{
|
||||
W1[i] = best_W1[i];
|
||||
best_W1_rate[i] *= .8;
|
||||
if (best_W1_rate[i]<1e-15) best_W1_rate[i]=1e-15;
|
||||
W1_rate[i] = best_W1_rate[i];
|
||||
W1_grad[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count_retries>10)
|
||||
break;
|
||||
for (i=0;i<W0_size;i++)
|
||||
{
|
||||
if (W0_oldgrad[i]*W0_grad[i] > 0)
|
||||
W0_rate[i] *= 1.01;
|
||||
else if (W0_oldgrad[i]*W0_grad[i] < 0)
|
||||
W0_rate[i] *= .9;
|
||||
mean_rate += W0_rate[i];
|
||||
if (W0_rate[i] < min_rate)
|
||||
min_rate = W0_rate[i];
|
||||
if (W0_rate[i] < 1e-15)
|
||||
W0_rate[i] = 1e-15;
|
||||
/*if (W0_rate[i] > .01)
|
||||
W0_rate[i] = .01;*/
|
||||
W0_oldgrad[i] = W0_grad[i];
|
||||
W0_old2[i] = W0_old[i];
|
||||
W0_old[i] = W0[i];
|
||||
W0[i] += W0_grad[i]*W0_rate[i];
|
||||
}
|
||||
for (i=0;i<W1_size;i++)
|
||||
{
|
||||
if (W1_oldgrad[i]*W1_grad[i] > 0)
|
||||
W1_rate[i] *= 1.01;
|
||||
else if (W1_oldgrad[i]*W1_grad[i] < 0)
|
||||
W1_rate[i] *= .9;
|
||||
mean_rate += W1_rate[i];
|
||||
if (W1_rate[i] < min_rate)
|
||||
min_rate = W1_rate[i];
|
||||
if (W1_rate[i] < 1e-15)
|
||||
W1_rate[i] = 1e-15;
|
||||
W1_oldgrad[i] = W1_grad[i];
|
||||
W1_old2[i] = W1_old[i];
|
||||
W1_old[i] = W1[i];
|
||||
W1[i] += W1_grad[i]*W1_rate[i];
|
||||
}
|
||||
mean_rate /= (topo[0]+1)*topo[1] + (topo[1]+1)*topo[2];
|
||||
fprintf (stderr, "%g %d", mean_rate, e);
|
||||
if (count_retries)
|
||||
fprintf(stderr, " %d", count_retries);
|
||||
fprintf(stderr, "\n");
|
||||
if (stopped)
|
||||
break;
|
||||
}
|
||||
for (i=0;i<NB_THREADS;i++)
|
||||
{
|
||||
args[i].done = 1;
|
||||
sem_post(&sem_begin[i]);
|
||||
pthread_join(thread[i], NULL);
|
||||
fprintf (stderr, "joined %d\n", i);
|
||||
}
|
||||
free(W0_old);
|
||||
free(W1_old);
|
||||
free(W0_grad);
|
||||
free(W1_grad);
|
||||
free(W0_rate);
|
||||
free(W1_rate);
|
||||
return best_rms;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i, j;
|
||||
int nbInputs;
|
||||
int nbOutputs;
|
||||
int nbHidden;
|
||||
int nbSamples;
|
||||
int nbEpoch;
|
||||
int nbRealInputs;
|
||||
unsigned int seed;
|
||||
int ret;
|
||||
float rms;
|
||||
float *inputs;
|
||||
float *outputs;
|
||||
if (argc!=6)
|
||||
{
|
||||
fprintf (stderr, "usage: mlp_train <inputs> <hidden> <outputs> <nb samples> <nb epoch>\n");
|
||||
return 1;
|
||||
}
|
||||
nbInputs = atoi(argv[1]);
|
||||
nbHidden = atoi(argv[2]);
|
||||
nbOutputs = atoi(argv[3]);
|
||||
nbSamples = atoi(argv[4]);
|
||||
nbEpoch = atoi(argv[5]);
|
||||
nbRealInputs = nbInputs;
|
||||
inputs = malloc(nbInputs*nbSamples*sizeof(*inputs));
|
||||
outputs = malloc(nbOutputs*nbSamples*sizeof(*outputs));
|
||||
|
||||
seed = time(NULL);
|
||||
/*seed = 1361480659;*/
|
||||
fprintf (stderr, "Seed is %u\n", seed);
|
||||
srand(seed);
|
||||
build_tansig_table();
|
||||
signal(SIGTERM, handler);
|
||||
signal(SIGINT, handler);
|
||||
signal(SIGHUP, handler);
|
||||
for (i=0;i<nbSamples;i++)
|
||||
{
|
||||
for (j=0;j<nbRealInputs;j++)
|
||||
ret = scanf(" %f", &inputs[i*nbInputs+j]);
|
||||
for (j=0;j<nbOutputs;j++)
|
||||
ret = scanf(" %f", &outputs[i*nbOutputs+j]);
|
||||
if (feof(stdin))
|
||||
{
|
||||
nbSamples = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int topo[3] = {nbInputs, nbHidden, nbOutputs};
|
||||
MLPTrain *net;
|
||||
int i, j;
|
||||
int nbInputs;
|
||||
int nbOutputs;
|
||||
int nbHidden;
|
||||
int nbSamples;
|
||||
int nbEpoch;
|
||||
int nbRealInputs;
|
||||
unsigned int seed;
|
||||
int ret;
|
||||
float rms;
|
||||
float *inputs;
|
||||
float *outputs;
|
||||
if (argc!=6)
|
||||
{
|
||||
fprintf (stderr, "usage: mlp_train <inputs> <hidden> <outputs> <nb samples> <nb epoch>\n");
|
||||
return 1;
|
||||
}
|
||||
nbInputs = atoi(argv[1]);
|
||||
nbHidden = atoi(argv[2]);
|
||||
nbOutputs = atoi(argv[3]);
|
||||
nbSamples = atoi(argv[4]);
|
||||
nbEpoch = atoi(argv[5]);
|
||||
nbRealInputs = nbInputs;
|
||||
inputs = malloc(nbInputs*nbSamples*sizeof(*inputs));
|
||||
outputs = malloc(nbOutputs*nbSamples*sizeof(*outputs));
|
||||
|
||||
fprintf (stderr, "Got %d samples\n", nbSamples);
|
||||
net = mlp_init(topo, 3, inputs, outputs, nbSamples);
|
||||
rms = mlp_train_backprop(net, inputs, outputs, nbSamples, nbEpoch, 1);
|
||||
printf ("#include \"mlp.h\"\n\n");
|
||||
printf ("/* RMS error was %f, seed was %u */\n\n", rms, seed);
|
||||
printf ("static const float weights[%d] = {\n", (topo[0]+1)*topo[1] + (topo[1]+1)*topo[2]);
|
||||
printf ("\n/* hidden layer */\n");
|
||||
for (i=0;i<(topo[0]+1)*topo[1];i++)
|
||||
{
|
||||
printf ("%gf, ", net->weights[0][i]);
|
||||
if (i%5==4)
|
||||
printf("\n");
|
||||
}
|
||||
printf ("\n/* output layer */\n");
|
||||
for (i=0;i<(topo[1]+1)*topo[2];i++)
|
||||
{
|
||||
printf ("%g, ", net->weights[1][i]);
|
||||
if (i%5==4)
|
||||
printf("\n");
|
||||
}
|
||||
printf ("};\n\n");
|
||||
printf ("static const int topo[3] = {%d, %d, %d};\n\n", topo[0], topo[1], topo[2]);
|
||||
printf ("const MLP net = {\n");
|
||||
printf ("\t3,\n");
|
||||
printf ("\ttopo,\n");
|
||||
printf ("\tweights\n};\n");
|
||||
return 0;
|
||||
seed = time(NULL);
|
||||
/*seed = 1361480659;*/
|
||||
fprintf (stderr, "Seed is %u\n", seed);
|
||||
srand(seed);
|
||||
build_tansig_table();
|
||||
signal(SIGTERM, handler);
|
||||
signal(SIGINT, handler);
|
||||
signal(SIGHUP, handler);
|
||||
for (i=0;i<nbSamples;i++)
|
||||
{
|
||||
for (j=0;j<nbRealInputs;j++)
|
||||
ret = scanf(" %f", &inputs[i*nbInputs+j]);
|
||||
for (j=0;j<nbOutputs;j++)
|
||||
ret = scanf(" %f", &outputs[i*nbOutputs+j]);
|
||||
if (feof(stdin))
|
||||
{
|
||||
nbSamples = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int topo[3] = {nbInputs, nbHidden, nbOutputs};
|
||||
MLPTrain *net;
|
||||
|
||||
fprintf (stderr, "Got %d samples\n", nbSamples);
|
||||
net = mlp_init(topo, 3, inputs, outputs, nbSamples);
|
||||
rms = mlp_train_backprop(net, inputs, outputs, nbSamples, nbEpoch, 1);
|
||||
printf ("#include \"mlp.h\"\n\n");
|
||||
printf ("/* RMS error was %f, seed was %u */\n\n", rms, seed);
|
||||
printf ("static const float weights[%d] = {\n", (topo[0]+1)*topo[1] + (topo[1]+1)*topo[2]);
|
||||
printf ("\n/* hidden layer */\n");
|
||||
for (i=0;i<(topo[0]+1)*topo[1];i++)
|
||||
{
|
||||
printf ("%gf, ", net->weights[0][i]);
|
||||
if (i%5==4)
|
||||
printf("\n");
|
||||
}
|
||||
printf ("\n/* output layer */\n");
|
||||
for (i=0;i<(topo[1]+1)*topo[2];i++)
|
||||
{
|
||||
printf ("%g, ", net->weights[1][i]);
|
||||
if (i%5==4)
|
||||
printf("\n");
|
||||
}
|
||||
printf ("};\n\n");
|
||||
printf ("static const int topo[3] = {%d, %d, %d};\n\n", topo[0], topo[1], topo[2]);
|
||||
printf ("const MLP net = {\n");
|
||||
printf ("\t3,\n");
|
||||
printf ("\ttopo,\n");
|
||||
printf ("\tweights\n};\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -32,31 +32,31 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
double tansig_table[501];
|
||||
static inline double tansig_double(double x)
|
||||
static inline double tansig_double(double x)
|
||||
{
|
||||
return 2./(1.+exp(-2.*x)) - 1.;
|
||||
return 2./(1.+exp(-2.*x)) - 1.;
|
||||
}
|
||||
static inline void build_tansig_table()
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<501;i++)
|
||||
tansig_table[i] = tansig_double(.04*(i-250));
|
||||
int i;
|
||||
for (i=0;i<501;i++)
|
||||
tansig_table[i] = tansig_double(.04*(i-250));
|
||||
}
|
||||
|
||||
static inline double tansig_approx(double x)
|
||||
{
|
||||
int i;
|
||||
double y, dy;
|
||||
if (x>=10)
|
||||
return 1;
|
||||
if (x<=-10)
|
||||
return -1;
|
||||
i = lrint(25*x);
|
||||
x -= .04*i;
|
||||
y = tansig_table[250+i];
|
||||
dy = 1-y*y;
|
||||
y = y + x*dy*(1 - y*x);
|
||||
return y;
|
||||
int i;
|
||||
double y, dy;
|
||||
if (x>=10)
|
||||
return 1;
|
||||
if (x<=-10)
|
||||
return -1;
|
||||
i = lrint(25*x);
|
||||
x -= .04*i;
|
||||
y = tansig_table[250+i];
|
||||
dy = 1-y*y;
|
||||
y = y + x*dy*(1 - y*x);
|
||||
return y;
|
||||
}
|
||||
|
||||
inline float randn(float sd)
|
||||
@ -75,11 +75,11 @@ inline float randn(float sd)
|
||||
|
||||
|
||||
typedef struct {
|
||||
int layers;
|
||||
int *topo;
|
||||
double **weights;
|
||||
double **best_weights;
|
||||
double *in_rate;
|
||||
int layers;
|
||||
int *topo;
|
||||
double **weights;
|
||||
double **best_weights;
|
||||
double *in_rate;
|
||||
} MLPTrain;
|
||||
|
||||
|
||||
|
||||
@ -232,7 +232,7 @@ int opus_encoder_init(OpusEncoder* st, opus_int32 Fs, int channels, int applicat
|
||||
st->lsb_depth = 24;
|
||||
st->variable_duration = OPUS_FRAMESIZE_ARG;
|
||||
|
||||
/* Delay compensation of 4 ms (2.5 ms for SILK's extra look-ahead
|
||||
/* Delay compensation of 4 ms (2.5 ms for SILK's extra look-ahead
|
||||
+ 1.5 ms for SILK resamplers and stereo prediction) */
|
||||
st->delay_compensation = st->Fs/250;
|
||||
|
||||
@ -2125,7 +2125,7 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
|
||||
case OPUS_SET_MAX_BANDWIDTH_REQUEST:
|
||||
{
|
||||
opus_int32 value = va_arg(ap, opus_int32);
|
||||
if (value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND)
|
||||
if (value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND)
|
||||
{
|
||||
goto bad_arg;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user