summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Marc Valin <jmvalin@jmvalin.ca>2012-12-20 00:23:01 -0500
committerJean-Marc Valin <jmvalin@jmvalin.ca>2012-12-20 00:23:01 -0500
commit94b81ea9f3ed77e90d10e9c3f78fc7c7901b6e6d (patch)
tree1ea6466c27986e0b08e9a9901ac7ac5cd4bc8dbe
parentbfd66aa3ab520649ec43eb30742eae68e9676b42 (diff)
downloadopus-exp_analysis9.tar.gz
Making multistream variable duration work for both the float and int APIexp_analysis9
-rw-r--r--src/opus_encoder.c45
-rw-r--r--src/opus_multistream_encoder.c9
-rw-r--r--src/opus_private.h7
3 files changed, 45 insertions, 16 deletions
diff --git a/src/opus_encoder.c b/src/opus_encoder.c
index 87178105..7560f712 100644
--- a/src/opus_encoder.c
+++ b/src/opus_encoder.c
@@ -662,11 +662,36 @@ static int transient_viterbi(const float *E, const float *E_1, int N, int frame_
return best_state;
}
+void downmix_float(const void *_x, float *sub, int subframe, int i, int C)
+{
+ const float *x;
+ int c, j;
+ x = (const float *)_x;
+ for (j=0;j<subframe;j++)
+ sub[j] = x[(subframe*i+j)*C];
+ for (c=1;c<C;c++)
+ for (j=0;j<subframe;j++)
+ sub[j] += x[(subframe*i+j)*C+c];
+}
+
+void downmix_int(const void *_x, float *sub, int subframe, int i, int C)
+{
+ const opus_int16 *x;
+ int c, j;
+ x = (const opus_int16 *)_x;
+ for (j=0;j<subframe;j++)
+ sub[j] = x[(subframe*i+j)*C];
+ for (c=1;c<C;c++)
+ for (j=0;j<subframe;j++)
+ sub[j] += x[(subframe*i+j)*C+c];
+}
+
int optimize_framesize(const opus_val16 *x, int len, int C, opus_int32 Fs,
- int bitrate, opus_val16 tonality, opus_val32 *mem, int buffering)
+ int bitrate, opus_val16 tonality, opus_val32 *mem, int buffering,
+ downmix_func downmix)
{
int N;
- int i, c;
+ int i;
float e[MAX_DYNAMIC_FRAMESIZE+4];
float e_1[MAX_DYNAMIC_FRAMESIZE+3];
float memx;
@@ -697,8 +722,6 @@ int optimize_framesize(const opus_val16 *x, int len, int C, opus_int32 Fs,
}
N=IMIN(len/subframe, MAX_DYNAMIC_FRAMESIZE);
memx = x[0];
- for (c=1;c<C;c++)
- memx += x[c];
for (i=0;i<N;i++)
{
float tmp;
@@ -706,12 +729,9 @@ int optimize_framesize(const opus_val16 *x, int len, int C, opus_int32 Fs,
int j;
tmp=EPSILON;
- for (j=0;j<subframe;j++)
- sub[j] = x[(subframe*i+j)*C];
- for (c=1;c<C;c++)
- for (j=0;j<subframe;j++)
- sub[j] += x[(subframe*i+j)*C+c];
-
+ downmix(x, sub, subframe, i, C);
+ if (i==0)
+ memx = sub[0];
for (j=0;j<subframe;j++)
{
tmpx = sub[j];
@@ -808,7 +828,7 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s
int LM = 3;
#ifndef FIXED_POINT
LM = optimize_framesize(pcm, frame_size, st->channels, st->Fs, st->bitrate_bps,
- st->analysis.prev_tonality, st->subframe_mem, delay_compensation);
+ st->analysis.prev_tonality, st->subframe_mem, delay_compensation, downmix_float);
#endif
while ((st->Fs/400<<LM)>frame_size)
LM--;
@@ -1156,6 +1176,7 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s
RESTORE_STACK;
return ret;
}
+#ifndef FIXED_POINT
/* Perform analysis for 40-60 ms frames */
if (perform_analysis && frame_size > st->Fs/50)
{
@@ -1164,7 +1185,7 @@ opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_s
tonality_analysis(&st->analysis, &analysis_info, celt_enc, pcm+i*(st->Fs/100)*st->channels, 480, st->channels);
st->voice_ratio = (int)floor(.5+100*(1-analysis_info.music_prob));
}
-
+#endif
curr_bandwidth = st->bandwidth;
/* Chooses the appropriate mode for speech
diff --git a/src/opus_multistream_encoder.c b/src/opus_multistream_encoder.c
index c2b47a31..bdd00fbf 100644
--- a/src/opus_multistream_encoder.c
+++ b/src/opus_multistream_encoder.c
@@ -189,6 +189,9 @@ static int opus_multistream_encode_native
int frame_size,
unsigned char *data,
opus_int32 max_data_bytes
+#ifndef FIXED_POINT
+ , downmix_func downmix
+#endif
)
{
opus_int32 Fs;
@@ -225,7 +228,7 @@ static int opus_multistream_encode_native
delay_compensation -= Fs/400;
#ifndef FIXED_POINT
LM = optimize_framesize(pcm, frame_size, channels, Fs, st->bitrate_bps,
- 0.f, st->subframe_mem, delay_compensation);
+ 0.f, st->subframe_mem, delay_compensation, downmix);
#endif
while ((Fs/400<<LM)>frame_size)
LM--;
@@ -414,7 +417,7 @@ int opus_multistream_encode_float
)
{
return opus_multistream_encode_native(st, opus_copy_channel_in_float,
- pcm, frame_size, data, max_data_bytes);
+ pcm, frame_size, data, max_data_bytes, downmix_float);
}
int opus_multistream_encode(
@@ -426,7 +429,7 @@ int opus_multistream_encode(
)
{
return opus_multistream_encode_native(st, opus_copy_channel_in_short,
- pcm, frame_size, data, max_data_bytes);
+ pcm, frame_size, data, max_data_bytes, downmix_int);
}
#endif
diff --git a/src/opus_private.h b/src/opus_private.h
index 60fbf3ab..58aa92e2 100644
--- a/src/opus_private.h
+++ b/src/opus_private.h
@@ -81,8 +81,13 @@ int get_mono_channel(const ChannelLayout *layout, int stream_id, int prev);
#define OPUS_SET_FORCE_MODE_REQUEST 11002
#define OPUS_SET_FORCE_MODE(x) OPUS_SET_FORCE_MODE_REQUEST, __opus_check_int(x)
+typedef void (*downmix_func)(const void *, float *, int, int, int);
+void downmix_float(const void *_x, float *sub, int subframe, int i, int C);
+void downmix_int(const void *_x, float *sub, int subframe, int i, int C);
+
int optimize_framesize(const opus_val16 *x, int len, int C, opus_int32 Fs,
- int bitrate, opus_val16 tonality, opus_val32 *mem, int buffering);
+ int bitrate, opus_val16 tonality, opus_val32 *mem, int buffering,
+ void (*downmix)(const void *, float *, int, int, int));
int encode_size(int size, unsigned char *data);