splitting encoder config in terms of application and signal type
This commit is contained in:
parent
541df0a97e
commit
00cb6f7ab4
4 changed files with 69 additions and 19 deletions
17
src/opus.h
17
src/opus.h
|
@ -65,8 +65,12 @@ extern "C" {
|
||||||
|
|
||||||
#define OPUS_BITRATE_AUTO -1
|
#define OPUS_BITRATE_AUTO -1
|
||||||
|
|
||||||
#define OPUS_MODE_VOICE 2000
|
#define OPUS_APPLICATION_VOIP 2000
|
||||||
#define OPUS_MODE_AUDIO 2001
|
#define OPUS_APPLICATION_AUDIO 2001
|
||||||
|
|
||||||
|
#define OPUS_SIGNAL_AUTO 3000
|
||||||
|
#define OPUS_SIGNAL_VOICE 3001
|
||||||
|
#define OPUS_SIGNAL_MUSIC 3002
|
||||||
|
|
||||||
#define MODE_SILK_ONLY 1000
|
#define MODE_SILK_ONLY 1000
|
||||||
#define MODE_HYBRID 1001
|
#define MODE_HYBRID 1001
|
||||||
|
@ -136,6 +140,11 @@ extern "C" {
|
||||||
#define OPUS_GET_FORCE_MONO_REQUEST 23
|
#define OPUS_GET_FORCE_MONO_REQUEST 23
|
||||||
#define OPUS_GET_FORCE_MONO(x) OPUS_GET_FORCE_MONO_REQUEST, __check_int_ptr(x)
|
#define OPUS_GET_FORCE_MONO(x) OPUS_GET_FORCE_MONO_REQUEST, __check_int_ptr(x)
|
||||||
|
|
||||||
|
#define OPUS_SET_SIGNAL_REQUEST 24
|
||||||
|
#define OPUS_SET_SIGNAL(x) OPUS_SET_SIGNAL_REQUEST, __check_int(x)
|
||||||
|
#define OPUS_GET_SIGNAL_REQUEST 25
|
||||||
|
#define OPUS_GET_SIGNAL(x) OPUS_GET_SIGNAL_REQUEST, __check_int_ptr(x)
|
||||||
|
|
||||||
typedef struct OpusEncoder OpusEncoder;
|
typedef struct OpusEncoder OpusEncoder;
|
||||||
typedef struct OpusDecoder OpusDecoder;
|
typedef struct OpusDecoder OpusDecoder;
|
||||||
|
|
||||||
|
@ -155,14 +164,14 @@ typedef struct OpusDecoder OpusDecoder;
|
||||||
OPUS_EXPORT OpusEncoder *opus_encoder_create(
|
OPUS_EXPORT OpusEncoder *opus_encoder_create(
|
||||||
int Fs, /* Sampling rate of input signal (Hz) */
|
int Fs, /* Sampling rate of input signal (Hz) */
|
||||||
int channels, /* Number of channels (1/2) in input signal */
|
int channels, /* Number of channels (1/2) in input signal */
|
||||||
int mode /* Coding mode (OPUS_MODE_VOICE/OPUS_MODE_AUDIO) */
|
int application /* Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO) */
|
||||||
);
|
);
|
||||||
|
|
||||||
OPUS_EXPORT OpusEncoder *opus_encoder_init(
|
OPUS_EXPORT OpusEncoder *opus_encoder_init(
|
||||||
OpusEncoder *st, /* Encoder state */
|
OpusEncoder *st, /* Encoder state */
|
||||||
int Fs, /* Sampling rate of input signal (Hz) */
|
int Fs, /* Sampling rate of input signal (Hz) */
|
||||||
int channels, /* Number of channels (1/2) in input signal */
|
int channels, /* Number of channels (1/2) in input signal */
|
||||||
int mode /* Coding mode (OPUS_MODE_VOICE/OPUS_MODE_AUDIO) */
|
int application /* Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO) */
|
||||||
);
|
);
|
||||||
|
|
||||||
/* returns length of data payload (in bytes) */
|
/* returns length of data payload (in bytes) */
|
||||||
|
|
|
@ -75,7 +75,7 @@ int opus_encoder_get_size(int channels)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OpusEncoder *opus_encoder_init(OpusEncoder* st, int Fs, int channels, int mode)
|
OpusEncoder *opus_encoder_init(OpusEncoder* st, int Fs, int channels, int application)
|
||||||
{
|
{
|
||||||
void *silk_enc;
|
void *silk_enc;
|
||||||
CELTEncoder *celt_enc;
|
CELTEncoder *celt_enc;
|
||||||
|
@ -131,7 +131,8 @@ OpusEncoder *opus_encoder_init(OpusEncoder* st, int Fs, int channels, int mode)
|
||||||
st->use_vbr = 0;
|
st->use_vbr = 0;
|
||||||
st->user_bitrate_bps = OPUS_BITRATE_AUTO;
|
st->user_bitrate_bps = OPUS_BITRATE_AUTO;
|
||||||
st->bitrate_bps = 3000+Fs*channels;
|
st->bitrate_bps = 3000+Fs*channels;
|
||||||
st->user_mode = mode;
|
st->user_mode = application;
|
||||||
|
st->signal_type = OPUS_SIGNAL_AUTO;
|
||||||
st->user_bandwidth = OPUS_BANDWIDTH_AUTO;
|
st->user_bandwidth = OPUS_BANDWIDTH_AUTO;
|
||||||
st->voice_ratio = 90;
|
st->voice_ratio = 90;
|
||||||
st->first = 1;
|
st->first = 1;
|
||||||
|
@ -209,19 +210,46 @@ int opus_encode(OpusEncoder *st, const short *pcm, int frame_size,
|
||||||
/* Equivalent bit-rate for mono */
|
/* Equivalent bit-rate for mono */
|
||||||
mono_rate = st->bitrate_bps;
|
mono_rate = st->bitrate_bps;
|
||||||
if (st->stream_channels==2)
|
if (st->stream_channels==2)
|
||||||
mono_rate = (mono_rate+10000)/2;
|
mono_rate = 2*mono_rate/3;
|
||||||
/* Compensate for smaller frame sizes assuming an equivalent overhead
|
/* Compensate for smaller frame sizes assuming an equivalent overhead
|
||||||
of 60 bits/frame */
|
of 60 bits/frame */
|
||||||
mono_rate -= 60*(st->Fs/frame_size - 50);
|
mono_rate -= 60*(st->Fs/frame_size - 50);
|
||||||
|
|
||||||
/* Mode selection */
|
/* Mode selection depending on application and signal type */
|
||||||
if (st->user_mode==OPUS_MODE_VOICE)
|
if (st->user_mode==OPUS_APPLICATION_VOIP)
|
||||||
{
|
{
|
||||||
st->mode = MODE_SILK_ONLY;
|
celt_int32 threshold = 20000;
|
||||||
} else {/* OPUS_AUDIO_MODE */
|
/* Hysteresis */
|
||||||
st->mode = MODE_CELT_ONLY;
|
if (st->prev_mode == MODE_CELT_ONLY)
|
||||||
}
|
threshold -= 4000;
|
||||||
|
else if (st->prev_mode>0)
|
||||||
|
threshold += 4000;
|
||||||
|
|
||||||
|
/* OPUS_APPLICATION_VOIP defaults to MODE_SILK_ONLY */
|
||||||
|
if (st->signal_type == OPUS_SIGNAL_MUSIC && mono_rate > threshold)
|
||||||
|
st->mode = MODE_CELT_ONLY;
|
||||||
|
else
|
||||||
|
st->mode = MODE_SILK_ONLY;
|
||||||
|
} else {/* OPUS_APPLICATION_AUDIO */
|
||||||
|
celt_int32 threshold;
|
||||||
|
/* SILK/CELT threshold is higher for voice than for music */
|
||||||
|
threshold = 36000;
|
||||||
|
if (st->signal_type == OPUS_SIGNAL_MUSIC)
|
||||||
|
threshold -= 20000;
|
||||||
|
else if (st->signal_type == OPUS_SIGNAL_VOICE)
|
||||||
|
threshold += 8000;
|
||||||
|
|
||||||
|
/* Hysteresis */
|
||||||
|
if (st->prev_mode == MODE_CELT_ONLY)
|
||||||
|
threshold -= 4000;
|
||||||
|
else if (st->prev_mode>0)
|
||||||
|
threshold += 4000;
|
||||||
|
|
||||||
|
if (mono_rate>threshold)
|
||||||
|
st->mode = MODE_CELT_ONLY;
|
||||||
|
else
|
||||||
|
st->mode = MODE_SILK_ONLY;
|
||||||
|
}
|
||||||
/* Automatic (rate-dependent) bandwidth selection */
|
/* Automatic (rate-dependent) bandwidth selection */
|
||||||
if (st->mode == MODE_CELT_ONLY || st->first || st->silk_mode.allowBandwidthSwitch)
|
if (st->mode == MODE_CELT_ONLY || st->first || st->silk_mode.allowBandwidthSwitch)
|
||||||
{
|
{
|
||||||
|
@ -753,6 +781,18 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
|
||||||
*value = st->vbr_constraint;
|
*value = st->vbr_constraint;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case OPUS_SET_SIGNAL_REQUEST:
|
||||||
|
{
|
||||||
|
int value = va_arg(ap, int);
|
||||||
|
st->signal_type = value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OPUS_GET_SIGNAL_REQUEST:
|
||||||
|
{
|
||||||
|
int *value = va_arg(ap, int*);
|
||||||
|
*value = st->signal_type;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);
|
fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -47,6 +47,7 @@ struct OpusEncoder {
|
||||||
int mode;
|
int mode;
|
||||||
int user_mode;
|
int user_mode;
|
||||||
int prev_mode;
|
int prev_mode;
|
||||||
|
int signal_type;
|
||||||
int bandwidth;
|
int bandwidth;
|
||||||
int user_bandwidth;
|
int user_bandwidth;
|
||||||
int voice_ratio;
|
int voice_ratio;
|
||||||
|
|
|
@ -42,9 +42,9 @@
|
||||||
|
|
||||||
void print_usage( char* argv[] )
|
void print_usage( char* argv[] )
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Usage: %s <mode (0/1)> <sampling rate (Hz)> <channels (1/2)> "
|
fprintf(stderr, "Usage: %s <application (0/1)> <sampling rate (Hz)> <channels (1/2)> "
|
||||||
"<bits per second> [options] <input> <output>\n\n", argv[0]);
|
"<bits per second> [options] <input> <output>\n\n", argv[0]);
|
||||||
fprintf(stderr, "mode: 0 for voice, 1 for audio:\n" );
|
fprintf(stderr, "mode: 0 for VoIP, 1 for audio:\n" );
|
||||||
fprintf(stderr, "options:\n" );
|
fprintf(stderr, "options:\n" );
|
||||||
fprintf(stderr, "-cbr : enable constant bitrate; default: variable bitrate\n" );
|
fprintf(stderr, "-cbr : enable constant bitrate; default: variable bitrate\n" );
|
||||||
fprintf(stderr, "-cvbr : enable constraint variable bitrate; default: unconstraint\n" );
|
fprintf(stderr, "-cvbr : enable constraint variable bitrate; default: unconstraint\n" );
|
||||||
|
@ -92,7 +92,7 @@ int main(int argc, char *argv[])
|
||||||
int stop=0;
|
int stop=0;
|
||||||
int tot_read=0, tot_written=0;
|
int tot_read=0, tot_written=0;
|
||||||
short *in, *out;
|
short *in, *out;
|
||||||
int mode;
|
int application;
|
||||||
double bits=0.0, bits_act=0.0, bits2=0.0, nrg;
|
double bits=0.0, bits_act=0.0, bits2=0.0, nrg;
|
||||||
int bandwidth=-1;
|
int bandwidth=-1;
|
||||||
const char *bandwidth_string;
|
const char *bandwidth_string;
|
||||||
|
@ -107,7 +107,7 @@ int main(int argc, char *argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
mode = atoi(argv[1]) + OPUS_MODE_VOICE;
|
application = atoi(argv[1]) + OPUS_APPLICATION_VOIP;
|
||||||
sampling_rate = atoi(argv[2]);
|
sampling_rate = atoi(argv[2]);
|
||||||
channels = atoi(argv[3]);
|
channels = atoi(argv[3]);
|
||||||
bitrate_bps = atoi(argv[4]);
|
bitrate_bps = atoi(argv[4]);
|
||||||
|
@ -200,7 +200,7 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( mode < OPUS_MODE_VOICE || mode > OPUS_MODE_AUDIO) {
|
if( application < OPUS_APPLICATION_VOIP || application > OPUS_APPLICATION_AUDIO) {
|
||||||
fprintf (stderr, "mode must be: 0 or 1\n");
|
fprintf (stderr, "mode must be: 0 or 1\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -233,7 +233,7 @@ int main(int argc, char *argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
enc = opus_encoder_create(sampling_rate, channels, mode);
|
enc = opus_encoder_create(sampling_rate, channels, application);
|
||||||
dec = opus_decoder_create(sampling_rate, channels);
|
dec = opus_decoder_create(sampling_rate, channels);
|
||||||
|
|
||||||
if (enc==NULL)
|
if (enc==NULL)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue