mirror of
https://github.com/ioquake/ioq3.git
synced 2024-11-10 07:11:46 +00:00
Merge branch 'master' into sdl2
This commit is contained in:
commit
ed087bb89e
320 changed files with 18335 additions and 9574 deletions
24
Makefile
24
Makefile
|
@ -240,9 +240,9 @@ UIDIR=$(MOUNT_DIR)/ui
|
||||||
Q3UIDIR=$(MOUNT_DIR)/q3_ui
|
Q3UIDIR=$(MOUNT_DIR)/q3_ui
|
||||||
JPDIR=$(MOUNT_DIR)/jpeg-8c
|
JPDIR=$(MOUNT_DIR)/jpeg-8c
|
||||||
SPEEXDIR=$(MOUNT_DIR)/libspeex
|
SPEEXDIR=$(MOUNT_DIR)/libspeex
|
||||||
OGGDIR=$(MOUNT_DIR)/libogg-1.3.0
|
OGGDIR=$(MOUNT_DIR)/libogg-1.3.1
|
||||||
OPUSDIR=$(MOUNT_DIR)/opus-1.0.2
|
OPUSDIR=$(MOUNT_DIR)/opus-1.1
|
||||||
OPUSFILEDIR=$(MOUNT_DIR)/opusfile-0.2
|
OPUSFILEDIR=$(MOUNT_DIR)/opusfile-0.5
|
||||||
ZDIR=$(MOUNT_DIR)/zlib
|
ZDIR=$(MOUNT_DIR)/zlib
|
||||||
Q3ASMDIR=$(MOUNT_DIR)/tools/asm
|
Q3ASMDIR=$(MOUNT_DIR)/tools/asm
|
||||||
LBURGDIR=$(MOUNT_DIR)/tools/lcc/lburg
|
LBURGDIR=$(MOUNT_DIR)/tools/lcc/lburg
|
||||||
|
@ -534,6 +534,10 @@ ifeq ($(PLATFORM),mingw32)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CC),)
|
||||||
|
$(error Cannot find a suitable cross compiler for $(PLATFORM))
|
||||||
|
endif
|
||||||
|
|
||||||
BASE_CFLAGS = -Wall -fno-strict-aliasing -Wimplicit -Wstrict-prototypes \
|
BASE_CFLAGS = -Wall -fno-strict-aliasing -Wimplicit -Wstrict-prototypes \
|
||||||
-DUSE_ICON
|
-DUSE_ICON
|
||||||
|
|
||||||
|
@ -1819,10 +1823,15 @@ endif
|
||||||
ifeq ($(USE_CODEC_OPUS),1)
|
ifeq ($(USE_CODEC_OPUS),1)
|
||||||
ifeq ($(USE_INTERNAL_OPUS),1)
|
ifeq ($(USE_INTERNAL_OPUS),1)
|
||||||
Q3OBJ += \
|
Q3OBJ += \
|
||||||
|
$(B)/client/opus/analysis.o \
|
||||||
|
$(B)/client/opus/mlp.o \
|
||||||
|
$(B)/client/opus/mlp_data.o \
|
||||||
$(B)/client/opus/opus.o \
|
$(B)/client/opus/opus.o \
|
||||||
$(B)/client/opus/opus_decoder.o \
|
$(B)/client/opus/opus_decoder.o \
|
||||||
$(B)/client/opus/opus_encoder.o \
|
$(B)/client/opus/opus_encoder.o \
|
||||||
$(B)/client/opus/opus_multistream.o \
|
$(B)/client/opus/opus_multistream.o \
|
||||||
|
$(B)/client/opus/opus_multistream_encoder.o \
|
||||||
|
$(B)/client/opus/opus_multistream_decoder.o \
|
||||||
$(B)/client/opus/repacketizer.o \
|
$(B)/client/opus/repacketizer.o \
|
||||||
\
|
\
|
||||||
$(B)/client/opus/bands.o \
|
$(B)/client/opus/bands.o \
|
||||||
|
@ -1837,6 +1846,8 @@ Q3OBJ += \
|
||||||
$(B)/client/opus/mdct.o \
|
$(B)/client/opus/mdct.o \
|
||||||
$(B)/client/opus/modes.o \
|
$(B)/client/opus/modes.o \
|
||||||
$(B)/client/opus/pitch.o \
|
$(B)/client/opus/pitch.o \
|
||||||
|
$(B)/client/opus/celt_encoder.o \
|
||||||
|
$(B)/client/opus/celt_decoder.o \
|
||||||
$(B)/client/opus/celt_lpc.o \
|
$(B)/client/opus/celt_lpc.o \
|
||||||
$(B)/client/opus/quant_bands.o \
|
$(B)/client/opus/quant_bands.o \
|
||||||
$(B)/client/opus/rate.o \
|
$(B)/client/opus/rate.o \
|
||||||
|
@ -1955,7 +1966,8 @@ Q3OBJ += \
|
||||||
$(B)/client/info.o \
|
$(B)/client/info.o \
|
||||||
$(B)/client/internal.o \
|
$(B)/client/internal.o \
|
||||||
$(B)/client/opusfile.o \
|
$(B)/client/opusfile.o \
|
||||||
$(B)/client/stream.o
|
$(B)/client/stream.o \
|
||||||
|
$(B)/client/wincerts.o
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
@ -2701,6 +2713,10 @@ ifneq ($(BUILD_CLIENT),0)
|
||||||
ifneq ($(BUILD_RENDERER_OPENGL2),0)
|
ifneq ($(BUILD_RENDERER_OPENGL2),0)
|
||||||
$(INSTALL) $(STRIP_FLAG) -m 0755 $(BR)/renderer_opengl2_$(SHLIBNAME) $(COPYBINDIR)/renderer_opengl2_$(SHLIBNAME)
|
$(INSTALL) $(STRIP_FLAG) -m 0755 $(BR)/renderer_opengl2_$(SHLIBNAME) $(COPYBINDIR)/renderer_opengl2_$(SHLIBNAME)
|
||||||
endif
|
endif
|
||||||
|
else
|
||||||
|
ifneq ($(BUILD_RENDERER_OPENGL2),0)
|
||||||
|
$(INSTALL) $(STRIP_FLAG) -m 0755 $(BR)/$(CLIENTBIN)_opengl2$(FULLBINEXT) $(COPYBINDIR)/$(CLIENTBIN)_opengl2$(FULLBINEXT)
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -783,4 +783,4 @@ Significant contributions from
|
||||||
* Aaron Gyes <floam@aaron.gy>
|
* Aaron Gyes <floam@aaron.gy>
|
||||||
|
|
||||||
|
|
||||||
[![githalytics.com alpha](https://cruel-carlota.pagodabox.com/f88af076b5015c62b699968f6772c3a5 "githalytics.com")](http://githalytics.com/ioquake/ioq3)
|
[![githalytics.com alpha](https://cruel-carlota.pagodabox.com/6d196bd663b47049a25dcb8caef95949 "githalytics.com")](http://githalytics.com/ioquake/ioq3)
|
||||||
|
|
|
@ -1472,7 +1472,9 @@ int CIN_PlayCinematic( const char *arg, int x, int y, int w, int h, int systemBi
|
||||||
|
|
||||||
Con_Close();
|
Con_Close();
|
||||||
|
|
||||||
s_rawend[0] = s_soundtime;
|
if (!cinTable[currentHandle].silent) {
|
||||||
|
s_rawend[0] = s_soundtime;
|
||||||
|
}
|
||||||
|
|
||||||
return currentHandle;
|
return currentHandle;
|
||||||
}
|
}
|
||||||
|
|
|
@ -670,7 +670,7 @@ void CL_StopRecord_f( void ) {
|
||||||
CL_DemoFilename
|
CL_DemoFilename
|
||||||
==================
|
==================
|
||||||
*/
|
*/
|
||||||
void CL_DemoFilename( int number, char *fileName ) {
|
void CL_DemoFilename( int number, char *fileName, int fileNameSize ) {
|
||||||
int a,b,c,d;
|
int a,b,c,d;
|
||||||
|
|
||||||
if(number < 0 || number > 9999)
|
if(number < 0 || number > 9999)
|
||||||
|
@ -684,7 +684,7 @@ void CL_DemoFilename( int number, char *fileName ) {
|
||||||
number -= c*10;
|
number -= c*10;
|
||||||
d = number;
|
d = number;
|
||||||
|
|
||||||
Com_sprintf( fileName, MAX_OSPATH, "demo%i%i%i%i"
|
Com_sprintf( fileName, fileNameSize, "demo%i%i%i%i"
|
||||||
, a, b, c, d );
|
, a, b, c, d );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -744,7 +744,7 @@ void CL_Record_f( void ) {
|
||||||
|
|
||||||
// scan for a free demo name
|
// scan for a free demo name
|
||||||
for ( number = 0 ; number <= 9999 ; number++ ) {
|
for ( number = 0 ; number <= 9999 ; number++ ) {
|
||||||
CL_DemoFilename( number, demoName );
|
CL_DemoFilename( number, demoName, sizeof( demoName ) );
|
||||||
#ifdef LEGACY_PROTOCOL
|
#ifdef LEGACY_PROTOCOL
|
||||||
if(clc.compat)
|
if(clc.compat)
|
||||||
Com_sprintf(name, sizeof(name), "demos/%s.%s%d", demoName, DEMOEXT, com_legacyprotocol->integer);
|
Com_sprintf(name, sizeof(name), "demos/%s.%s%d", demoName, DEMOEXT, com_legacyprotocol->integer);
|
||||||
|
|
|
@ -709,7 +709,7 @@ void CL_ParseVoip ( msg_t *msg ) {
|
||||||
const int packetsize = MSG_ReadShort(msg);
|
const int packetsize = MSG_ReadShort(msg);
|
||||||
const int flags = MSG_ReadBits(msg, VOIP_FLAGCNT);
|
const int flags = MSG_ReadBits(msg, VOIP_FLAGCNT);
|
||||||
char encoded[1024];
|
char encoded[1024];
|
||||||
int seqdiff = sequence - clc.voipIncomingSequence[sender];
|
int seqdiff;
|
||||||
int written = 0;
|
int written = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -753,6 +753,8 @@ void CL_ParseVoip ( msg_t *msg ) {
|
||||||
|
|
||||||
Com_DPrintf("VoIP: packet accepted!\n");
|
Com_DPrintf("VoIP: packet accepted!\n");
|
||||||
|
|
||||||
|
seqdiff = sequence - clc.voipIncomingSequence[sender];
|
||||||
|
|
||||||
// This is a new "generation" ... a new recording started, reset the bits.
|
// This is a new "generation" ... a new recording started, reset the bits.
|
||||||
if (generation != clc.voipIncomingGeneration[sender]) {
|
if (generation != clc.voipIncomingGeneration[sender]) {
|
||||||
Com_DPrintf("VoIP: new generation %d!\n", generation);
|
Com_DPrintf("VoIP: new generation %d!\n", generation);
|
||||||
|
|
|
@ -481,7 +481,7 @@ void SCR_DrawScreenField( stereoFrame_t stereoFrame ) {
|
||||||
|
|
||||||
// wide aspect ratio screens need to have the sides cleared
|
// wide aspect ratio screens need to have the sides cleared
|
||||||
// unless they are displaying game renderings
|
// unless they are displaying game renderings
|
||||||
if ( uiFullscreen || (clc.state != CA_ACTIVE && clc.state != CA_CINEMATIC) ) {
|
if ( uiFullscreen || clc.state < CA_LOADING ) {
|
||||||
if ( cls.glconfig.vidWidth * 480 > cls.glconfig.vidHeight * 640 ) {
|
if ( cls.glconfig.vidWidth * 480 > cls.glconfig.vidHeight * 640 ) {
|
||||||
re.SetColor( g_color_table[0] );
|
re.SetColor( g_color_table[0] );
|
||||||
re.DrawStretchPic( 0, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight, 0, 0, 0, 0, cls.whiteShader );
|
re.DrawStretchPic( 0, 0, cls.glconfig.vidWidth, cls.glconfig.vidHeight, 0, 0, 0, 0, cls.whiteShader );
|
||||||
|
|
|
@ -982,29 +982,34 @@ void S_Base_RawSamples( int stream, int samples, int rate, int width, int s_chan
|
||||||
int i;
|
int i;
|
||||||
int src, dst;
|
int src, dst;
|
||||||
float scale;
|
float scale;
|
||||||
int intVolume;
|
int intVolumeLeft, intVolumeRight;
|
||||||
portable_samplepair_t *rawsamples;
|
portable_samplepair_t *rawsamples;
|
||||||
|
|
||||||
if ( !s_soundStarted || s_soundMuted ) {
|
if ( !s_soundStarted || s_soundMuted ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(entityNum >= 0)
|
|
||||||
{
|
|
||||||
// FIXME: support spatialized raw streams, e.g. for VoIP
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( (stream < 0) || (stream >= MAX_RAW_STREAMS) ) {
|
if ( (stream < 0) || (stream >= MAX_RAW_STREAMS) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rawsamples = s_rawsamples[stream];
|
rawsamples = s_rawsamples[stream];
|
||||||
|
|
||||||
if(s_muted->integer)
|
if ( s_muted->integer ) {
|
||||||
intVolume = 0;
|
intVolumeLeft = intVolumeRight = 0;
|
||||||
else
|
} else {
|
||||||
intVolume = 256 * volume * s_volume->value;
|
int leftvol, rightvol;
|
||||||
|
|
||||||
|
if ( entityNum >= 0 && entityNum < MAX_GENTITIES ) {
|
||||||
|
// support spatialized raw streams, e.g. for VoIP
|
||||||
|
S_SpatializeOrigin( loopSounds[ entityNum ].origin, 256, &leftvol, &rightvol );
|
||||||
|
} else {
|
||||||
|
leftvol = rightvol = 256;
|
||||||
|
}
|
||||||
|
|
||||||
|
intVolumeLeft = leftvol * volume * s_volume->value;
|
||||||
|
intVolumeRight = rightvol * volume * s_volume->value;
|
||||||
|
}
|
||||||
|
|
||||||
if ( s_rawend[stream] < s_soundtime ) {
|
if ( s_rawend[stream] < s_soundtime ) {
|
||||||
Com_DPrintf( "S_Base_RawSamples: resetting minimum: %i < %i\n", s_rawend[stream], s_soundtime );
|
Com_DPrintf( "S_Base_RawSamples: resetting minimum: %i < %i\n", s_rawend[stream], s_soundtime );
|
||||||
|
@ -1022,8 +1027,8 @@ void S_Base_RawSamples( int stream, int samples, int rate, int width, int s_chan
|
||||||
{
|
{
|
||||||
dst = s_rawend[stream]&(MAX_RAW_SAMPLES-1);
|
dst = s_rawend[stream]&(MAX_RAW_SAMPLES-1);
|
||||||
s_rawend[stream]++;
|
s_rawend[stream]++;
|
||||||
rawsamples[dst].left = ((short *)data)[i*2] * intVolume;
|
rawsamples[dst].left = ((short *)data)[i*2] * intVolumeLeft;
|
||||||
rawsamples[dst].right = ((short *)data)[i*2+1] * intVolume;
|
rawsamples[dst].right = ((short *)data)[i*2+1] * intVolumeRight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1035,8 +1040,8 @@ void S_Base_RawSamples( int stream, int samples, int rate, int width, int s_chan
|
||||||
break;
|
break;
|
||||||
dst = s_rawend[stream]&(MAX_RAW_SAMPLES-1);
|
dst = s_rawend[stream]&(MAX_RAW_SAMPLES-1);
|
||||||
s_rawend[stream]++;
|
s_rawend[stream]++;
|
||||||
rawsamples[dst].left = ((short *)data)[src*2] * intVolume;
|
rawsamples[dst].left = ((short *)data)[src*2] * intVolumeLeft;
|
||||||
rawsamples[dst].right = ((short *)data)[src*2+1] * intVolume;
|
rawsamples[dst].right = ((short *)data)[src*2+1] * intVolumeRight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1049,13 +1054,14 @@ void S_Base_RawSamples( int stream, int samples, int rate, int width, int s_chan
|
||||||
break;
|
break;
|
||||||
dst = s_rawend[stream]&(MAX_RAW_SAMPLES-1);
|
dst = s_rawend[stream]&(MAX_RAW_SAMPLES-1);
|
||||||
s_rawend[stream]++;
|
s_rawend[stream]++;
|
||||||
rawsamples[dst].left = ((short *)data)[src] * intVolume;
|
rawsamples[dst].left = ((short *)data)[src] * intVolumeLeft;
|
||||||
rawsamples[dst].right = ((short *)data)[src] * intVolume;
|
rawsamples[dst].right = ((short *)data)[src] * intVolumeRight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (s_channels == 2 && width == 1)
|
else if (s_channels == 2 && width == 1)
|
||||||
{
|
{
|
||||||
intVolume *= 256;
|
intVolumeLeft *= 256;
|
||||||
|
intVolumeRight *= 256;
|
||||||
|
|
||||||
for (i=0 ; ; i++)
|
for (i=0 ; ; i++)
|
||||||
{
|
{
|
||||||
|
@ -1064,13 +1070,14 @@ void S_Base_RawSamples( int stream, int samples, int rate, int width, int s_chan
|
||||||
break;
|
break;
|
||||||
dst = s_rawend[stream]&(MAX_RAW_SAMPLES-1);
|
dst = s_rawend[stream]&(MAX_RAW_SAMPLES-1);
|
||||||
s_rawend[stream]++;
|
s_rawend[stream]++;
|
||||||
rawsamples[dst].left = ((char *)data)[src*2] * intVolume;
|
rawsamples[dst].left = ((char *)data)[src*2] * intVolumeLeft;
|
||||||
rawsamples[dst].right = ((char *)data)[src*2+1] * intVolume;
|
rawsamples[dst].right = ((char *)data)[src*2+1] * intVolumeRight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (s_channels == 1 && width == 1)
|
else if (s_channels == 1 && width == 1)
|
||||||
{
|
{
|
||||||
intVolume *= 256;
|
intVolumeLeft *= 256;
|
||||||
|
intVolumeRight *= 256;
|
||||||
|
|
||||||
for (i=0 ; ; i++)
|
for (i=0 ; ; i++)
|
||||||
{
|
{
|
||||||
|
@ -1079,8 +1086,8 @@ void S_Base_RawSamples( int stream, int samples, int rate, int width, int s_chan
|
||||||
break;
|
break;
|
||||||
dst = s_rawend[stream]&(MAX_RAW_SAMPLES-1);
|
dst = s_rawend[stream]&(MAX_RAW_SAMPLES-1);
|
||||||
s_rawend[stream]++;
|
s_rawend[stream]++;
|
||||||
rawsamples[dst].left = (((byte *)data)[src]-128) * intVolume;
|
rawsamples[dst].left = (((byte *)data)[src]-128) * intVolumeLeft;
|
||||||
rawsamples[dst].right = (((byte *)data)[src]-128) * intVolume;
|
rawsamples[dst].right = (((byte *)data)[src]-128) * intVolumeRight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1417,11 +1424,7 @@ void S_Base_StartBackgroundTrack( const char *intro, const char *loop ){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !loop ) {
|
Q_strncpyz( s_backgroundLoop, loop, sizeof( s_backgroundLoop ) );
|
||||||
s_backgroundLoop[0] = 0;
|
|
||||||
} else {
|
|
||||||
Q_strncpyz( s_backgroundLoop, loop, sizeof( s_backgroundLoop ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
S_OpenBackgroundStream( intro );
|
S_OpenBackgroundStream( intro );
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@ typedef struct sfx_s {
|
||||||
qboolean soundCompressed; // not in Memory
|
qboolean soundCompressed; // not in Memory
|
||||||
int soundCompressionMethod;
|
int soundCompressionMethod;
|
||||||
int soundLength;
|
int soundLength;
|
||||||
|
int soundChannels;
|
||||||
char soundName[MAX_QPATH];
|
char soundName[MAX_QPATH];
|
||||||
int lastTimeUsed;
|
int lastTimeUsed;
|
||||||
struct sfx_s *next;
|
struct sfx_s *next;
|
||||||
|
|
|
@ -113,47 +113,51 @@ ResampleSfx
|
||||||
resample / decimate to the current source rate
|
resample / decimate to the current source rate
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
static void ResampleSfx( sfx_t *sfx, int inrate, int inwidth, byte *data, qboolean compressed ) {
|
static int ResampleSfx( sfx_t *sfx, int channels, int inrate, int inwidth, int samples, byte *data, qboolean compressed ) {
|
||||||
int outcount;
|
int outcount;
|
||||||
int srcsample;
|
int srcsample;
|
||||||
float stepscale;
|
float stepscale;
|
||||||
int i;
|
int i, j;
|
||||||
int sample, samplefrac, fracstep;
|
int sample, samplefrac, fracstep;
|
||||||
int part;
|
int part;
|
||||||
sndBuffer *chunk;
|
sndBuffer *chunk;
|
||||||
|
|
||||||
stepscale = (float)inrate / dma.speed; // this is usually 0.5, 1, or 2
|
stepscale = (float)inrate / dma.speed; // this is usually 0.5, 1, or 2
|
||||||
|
|
||||||
outcount = sfx->soundLength / stepscale;
|
outcount = samples / stepscale;
|
||||||
sfx->soundLength = outcount;
|
|
||||||
|
|
||||||
samplefrac = 0;
|
samplefrac = 0;
|
||||||
fracstep = stepscale * 256;
|
fracstep = stepscale * 256 * channels;
|
||||||
chunk = sfx->soundData;
|
chunk = sfx->soundData;
|
||||||
|
|
||||||
for (i=0 ; i<outcount ; i++)
|
for (i=0 ; i<outcount ; i++)
|
||||||
{
|
{
|
||||||
srcsample = samplefrac >> 8;
|
srcsample = samplefrac >> 8;
|
||||||
samplefrac += fracstep;
|
samplefrac += fracstep;
|
||||||
if( inwidth == 2 ) {
|
for (j=0 ; j<channels ; j++)
|
||||||
sample = ( ((short *)data)[srcsample] );
|
{
|
||||||
} else {
|
if( inwidth == 2 ) {
|
||||||
sample = (int)( (unsigned char)(data[srcsample]) - 128) << 8;
|
sample = ( ((short *)data)[srcsample+j] );
|
||||||
}
|
|
||||||
part = (i&(SND_CHUNK_SIZE-1));
|
|
||||||
if (part == 0) {
|
|
||||||
sndBuffer *newchunk;
|
|
||||||
newchunk = SND_malloc();
|
|
||||||
if (chunk == NULL) {
|
|
||||||
sfx->soundData = newchunk;
|
|
||||||
} else {
|
} else {
|
||||||
chunk->next = newchunk;
|
sample = (int)( (unsigned char)(data[srcsample+j]) - 128) << 8;
|
||||||
|
}
|
||||||
|
part = (i*channels+j)&(SND_CHUNK_SIZE-1);
|
||||||
|
if (part == 0) {
|
||||||
|
sndBuffer *newchunk;
|
||||||
|
newchunk = SND_malloc();
|
||||||
|
if (chunk == NULL) {
|
||||||
|
sfx->soundData = newchunk;
|
||||||
|
} else {
|
||||||
|
chunk->next = newchunk;
|
||||||
|
}
|
||||||
|
chunk = newchunk;
|
||||||
}
|
}
|
||||||
chunk = newchunk;
|
|
||||||
}
|
|
||||||
|
|
||||||
chunk->sndChunk[part] = sample;
|
chunk->sndChunk[part] = sample;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return outcount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -163,11 +167,11 @@ ResampleSfx
|
||||||
resample / decimate to the current source rate
|
resample / decimate to the current source rate
|
||||||
================
|
================
|
||||||
*/
|
*/
|
||||||
static int ResampleSfxRaw( short *sfx, int inrate, int inwidth, int samples, byte *data ) {
|
static int ResampleSfxRaw( short *sfx, int channels, int inrate, int inwidth, int samples, byte *data ) {
|
||||||
int outcount;
|
int outcount;
|
||||||
int srcsample;
|
int srcsample;
|
||||||
float stepscale;
|
float stepscale;
|
||||||
int i;
|
int i, j;
|
||||||
int sample, samplefrac, fracstep;
|
int sample, samplefrac, fracstep;
|
||||||
|
|
||||||
stepscale = (float)inrate / dma.speed; // this is usually 0.5, 1, or 2
|
stepscale = (float)inrate / dma.speed; // this is usually 0.5, 1, or 2
|
||||||
|
@ -175,18 +179,21 @@ static int ResampleSfxRaw( short *sfx, int inrate, int inwidth, int samples, byt
|
||||||
outcount = samples / stepscale;
|
outcount = samples / stepscale;
|
||||||
|
|
||||||
samplefrac = 0;
|
samplefrac = 0;
|
||||||
fracstep = stepscale * 256;
|
fracstep = stepscale * 256 * channels;
|
||||||
|
|
||||||
for (i=0 ; i<outcount ; i++)
|
for (i=0 ; i<outcount ; i++)
|
||||||
{
|
{
|
||||||
srcsample = samplefrac >> 8;
|
srcsample = samplefrac >> 8;
|
||||||
samplefrac += fracstep;
|
samplefrac += fracstep;
|
||||||
if( inwidth == 2 ) {
|
for (j=0 ; j<channels ; j++)
|
||||||
sample = LittleShort ( ((short *)data)[srcsample] );
|
{
|
||||||
} else {
|
if( inwidth == 2 ) {
|
||||||
sample = (int)( (unsigned char)(data[srcsample]) - 128) << 8;
|
sample = LittleShort ( ((short *)data)[srcsample+j] );
|
||||||
|
} else {
|
||||||
|
sample = (int)( (unsigned char)(data[srcsample+j]) - 128) << 8;
|
||||||
|
}
|
||||||
|
sfx[i*channels+j] = sample;
|
||||||
}
|
}
|
||||||
sfx[i] = sample;
|
|
||||||
}
|
}
|
||||||
return outcount;
|
return outcount;
|
||||||
}
|
}
|
||||||
|
@ -221,7 +228,7 @@ qboolean S_LoadSound( sfx_t *sfx )
|
||||||
Com_DPrintf(S_COLOR_YELLOW "WARNING: %s is not a 22kHz audio file\n", sfx->soundName);
|
Com_DPrintf(S_COLOR_YELLOW "WARNING: %s is not a 22kHz audio file\n", sfx->soundName);
|
||||||
}
|
}
|
||||||
|
|
||||||
samples = Hunk_AllocateTempMemory(info.samples * sizeof(short) * 2);
|
samples = Hunk_AllocateTempMemory(info.channels * info.samples * sizeof(short) * 2);
|
||||||
|
|
||||||
sfx->lastTimeUsed = Com_Milliseconds()+1;
|
sfx->lastTimeUsed = Com_Milliseconds()+1;
|
||||||
|
|
||||||
|
@ -231,29 +238,30 @@ qboolean S_LoadSound( sfx_t *sfx )
|
||||||
// manager to do the right thing for us and page
|
// manager to do the right thing for us and page
|
||||||
// sound in as needed
|
// sound in as needed
|
||||||
|
|
||||||
if( sfx->soundCompressed == qtrue) {
|
if( info.channels == 1 && sfx->soundCompressed == qtrue) {
|
||||||
sfx->soundCompressionMethod = 1;
|
sfx->soundCompressionMethod = 1;
|
||||||
sfx->soundData = NULL;
|
sfx->soundData = NULL;
|
||||||
sfx->soundLength = ResampleSfxRaw( samples, info.rate, info.width, info.samples, data + info.dataofs );
|
sfx->soundLength = ResampleSfxRaw( samples, info.channels, info.rate, info.width, info.samples, data + info.dataofs );
|
||||||
S_AdpcmEncodeSound(sfx, samples);
|
S_AdpcmEncodeSound(sfx, samples);
|
||||||
#if 0
|
#if 0
|
||||||
} else if (info.samples>(SND_CHUNK_SIZE*16) && info.width >1) {
|
} else if (info.channels == 1 && info.samples>(SND_CHUNK_SIZE*16) && info.width >1) {
|
||||||
sfx->soundCompressionMethod = 3;
|
sfx->soundCompressionMethod = 3;
|
||||||
sfx->soundData = NULL;
|
sfx->soundData = NULL;
|
||||||
sfx->soundLength = ResampleSfxRaw( samples, info.rate, info.width, info.samples, (data + info.dataofs) );
|
sfx->soundLength = ResampleSfxRaw( samples, info.channels, info.rate, info.width, info.samples, (data + info.dataofs) );
|
||||||
encodeMuLaw( sfx, samples);
|
encodeMuLaw( sfx, samples);
|
||||||
} else if (info.samples>(SND_CHUNK_SIZE*6400) && info.width >1) {
|
} else if (info.channels == 1 && info.samples>(SND_CHUNK_SIZE*6400) && info.width >1) {
|
||||||
sfx->soundCompressionMethod = 2;
|
sfx->soundCompressionMethod = 2;
|
||||||
sfx->soundData = NULL;
|
sfx->soundData = NULL;
|
||||||
sfx->soundLength = ResampleSfxRaw( samples, info.rate, info.width, info.samples, (data + info.dataofs) );
|
sfx->soundLength = ResampleSfxRaw( samples, info.channels, info.rate, info.width, info.samples, (data + info.dataofs) );
|
||||||
encodeWavelet( sfx, samples);
|
encodeWavelet( sfx, samples);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
sfx->soundCompressionMethod = 0;
|
sfx->soundCompressionMethod = 0;
|
||||||
sfx->soundLength = info.samples;
|
|
||||||
sfx->soundData = NULL;
|
sfx->soundData = NULL;
|
||||||
ResampleSfx( sfx, info.rate, info.width, data + info.dataofs, qfalse );
|
sfx->soundLength = ResampleSfx( sfx, info.channels, info.rate, info.width, info.samples, data + info.dataofs, qfalse );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sfx->soundChannels = info.channels;
|
||||||
|
|
||||||
Hunk_FreeTempMemory(samples);
|
Hunk_FreeTempMemory(samples);
|
||||||
Hunk_FreeTempMemory(data);
|
Hunk_FreeTempMemory(data);
|
||||||
|
|
|
@ -234,7 +234,7 @@ static void S_PaintChannelFrom16_altivec( channel_t *ch, const sfx_t *sc, int co
|
||||||
portable_samplepair_t *samp;
|
portable_samplepair_t *samp;
|
||||||
sndBuffer *chunk;
|
sndBuffer *chunk;
|
||||||
short *samples;
|
short *samples;
|
||||||
float ooff, fdata, fdiv, fleftvol, frightvol;
|
float ooff, fdata[2], fdiv, fleftvol, frightvol;
|
||||||
|
|
||||||
samp = &paintbuffer[ bufferOffset ];
|
samp = &paintbuffer[ bufferOffset ];
|
||||||
|
|
||||||
|
@ -242,6 +242,14 @@ static void S_PaintChannelFrom16_altivec( channel_t *ch, const sfx_t *sc, int co
|
||||||
sampleOffset = sampleOffset*ch->oldDopplerScale;
|
sampleOffset = sampleOffset*ch->oldDopplerScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( sc->soundChannels == 2 ) {
|
||||||
|
sampleOffset *= sc->soundChannels;
|
||||||
|
|
||||||
|
if ( sampleOffset & 1 ) {
|
||||||
|
sampleOffset &= ~1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
chunk = sc->soundData;
|
chunk = sc->soundData;
|
||||||
while (sampleOffset>=SND_CHUNK_SIZE) {
|
while (sampleOffset>=SND_CHUNK_SIZE) {
|
||||||
chunk = chunk->next;
|
chunk = chunk->next;
|
||||||
|
@ -274,6 +282,10 @@ static void S_PaintChannelFrom16_altivec( channel_t *ch, const sfx_t *sc, int co
|
||||||
while(i < count && (((unsigned long)&samp[i] & 0x1f) || ((count-i) < 8) || ((SND_CHUNK_SIZE - sampleOffset) < 8))) {
|
while(i < count && (((unsigned long)&samp[i] & 0x1f) || ((count-i) < 8) || ((SND_CHUNK_SIZE - sampleOffset) < 8))) {
|
||||||
data = samples[sampleOffset++];
|
data = samples[sampleOffset++];
|
||||||
samp[i].left += (data * leftvol)>>8;
|
samp[i].left += (data * leftvol)>>8;
|
||||||
|
|
||||||
|
if ( sc->soundChannels == 2 ) {
|
||||||
|
data = samples[sampleOffset++];
|
||||||
|
}
|
||||||
samp[i].right += (data * rightvol)>>8;
|
samp[i].right += (data * rightvol)>>8;
|
||||||
|
|
||||||
if (sampleOffset == SND_CHUNK_SIZE) {
|
if (sampleOffset == SND_CHUNK_SIZE) {
|
||||||
|
@ -373,10 +385,10 @@ static void S_PaintChannelFrom16_altivec( channel_t *ch, const sfx_t *sc, int co
|
||||||
for ( i=0 ; i<count ; i++ ) {
|
for ( i=0 ; i<count ; i++ ) {
|
||||||
|
|
||||||
aoff = ooff;
|
aoff = ooff;
|
||||||
ooff = ooff + ch->dopplerScale;
|
ooff = ooff + ch->dopplerScale * sc->soundChannels;
|
||||||
boff = ooff;
|
boff = ooff;
|
||||||
fdata = 0;
|
fdata[0] = fdata[1] = 0;
|
||||||
for (j=aoff; j<boff; j++) {
|
for (j=aoff; j<boff; j += sc->soundChannels) {
|
||||||
if (j == SND_CHUNK_SIZE) {
|
if (j == SND_CHUNK_SIZE) {
|
||||||
chunk = chunk->next;
|
chunk = chunk->next;
|
||||||
if (!chunk) {
|
if (!chunk) {
|
||||||
|
@ -385,11 +397,17 @@ static void S_PaintChannelFrom16_altivec( channel_t *ch, const sfx_t *sc, int co
|
||||||
samples = chunk->sndChunk;
|
samples = chunk->sndChunk;
|
||||||
ooff -= SND_CHUNK_SIZE;
|
ooff -= SND_CHUNK_SIZE;
|
||||||
}
|
}
|
||||||
fdata += samples[j&(SND_CHUNK_SIZE-1)];
|
if ( sc->soundChannels == 2 ) {
|
||||||
|
fdata[0] += samples[j&(SND_CHUNK_SIZE-1)];
|
||||||
|
fdata[1] += samples[(j+1)&(SND_CHUNK_SIZE-1)];
|
||||||
|
} else {
|
||||||
|
fdata[0] += samples[j&(SND_CHUNK_SIZE-1)];
|
||||||
|
fdata[1] += samples[j&(SND_CHUNK_SIZE-1)];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fdiv = 256 * (boff-aoff);
|
fdiv = 256 * (boff-aoff) / sc->soundChannels;
|
||||||
samp[i].left += (fdata * fleftvol)/fdiv;
|
samp[i].left += (fdata[0] * fleftvol)/fdiv;
|
||||||
samp[i].right += (fdata * frightvol)/fdiv;
|
samp[i].right += (fdata[1] * frightvol)/fdiv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -402,7 +420,7 @@ static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int cou
|
||||||
portable_samplepair_t *samp;
|
portable_samplepair_t *samp;
|
||||||
sndBuffer *chunk;
|
sndBuffer *chunk;
|
||||||
short *samples;
|
short *samples;
|
||||||
float ooff, fdata, fdiv, fleftvol, frightvol;
|
float ooff, fdata[2], fdiv, fleftvol, frightvol;
|
||||||
|
|
||||||
samp = &paintbuffer[ bufferOffset ];
|
samp = &paintbuffer[ bufferOffset ];
|
||||||
|
|
||||||
|
@ -410,6 +428,14 @@ static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int cou
|
||||||
sampleOffset = sampleOffset*ch->oldDopplerScale;
|
sampleOffset = sampleOffset*ch->oldDopplerScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( sc->soundChannels == 2 ) {
|
||||||
|
sampleOffset *= sc->soundChannels;
|
||||||
|
|
||||||
|
if ( sampleOffset & 1 ) {
|
||||||
|
sampleOffset &= ~1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
chunk = sc->soundData;
|
chunk = sc->soundData;
|
||||||
while (sampleOffset>=SND_CHUNK_SIZE) {
|
while (sampleOffset>=SND_CHUNK_SIZE) {
|
||||||
chunk = chunk->next;
|
chunk = chunk->next;
|
||||||
|
@ -426,6 +452,10 @@ static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int cou
|
||||||
for ( i=0 ; i<count ; i++ ) {
|
for ( i=0 ; i<count ; i++ ) {
|
||||||
data = samples[sampleOffset++];
|
data = samples[sampleOffset++];
|
||||||
samp[i].left += (data * leftvol)>>8;
|
samp[i].left += (data * leftvol)>>8;
|
||||||
|
|
||||||
|
if ( sc->soundChannels == 2 ) {
|
||||||
|
data = samples[sampleOffset++];
|
||||||
|
}
|
||||||
samp[i].right += (data * rightvol)>>8;
|
samp[i].right += (data * rightvol)>>8;
|
||||||
|
|
||||||
if (sampleOffset == SND_CHUNK_SIZE) {
|
if (sampleOffset == SND_CHUNK_SIZE) {
|
||||||
|
@ -447,10 +477,10 @@ static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int cou
|
||||||
for ( i=0 ; i<count ; i++ ) {
|
for ( i=0 ; i<count ; i++ ) {
|
||||||
|
|
||||||
aoff = ooff;
|
aoff = ooff;
|
||||||
ooff = ooff + ch->dopplerScale;
|
ooff = ooff + ch->dopplerScale * sc->soundChannels;
|
||||||
boff = ooff;
|
boff = ooff;
|
||||||
fdata = 0;
|
fdata[0] = fdata[1] = 0;
|
||||||
for (j=aoff; j<boff; j++) {
|
for (j=aoff; j<boff; j += sc->soundChannels) {
|
||||||
if (j == SND_CHUNK_SIZE) {
|
if (j == SND_CHUNK_SIZE) {
|
||||||
chunk = chunk->next;
|
chunk = chunk->next;
|
||||||
if (!chunk) {
|
if (!chunk) {
|
||||||
|
@ -459,11 +489,17 @@ static void S_PaintChannelFrom16_scalar( channel_t *ch, const sfx_t *sc, int cou
|
||||||
samples = chunk->sndChunk;
|
samples = chunk->sndChunk;
|
||||||
ooff -= SND_CHUNK_SIZE;
|
ooff -= SND_CHUNK_SIZE;
|
||||||
}
|
}
|
||||||
fdata += samples[j&(SND_CHUNK_SIZE-1)];
|
if ( sc->soundChannels == 2 ) {
|
||||||
|
fdata[0] += samples[j&(SND_CHUNK_SIZE-1)];
|
||||||
|
fdata[1] += samples[(j+1)&(SND_CHUNK_SIZE-1)];
|
||||||
|
} else {
|
||||||
|
fdata[0] += samples[j&(SND_CHUNK_SIZE-1)];
|
||||||
|
fdata[1] += samples[j&(SND_CHUNK_SIZE-1)];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fdiv = 256 * (boff-aoff);
|
fdiv = 256 * (boff-aoff) / sc->soundChannels;
|
||||||
samp[i].left += (fdata * fleftvol)/fdiv;
|
samp[i].left += (fdata[0] * fleftvol)/fdiv;
|
||||||
samp[i].right += (fdata * frightvol)/fdiv;
|
samp[i].right += (fdata[1] * frightvol)/fdiv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2521,7 +2521,9 @@ qboolean S_AL_Init( soundInterface_t *si )
|
||||||
if( !QAL_Init( s_alDriver->string ) )
|
if( !QAL_Init( s_alDriver->string ) )
|
||||||
{
|
{
|
||||||
Com_Printf( "Failed to load library: \"%s\".\n", s_alDriver->string );
|
Com_Printf( "Failed to load library: \"%s\".\n", s_alDriver->string );
|
||||||
return qfalse;
|
if( !Q_stricmp( s_alDriver->string, ALDRIVER_DEFAULT ) || !QAL_Init( ALDRIVER_DEFAULT ) ) {
|
||||||
|
return qfalse;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
device = s_alDevice->string;
|
device = s_alDevice->string;
|
||||||
|
@ -2667,11 +2669,14 @@ qboolean S_AL_Init( soundInterface_t *si )
|
||||||
defaultinputdevice = qalcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER);
|
defaultinputdevice = qalcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER);
|
||||||
|
|
||||||
// dump a list of available devices to a cvar for the user to see.
|
// dump a list of available devices to a cvar for the user to see.
|
||||||
while((curlen = strlen(inputdevicelist)))
|
if (inputdevicelist)
|
||||||
{
|
{
|
||||||
Q_strcat(inputdevicenames, sizeof(inputdevicenames), inputdevicelist);
|
while((curlen = strlen(inputdevicelist)))
|
||||||
Q_strcat(inputdevicenames, sizeof(inputdevicenames), "\n");
|
{
|
||||||
inputdevicelist += curlen + 1;
|
Q_strcat(inputdevicenames, sizeof(inputdevicenames), inputdevicelist);
|
||||||
|
Q_strcat(inputdevicenames, sizeof(inputdevicenames), "\n");
|
||||||
|
inputdevicelist += curlen + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s_alAvailableInputDevices = Cvar_Get("s_alAvailableInputDevices", inputdevicenames, CVAR_ROM | CVAR_NORESTART);
|
s_alAvailableInputDevices = Cvar_Get("s_alAvailableInputDevices", inputdevicenames, CVAR_ROM | CVAR_NORESTART);
|
||||||
|
@ -2680,7 +2685,7 @@ qboolean S_AL_Init( soundInterface_t *si )
|
||||||
// !!! FIXME: should probably open the capture device after
|
// !!! FIXME: should probably open the capture device after
|
||||||
// !!! FIXME: initializing Speex so we can change to wideband
|
// !!! FIXME: initializing Speex so we can change to wideband
|
||||||
// !!! FIXME: if we like.
|
// !!! FIXME: if we like.
|
||||||
Com_Printf("OpenAL default capture device is '%s'\n", defaultinputdevice);
|
Com_Printf("OpenAL default capture device is '%s'\n", defaultinputdevice ? defaultinputdevice : "none");
|
||||||
alCaptureDevice = qalcCaptureOpenDevice(inputdevice, 8000, AL_FORMAT_MONO16, 4096);
|
alCaptureDevice = qalcCaptureOpenDevice(inputdevice, 8000, AL_FORMAT_MONO16, 4096);
|
||||||
if( !alCaptureDevice && inputdevice )
|
if( !alCaptureDevice && inputdevice )
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef __CONFIG_TYPES_H__
|
#ifndef __CONFIG_TYPES_H__
|
||||||
#define __CONFIG_TYPES_H__
|
#define __CONFIG_TYPES_H__
|
||||||
|
|
||||||
|
/* these are filled in by configure */
|
||||||
/* #define INCLUDE_INTTYPES_H 1 */
|
/* #define INCLUDE_INTTYPES_H 1 */
|
||||||
#define INCLUDE_STDINT_H 1
|
#define INCLUDE_STDINT_H 1
|
||||||
/* #define INCLUDE_SYS_TYPES_H 1 */
|
/* #define INCLUDE_SYS_TYPES_H 1 */
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
function: code raw packets into framed OggSquish stream and
|
function: code raw packets into framed OggSquish stream and
|
||||||
decode Ogg streams back into raw packets
|
decode Ogg streams back into raw packets
|
||||||
last mod: $Id: framing.c 18052 2011-08-04 17:57:02Z giles $
|
last mod: $Id: framing.c 18758 2013-01-08 16:29:56Z tterribe $
|
||||||
|
|
||||||
note: The CRC code is directly derived from public domain code by
|
note: The CRC code is directly derived from public domain code by
|
||||||
Ross Williams (ross@guest.adelaide.edu.au). See docs/framing.html
|
Ross Williams (ross@guest.adelaide.edu.au). See docs/framing.html
|
||||||
|
@ -21,6 +21,7 @@
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <limits.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ogg/ogg.h>
|
#include <ogg/ogg.h>
|
||||||
|
|
||||||
|
@ -236,39 +237,51 @@ int ogg_stream_destroy(ogg_stream_state *os){
|
||||||
/* Helpers for ogg_stream_encode; this keeps the structure and
|
/* Helpers for ogg_stream_encode; this keeps the structure and
|
||||||
what's happening fairly clear */
|
what's happening fairly clear */
|
||||||
|
|
||||||
static int _os_body_expand(ogg_stream_state *os,int needed){
|
static int _os_body_expand(ogg_stream_state *os,long needed){
|
||||||
if(os->body_storage<=os->body_fill+needed){
|
if(os->body_storage-needed<=os->body_fill){
|
||||||
|
long body_storage;
|
||||||
void *ret;
|
void *ret;
|
||||||
ret=_ogg_realloc(os->body_data,(os->body_storage+needed+1024)*
|
if(os->body_storage>LONG_MAX-needed){
|
||||||
sizeof(*os->body_data));
|
ogg_stream_clear(os);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
body_storage=os->body_storage+needed;
|
||||||
|
if(body_storage<LONG_MAX-1024)body_storage+=1024;
|
||||||
|
ret=_ogg_realloc(os->body_data,body_storage*sizeof(*os->body_data));
|
||||||
if(!ret){
|
if(!ret){
|
||||||
ogg_stream_clear(os);
|
ogg_stream_clear(os);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
os->body_storage+=(needed+1024);
|
os->body_storage=body_storage;
|
||||||
os->body_data=ret;
|
os->body_data=ret;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _os_lacing_expand(ogg_stream_state *os,int needed){
|
static int _os_lacing_expand(ogg_stream_state *os,long needed){
|
||||||
if(os->lacing_storage<=os->lacing_fill+needed){
|
if(os->lacing_storage-needed<=os->lacing_fill){
|
||||||
|
long lacing_storage;
|
||||||
void *ret;
|
void *ret;
|
||||||
ret=_ogg_realloc(os->lacing_vals,(os->lacing_storage+needed+32)*
|
if(os->lacing_storage>LONG_MAX-needed){
|
||||||
sizeof(*os->lacing_vals));
|
ogg_stream_clear(os);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
lacing_storage=os->lacing_storage+needed;
|
||||||
|
if(lacing_storage<LONG_MAX-32)lacing_storage+=32;
|
||||||
|
ret=_ogg_realloc(os->lacing_vals,lacing_storage*sizeof(*os->lacing_vals));
|
||||||
if(!ret){
|
if(!ret){
|
||||||
ogg_stream_clear(os);
|
ogg_stream_clear(os);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
os->lacing_vals=ret;
|
os->lacing_vals=ret;
|
||||||
ret=_ogg_realloc(os->granule_vals,(os->lacing_storage+needed+32)*
|
ret=_ogg_realloc(os->granule_vals,lacing_storage*
|
||||||
sizeof(*os->granule_vals));
|
sizeof(*os->granule_vals));
|
||||||
if(!ret){
|
if(!ret){
|
||||||
ogg_stream_clear(os);
|
ogg_stream_clear(os);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
os->granule_vals=ret;
|
os->granule_vals=ret;
|
||||||
os->lacing_storage+=(needed+32);
|
os->lacing_storage=lacing_storage;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -304,12 +317,17 @@ void ogg_page_checksum_set(ogg_page *og){
|
||||||
int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, int count,
|
int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, int count,
|
||||||
long e_o_s, ogg_int64_t granulepos){
|
long e_o_s, ogg_int64_t granulepos){
|
||||||
|
|
||||||
int bytes = 0, lacing_vals, i;
|
long bytes = 0, lacing_vals;
|
||||||
|
int i;
|
||||||
|
|
||||||
if(ogg_stream_check(os)) return -1;
|
if(ogg_stream_check(os)) return -1;
|
||||||
if(!iov) return 0;
|
if(!iov) return 0;
|
||||||
|
|
||||||
for (i = 0; i < count; ++i) bytes += (int)iov[i].iov_len;
|
for (i = 0; i < count; ++i){
|
||||||
|
if(iov[i].iov_len>LONG_MAX) return -1;
|
||||||
|
if(bytes>LONG_MAX-(long)iov[i].iov_len) return -1;
|
||||||
|
bytes += (long)iov[i].iov_len;
|
||||||
|
}
|
||||||
lacing_vals=bytes/255+1;
|
lacing_vals=bytes/255+1;
|
||||||
|
|
||||||
if(os->body_returned){
|
if(os->body_returned){
|
File diff suppressed because it is too large
Load diff
|
@ -1,188 +0,0 @@
|
||||||
/* Copyright (c) 2009-2010 Xiph.Org Foundation
|
|
||||||
Written by Jean-Marc Valin */
|
|
||||||
/*
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
|
|
||||||
- Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
- Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
|
||||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
||||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "celt_lpc.h"
|
|
||||||
#include "stack_alloc.h"
|
|
||||||
#include "mathops.h"
|
|
||||||
|
|
||||||
void _celt_lpc(
|
|
||||||
opus_val16 *_lpc, /* out: [0...p-1] LPC coefficients */
|
|
||||||
const opus_val32 *ac, /* in: [0...p] autocorrelation values */
|
|
||||||
int p
|
|
||||||
)
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
opus_val32 r;
|
|
||||||
opus_val32 error = ac[0];
|
|
||||||
#ifdef FIXED_POINT
|
|
||||||
opus_val32 lpc[LPC_ORDER];
|
|
||||||
#else
|
|
||||||
float *lpc = _lpc;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (i = 0; i < p; i++)
|
|
||||||
lpc[i] = 0;
|
|
||||||
if (ac[0] != 0)
|
|
||||||
{
|
|
||||||
for (i = 0; i < p; i++) {
|
|
||||||
/* Sum up this iteration's reflection coefficient */
|
|
||||||
opus_val32 rr = 0;
|
|
||||||
for (j = 0; j < i; j++)
|
|
||||||
rr += MULT32_32_Q31(lpc[j],ac[i - j]);
|
|
||||||
rr += SHR32(ac[i + 1],3);
|
|
||||||
r = -frac_div32(SHL32(rr,3), error);
|
|
||||||
/* Update LPC coefficients and total error */
|
|
||||||
lpc[i] = SHR32(r,3);
|
|
||||||
for (j = 0; j < (i+1)>>1; j++)
|
|
||||||
{
|
|
||||||
opus_val32 tmp1, tmp2;
|
|
||||||
tmp1 = lpc[j];
|
|
||||||
tmp2 = lpc[i-1-j];
|
|
||||||
lpc[j] = tmp1 + MULT32_32_Q31(r,tmp2);
|
|
||||||
lpc[i-1-j] = tmp2 + MULT32_32_Q31(r,tmp1);
|
|
||||||
}
|
|
||||||
|
|
||||||
error = error - MULT32_32_Q31(MULT32_32_Q31(r,r),error);
|
|
||||||
/* Bail out once we get 30 dB gain */
|
|
||||||
#ifdef FIXED_POINT
|
|
||||||
if (error<SHR32(ac[0],10))
|
|
||||||
break;
|
|
||||||
#else
|
|
||||||
if (error<.001f*ac[0])
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef FIXED_POINT
|
|
||||||
for (i=0;i<p;i++)
|
|
||||||
_lpc[i] = ROUND16(lpc[i],16);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void celt_fir(const opus_val16 *x,
|
|
||||||
const opus_val16 *num,
|
|
||||||
opus_val16 *y,
|
|
||||||
int N,
|
|
||||||
int ord,
|
|
||||||
opus_val16 *mem)
|
|
||||||
{
|
|
||||||
int i,j;
|
|
||||||
|
|
||||||
for (i=0;i<N;i++)
|
|
||||||
{
|
|
||||||
opus_val32 sum = SHL32(EXTEND32(x[i]), SIG_SHIFT);
|
|
||||||
for (j=0;j<ord;j++)
|
|
||||||
{
|
|
||||||
sum += MULT16_16(num[j],mem[j]);
|
|
||||||
}
|
|
||||||
for (j=ord-1;j>=1;j--)
|
|
||||||
{
|
|
||||||
mem[j]=mem[j-1];
|
|
||||||
}
|
|
||||||
mem[0] = x[i];
|
|
||||||
y[i] = ROUND16(sum, SIG_SHIFT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void celt_iir(const opus_val32 *x,
|
|
||||||
const opus_val16 *den,
|
|
||||||
opus_val32 *y,
|
|
||||||
int N,
|
|
||||||
int ord,
|
|
||||||
opus_val16 *mem)
|
|
||||||
{
|
|
||||||
int i,j;
|
|
||||||
for (i=0;i<N;i++)
|
|
||||||
{
|
|
||||||
opus_val32 sum = x[i];
|
|
||||||
for (j=0;j<ord;j++)
|
|
||||||
{
|
|
||||||
sum -= MULT16_16(den[j],mem[j]);
|
|
||||||
}
|
|
||||||
for (j=ord-1;j>=1;j--)
|
|
||||||
{
|
|
||||||
mem[j]=mem[j-1];
|
|
||||||
}
|
|
||||||
mem[0] = ROUND16(sum,SIG_SHIFT);
|
|
||||||
y[i] = sum;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _celt_autocorr(
|
|
||||||
const opus_val16 *x, /* in: [0...n-1] samples x */
|
|
||||||
opus_val32 *ac, /* out: [0...lag-1] ac values */
|
|
||||||
const opus_val16 *window,
|
|
||||||
int overlap,
|
|
||||||
int lag,
|
|
||||||
int n
|
|
||||||
)
|
|
||||||
{
|
|
||||||
opus_val32 d;
|
|
||||||
int i;
|
|
||||||
VARDECL(opus_val16, xx);
|
|
||||||
SAVE_STACK;
|
|
||||||
ALLOC(xx, n, opus_val16);
|
|
||||||
celt_assert(n>0);
|
|
||||||
celt_assert(overlap>=0);
|
|
||||||
for (i=0;i<n;i++)
|
|
||||||
xx[i] = x[i];
|
|
||||||
for (i=0;i<overlap;i++)
|
|
||||||
{
|
|
||||||
xx[i] = MULT16_16_Q15(x[i],window[i]);
|
|
||||||
xx[n-i-1] = MULT16_16_Q15(x[n-i-1],window[i]);
|
|
||||||
}
|
|
||||||
#ifdef FIXED_POINT
|
|
||||||
{
|
|
||||||
opus_val32 ac0=0;
|
|
||||||
int shift;
|
|
||||||
for(i=0;i<n;i++)
|
|
||||||
ac0 += SHR32(MULT16_16(xx[i],xx[i]),9);
|
|
||||||
ac0 += 1+n;
|
|
||||||
|
|
||||||
shift = celt_ilog2(ac0)-30+10;
|
|
||||||
shift = (shift+1)/2;
|
|
||||||
for(i=0;i<n;i++)
|
|
||||||
xx[i] = VSHR32(xx[i], shift);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
while (lag>=0)
|
|
||||||
{
|
|
||||||
for (i = lag, d = 0; i < n; i++)
|
|
||||||
d += xx[i] * xx[i-lag];
|
|
||||||
ac[lag] = d;
|
|
||||||
/*printf ("%f ", ac[lag]);*/
|
|
||||||
lag--;
|
|
||||||
}
|
|
||||||
/*printf ("\n");*/
|
|
||||||
ac[0] += 10;
|
|
||||||
|
|
||||||
RESTORE_STACK;
|
|
||||||
}
|
|
|
@ -1,645 +0,0 @@
|
||||||
/* Copyright (c) 2007-2008 CSIRO
|
|
||||||
Copyright (c) 2007-2009 Xiph.Org Foundation
|
|
||||||
Copyright (c) 2007-2009 Timothy B. Terriberry
|
|
||||||
Written by Timothy B. Terriberry and Jean-Marc Valin */
|
|
||||||
/*
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
|
|
||||||
- Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
- Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
|
||||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
||||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include "config.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "os_support.h"
|
|
||||||
#include "cwrs.h"
|
|
||||||
#include "mathops.h"
|
|
||||||
#include "arch.h"
|
|
||||||
|
|
||||||
#ifdef CUSTOM_MODES
|
|
||||||
|
|
||||||
/*Guaranteed to return a conservatively large estimate of the binary logarithm
|
|
||||||
with frac bits of fractional precision.
|
|
||||||
Tested for all possible 32-bit inputs with frac=4, where the maximum
|
|
||||||
overestimation is 0.06254243 bits.*/
|
|
||||||
int log2_frac(opus_uint32 val, int frac)
|
|
||||||
{
|
|
||||||
int l;
|
|
||||||
l=EC_ILOG(val);
|
|
||||||
if(val&(val-1)){
|
|
||||||
/*This is (val>>l-16), but guaranteed to round up, even if adding a bias
|
|
||||||
before the shift would cause overflow (e.g., for 0xFFFFxxxx).
|
|
||||||
Doesn't work for val=0, but that case fails the test above.*/
|
|
||||||
if(l>16)val=((val-1)>>(l-16))+1;
|
|
||||||
else val<<=16-l;
|
|
||||||
l=(l-1)<<frac;
|
|
||||||
/*Note that we always need one iteration, since the rounding up above means
|
|
||||||
that we might need to adjust the integer part of the logarithm.*/
|
|
||||||
do{
|
|
||||||
int b;
|
|
||||||
b=(int)(val>>16);
|
|
||||||
l+=b<<frac;
|
|
||||||
val=(val+b)>>b;
|
|
||||||
val=(val*val+0x7FFF)>>15;
|
|
||||||
}
|
|
||||||
while(frac-->0);
|
|
||||||
/*If val is not exactly 0x8000, then we have to round up the remainder.*/
|
|
||||||
return l+(val>0x8000);
|
|
||||||
}
|
|
||||||
/*Exact powers of two require no rounding.*/
|
|
||||||
else return (l-1)<<frac;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef SMALL_FOOTPRINT
|
|
||||||
|
|
||||||
#define MASK32 (0xFFFFFFFF)
|
|
||||||
|
|
||||||
/*INV_TABLE[i] holds the multiplicative inverse of (2*i+1) mod 2**32.*/
|
|
||||||
static const opus_uint32 INV_TABLE[53]={
|
|
||||||
0x00000001,0xAAAAAAAB,0xCCCCCCCD,0xB6DB6DB7,
|
|
||||||
0x38E38E39,0xBA2E8BA3,0xC4EC4EC5,0xEEEEEEEF,
|
|
||||||
0xF0F0F0F1,0x286BCA1B,0x3CF3CF3D,0xE9BD37A7,
|
|
||||||
0xC28F5C29,0x684BDA13,0x4F72C235,0xBDEF7BDF,
|
|
||||||
0x3E0F83E1,0x8AF8AF8B,0x914C1BAD,0x96F96F97,
|
|
||||||
0xC18F9C19,0x2FA0BE83,0xA4FA4FA5,0x677D46CF,
|
|
||||||
0x1A1F58D1,0xFAFAFAFB,0x8C13521D,0x586FB587,
|
|
||||||
0xB823EE09,0xA08AD8F3,0xC10C9715,0xBEFBEFBF,
|
|
||||||
0xC0FC0FC1,0x07A44C6B,0xA33F128D,0xE327A977,
|
|
||||||
0xC7E3F1F9,0x962FC963,0x3F2B3885,0x613716AF,
|
|
||||||
0x781948B1,0x2B2E43DB,0xFCFCFCFD,0x6FD0EB67,
|
|
||||||
0xFA3F47E9,0xD2FD2FD3,0x3F4FD3F5,0xD4E25B9F,
|
|
||||||
0x5F02A3A1,0xBF5A814B,0x7C32B16D,0xD3431B57,
|
|
||||||
0xD8FD8FD9,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*Computes (_a*_b-_c)/(2*_d+1) when the quotient is known to be exact.
|
|
||||||
_a, _b, _c, and _d may be arbitrary so long as the arbitrary precision result
|
|
||||||
fits in 32 bits, but currently the table for multiplicative inverses is only
|
|
||||||
valid for _d<=52.*/
|
|
||||||
static inline opus_uint32 imusdiv32odd(opus_uint32 _a,opus_uint32 _b,
|
|
||||||
opus_uint32 _c,int _d){
|
|
||||||
celt_assert(_d<=52);
|
|
||||||
return (_a*_b-_c)*INV_TABLE[_d]&MASK32;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Computes (_a*_b-_c)/_d when the quotient is known to be exact.
|
|
||||||
_d does not actually have to be even, but imusdiv32odd will be faster when
|
|
||||||
it's odd, so you should use that instead.
|
|
||||||
_a and _d are assumed to be small (e.g., _a*_d fits in 32 bits; currently the
|
|
||||||
table for multiplicative inverses is only valid for _d<=54).
|
|
||||||
_b and _c may be arbitrary so long as the arbitrary precision reuslt fits in
|
|
||||||
32 bits.*/
|
|
||||||
static inline opus_uint32 imusdiv32even(opus_uint32 _a,opus_uint32 _b,
|
|
||||||
opus_uint32 _c,int _d){
|
|
||||||
opus_uint32 inv;
|
|
||||||
int mask;
|
|
||||||
int shift;
|
|
||||||
int one;
|
|
||||||
celt_assert(_d>0);
|
|
||||||
celt_assert(_d<=54);
|
|
||||||
shift=EC_ILOG(_d^(_d-1));
|
|
||||||
inv=INV_TABLE[(_d-1)>>shift];
|
|
||||||
shift--;
|
|
||||||
one=1<<shift;
|
|
||||||
mask=one-1;
|
|
||||||
return (_a*(_b>>shift)-(_c>>shift)+
|
|
||||||
((_a*(_b&mask)+one-(_c&mask))>>shift)-1)*inv&MASK32;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* SMALL_FOOTPRINT */
|
|
||||||
|
|
||||||
/*Although derived separately, the pulse vector coding scheme is equivalent to
|
|
||||||
a Pyramid Vector Quantizer \cite{Fis86}.
|
|
||||||
Some additional notes about an early version appear at
|
|
||||||
http://people.xiph.org/~tterribe/notes/cwrs.html, but the codebook ordering
|
|
||||||
and the definitions of some terms have evolved since that was written.
|
|
||||||
|
|
||||||
The conversion from a pulse vector to an integer index (encoding) and back
|
|
||||||
(decoding) is governed by two related functions, V(N,K) and U(N,K).
|
|
||||||
|
|
||||||
V(N,K) = the number of combinations, with replacement, of N items, taken K
|
|
||||||
at a time, when a sign bit is added to each item taken at least once (i.e.,
|
|
||||||
the number of N-dimensional unit pulse vectors with K pulses).
|
|
||||||
One way to compute this is via
|
|
||||||
V(N,K) = K>0 ? sum(k=1...K,2**k*choose(N,k)*choose(K-1,k-1)) : 1,
|
|
||||||
where choose() is the binomial function.
|
|
||||||
A table of values for N<10 and K<10 looks like:
|
|
||||||
V[10][10] = {
|
|
||||||
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
||||||
{1, 2, 2, 2, 2, 2, 2, 2, 2, 2},
|
|
||||||
{1, 4, 8, 12, 16, 20, 24, 28, 32, 36},
|
|
||||||
{1, 6, 18, 38, 66, 102, 146, 198, 258, 326},
|
|
||||||
{1, 8, 32, 88, 192, 360, 608, 952, 1408, 1992},
|
|
||||||
{1, 10, 50, 170, 450, 1002, 1970, 3530, 5890, 9290},
|
|
||||||
{1, 12, 72, 292, 912, 2364, 5336, 10836, 20256, 35436},
|
|
||||||
{1, 14, 98, 462, 1666, 4942, 12642, 28814, 59906, 115598},
|
|
||||||
{1, 16, 128, 688, 2816, 9424, 27008, 68464, 157184, 332688},
|
|
||||||
{1, 18, 162, 978, 4482, 16722, 53154, 148626, 374274, 864146}
|
|
||||||
};
|
|
||||||
|
|
||||||
U(N,K) = the number of such combinations wherein N-1 objects are taken at
|
|
||||||
most K-1 at a time.
|
|
||||||
This is given by
|
|
||||||
U(N,K) = sum(k=0...K-1,V(N-1,k))
|
|
||||||
= K>0 ? (V(N-1,K-1) + V(N,K-1))/2 : 0.
|
|
||||||
The latter expression also makes clear that U(N,K) is half the number of such
|
|
||||||
combinations wherein the first object is taken at least once.
|
|
||||||
Although it may not be clear from either of these definitions, U(N,K) is the
|
|
||||||
natural function to work with when enumerating the pulse vector codebooks,
|
|
||||||
not V(N,K).
|
|
||||||
U(N,K) is not well-defined for N=0, but with the extension
|
|
||||||
U(0,K) = K>0 ? 0 : 1,
|
|
||||||
the function becomes symmetric: U(N,K) = U(K,N), with a similar table:
|
|
||||||
U[10][10] = {
|
|
||||||
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
|
||||||
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1},
|
|
||||||
{0, 1, 3, 5, 7, 9, 11, 13, 15, 17},
|
|
||||||
{0, 1, 5, 13, 25, 41, 61, 85, 113, 145},
|
|
||||||
{0, 1, 7, 25, 63, 129, 231, 377, 575, 833},
|
|
||||||
{0, 1, 9, 41, 129, 321, 681, 1289, 2241, 3649},
|
|
||||||
{0, 1, 11, 61, 231, 681, 1683, 3653, 7183, 13073},
|
|
||||||
{0, 1, 13, 85, 377, 1289, 3653, 8989, 19825, 40081},
|
|
||||||
{0, 1, 15, 113, 575, 2241, 7183, 19825, 48639, 108545},
|
|
||||||
{0, 1, 17, 145, 833, 3649, 13073, 40081, 108545, 265729}
|
|
||||||
};
|
|
||||||
|
|
||||||
With this extension, V(N,K) may be written in terms of U(N,K):
|
|
||||||
V(N,K) = U(N,K) + U(N,K+1)
|
|
||||||
for all N>=0, K>=0.
|
|
||||||
Thus U(N,K+1) represents the number of combinations where the first element
|
|
||||||
is positive or zero, and U(N,K) represents the number of combinations where
|
|
||||||
it is negative.
|
|
||||||
With a large enough table of U(N,K) values, we could write O(N) encoding
|
|
||||||
and O(min(N*log(K),N+K)) decoding routines, but such a table would be
|
|
||||||
prohibitively large for small embedded devices (K may be as large as 32767
|
|
||||||
for small N, and N may be as large as 200).
|
|
||||||
|
|
||||||
Both functions obey the same recurrence relation:
|
|
||||||
V(N,K) = V(N-1,K) + V(N,K-1) + V(N-1,K-1),
|
|
||||||
U(N,K) = U(N-1,K) + U(N,K-1) + U(N-1,K-1),
|
|
||||||
for all N>0, K>0, with different initial conditions at N=0 or K=0.
|
|
||||||
This allows us to construct a row of one of the tables above given the
|
|
||||||
previous row or the next row.
|
|
||||||
Thus we can derive O(NK) encoding and decoding routines with O(K) memory
|
|
||||||
using only addition and subtraction.
|
|
||||||
|
|
||||||
When encoding, we build up from the U(2,K) row and work our way forwards.
|
|
||||||
When decoding, we need to start at the U(N,K) row and work our way backwards,
|
|
||||||
which requires a means of computing U(N,K).
|
|
||||||
U(N,K) may be computed from two previous values with the same N:
|
|
||||||
U(N,K) = ((2*N-1)*U(N,K-1) - U(N,K-2))/(K-1) + U(N,K-2)
|
|
||||||
for all N>1, and since U(N,K) is symmetric, a similar relation holds for two
|
|
||||||
previous values with the same K:
|
|
||||||
U(N,K>1) = ((2*K-1)*U(N-1,K) - U(N-2,K))/(N-1) + U(N-2,K)
|
|
||||||
for all K>1.
|
|
||||||
This allows us to construct an arbitrary row of the U(N,K) table by starting
|
|
||||||
with the first two values, which are constants.
|
|
||||||
This saves roughly 2/3 the work in our O(NK) decoding routine, but costs O(K)
|
|
||||||
multiplications.
|
|
||||||
Similar relations can be derived for V(N,K), but are not used here.
|
|
||||||
|
|
||||||
For N>0 and K>0, U(N,K) and V(N,K) take on the form of an (N-1)-degree
|
|
||||||
polynomial for fixed N.
|
|
||||||
The first few are
|
|
||||||
U(1,K) = 1,
|
|
||||||
U(2,K) = 2*K-1,
|
|
||||||
U(3,K) = (2*K-2)*K+1,
|
|
||||||
U(4,K) = (((4*K-6)*K+8)*K-3)/3,
|
|
||||||
U(5,K) = ((((2*K-4)*K+10)*K-8)*K+3)/3,
|
|
||||||
and
|
|
||||||
V(1,K) = 2,
|
|
||||||
V(2,K) = 4*K,
|
|
||||||
V(3,K) = 4*K*K+2,
|
|
||||||
V(4,K) = 8*(K*K+2)*K/3,
|
|
||||||
V(5,K) = ((4*K*K+20)*K*K+6)/3,
|
|
||||||
for all K>0.
|
|
||||||
This allows us to derive O(N) encoding and O(N*log(K)) decoding routines for
|
|
||||||
small N (and indeed decoding is also O(N) for N<3).
|
|
||||||
|
|
||||||
@ARTICLE{Fis86,
|
|
||||||
author="Thomas R. Fischer",
|
|
||||||
title="A Pyramid Vector Quantizer",
|
|
||||||
journal="IEEE Transactions on Information Theory",
|
|
||||||
volume="IT-32",
|
|
||||||
number=4,
|
|
||||||
pages="568--583",
|
|
||||||
month=Jul,
|
|
||||||
year=1986
|
|
||||||
}*/
|
|
||||||
|
|
||||||
#ifndef SMALL_FOOTPRINT
|
|
||||||
/*Compute U(2,_k).
|
|
||||||
Note that this may be called with _k=32768 (maxK[2]+1).*/
|
|
||||||
static inline unsigned ucwrs2(unsigned _k){
|
|
||||||
celt_assert(_k>0);
|
|
||||||
return _k+(_k-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Compute V(2,_k).*/
|
|
||||||
static inline opus_uint32 ncwrs2(int _k){
|
|
||||||
celt_assert(_k>0);
|
|
||||||
return 4*(opus_uint32)_k;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Compute U(3,_k).
|
|
||||||
Note that this may be called with _k=32768 (maxK[3]+1).*/
|
|
||||||
static inline opus_uint32 ucwrs3(unsigned _k){
|
|
||||||
celt_assert(_k>0);
|
|
||||||
return (2*(opus_uint32)_k-2)*_k+1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Compute V(3,_k).*/
|
|
||||||
static inline opus_uint32 ncwrs3(int _k){
|
|
||||||
celt_assert(_k>0);
|
|
||||||
return 2*(2*(unsigned)_k*(opus_uint32)_k+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Compute U(4,_k).*/
|
|
||||||
static inline opus_uint32 ucwrs4(int _k){
|
|
||||||
celt_assert(_k>0);
|
|
||||||
return imusdiv32odd(2*_k,(2*_k-3)*(opus_uint32)_k+4,3,1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Compute V(4,_k).*/
|
|
||||||
static inline opus_uint32 ncwrs4(int _k){
|
|
||||||
celt_assert(_k>0);
|
|
||||||
return ((_k*(opus_uint32)_k+2)*_k)/3<<3;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* SMALL_FOOTPRINT */
|
|
||||||
|
|
||||||
/*Computes the next row/column of any recurrence that obeys the relation
|
|
||||||
u[i][j]=u[i-1][j]+u[i][j-1]+u[i-1][j-1].
|
|
||||||
_ui0 is the base case for the new row/column.*/
|
|
||||||
static inline void unext(opus_uint32 *_ui,unsigned _len,opus_uint32 _ui0){
|
|
||||||
opus_uint32 ui1;
|
|
||||||
unsigned j;
|
|
||||||
/*This do-while will overrun the array if we don't have storage for at least
|
|
||||||
2 values.*/
|
|
||||||
j=1; do {
|
|
||||||
ui1=UADD32(UADD32(_ui[j],_ui[j-1]),_ui0);
|
|
||||||
_ui[j-1]=_ui0;
|
|
||||||
_ui0=ui1;
|
|
||||||
} while (++j<_len);
|
|
||||||
_ui[j-1]=_ui0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Computes the previous row/column of any recurrence that obeys the relation
|
|
||||||
u[i-1][j]=u[i][j]-u[i][j-1]-u[i-1][j-1].
|
|
||||||
_ui0 is the base case for the new row/column.*/
|
|
||||||
static inline void uprev(opus_uint32 *_ui,unsigned _n,opus_uint32 _ui0){
|
|
||||||
opus_uint32 ui1;
|
|
||||||
unsigned j;
|
|
||||||
/*This do-while will overrun the array if we don't have storage for at least
|
|
||||||
2 values.*/
|
|
||||||
j=1; do {
|
|
||||||
ui1=USUB32(USUB32(_ui[j],_ui[j-1]),_ui0);
|
|
||||||
_ui[j-1]=_ui0;
|
|
||||||
_ui0=ui1;
|
|
||||||
} while (++j<_n);
|
|
||||||
_ui[j-1]=_ui0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Compute V(_n,_k), as well as U(_n,0..._k+1).
|
|
||||||
_u: On exit, _u[i] contains U(_n,i) for i in [0..._k+1].*/
|
|
||||||
static opus_uint32 ncwrs_urow(unsigned _n,unsigned _k,opus_uint32 *_u){
|
|
||||||
opus_uint32 um2;
|
|
||||||
unsigned len;
|
|
||||||
unsigned k;
|
|
||||||
len=_k+2;
|
|
||||||
/*We require storage at least 3 values (e.g., _k>0).*/
|
|
||||||
celt_assert(len>=3);
|
|
||||||
_u[0]=0;
|
|
||||||
_u[1]=um2=1;
|
|
||||||
#ifndef SMALL_FOOTPRINT
|
|
||||||
/*_k>52 doesn't work in the false branch due to the limits of INV_TABLE,
|
|
||||||
but _k isn't tested here because k<=52 for n=7*/
|
|
||||||
if(_n<=6)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
/*If _n==0, _u[0] should be 1 and the rest should be 0.*/
|
|
||||||
/*If _n==1, _u[i] should be 1 for i>1.*/
|
|
||||||
celt_assert(_n>=2);
|
|
||||||
/*If _k==0, the following do-while loop will overflow the buffer.*/
|
|
||||||
celt_assert(_k>0);
|
|
||||||
k=2;
|
|
||||||
do _u[k]=(k<<1)-1;
|
|
||||||
while(++k<len);
|
|
||||||
for(k=2;k<_n;k++)unext(_u+1,_k+1,1);
|
|
||||||
}
|
|
||||||
#ifndef SMALL_FOOTPRINT
|
|
||||||
else{
|
|
||||||
opus_uint32 um1;
|
|
||||||
opus_uint32 n2m1;
|
|
||||||
_u[2]=n2m1=um1=(_n<<1)-1;
|
|
||||||
for(k=3;k<len;k++){
|
|
||||||
/*U(N,K) = ((2*N-1)*U(N,K-1)-U(N,K-2))/(K-1) + U(N,K-2)*/
|
|
||||||
_u[k]=um2=imusdiv32even(n2m1,um1,um2,k-1)+um2;
|
|
||||||
if(++k>=len)break;
|
|
||||||
_u[k]=um1=imusdiv32odd(n2m1,um2,um1,(k-1)>>1)+um1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* SMALL_FOOTPRINT */
|
|
||||||
return _u[_k]+_u[_k+1];
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef SMALL_FOOTPRINT
|
|
||||||
|
|
||||||
/*Returns the _i'th combination of _k elements (at most 32767) chosen from a
|
|
||||||
set of size 1 with associated sign bits.
|
|
||||||
_y: Returns the vector of pulses.*/
|
|
||||||
static inline void cwrsi1(int _k,opus_uint32 _i,int *_y){
|
|
||||||
int s;
|
|
||||||
s=-(int)_i;
|
|
||||||
_y[0]=(_k+s)^s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Returns the _i'th combination of _k elements (at most 32767) chosen from a
|
|
||||||
set of size 2 with associated sign bits.
|
|
||||||
_y: Returns the vector of pulses.*/
|
|
||||||
static inline void cwrsi2(int _k,opus_uint32 _i,int *_y){
|
|
||||||
opus_uint32 p;
|
|
||||||
int s;
|
|
||||||
int yj;
|
|
||||||
p=ucwrs2(_k+1U);
|
|
||||||
s=-(_i>=p);
|
|
||||||
_i-=p&s;
|
|
||||||
yj=_k;
|
|
||||||
_k=(_i+1)>>1;
|
|
||||||
p=_k?ucwrs2(_k):0;
|
|
||||||
_i-=p;
|
|
||||||
yj-=_k;
|
|
||||||
_y[0]=(yj+s)^s;
|
|
||||||
cwrsi1(_k,_i,_y+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Returns the _i'th combination of _k elements (at most 32767) chosen from a
|
|
||||||
set of size 3 with associated sign bits.
|
|
||||||
_y: Returns the vector of pulses.*/
|
|
||||||
static void cwrsi3(int _k,opus_uint32 _i,int *_y){
|
|
||||||
opus_uint32 p;
|
|
||||||
int s;
|
|
||||||
int yj;
|
|
||||||
p=ucwrs3(_k+1U);
|
|
||||||
s=-(_i>=p);
|
|
||||||
_i-=p&s;
|
|
||||||
yj=_k;
|
|
||||||
/*Finds the maximum _k such that ucwrs3(_k)<=_i (tested for all
|
|
||||||
_i<2147418113=U(3,32768)).*/
|
|
||||||
_k=_i>0?(isqrt32(2*_i-1)+1)>>1:0;
|
|
||||||
p=_k?ucwrs3(_k):0;
|
|
||||||
_i-=p;
|
|
||||||
yj-=_k;
|
|
||||||
_y[0]=(yj+s)^s;
|
|
||||||
cwrsi2(_k,_i,_y+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Returns the _i'th combination of _k elements (at most 1172) chosen from a set
|
|
||||||
of size 4 with associated sign bits.
|
|
||||||
_y: Returns the vector of pulses.*/
|
|
||||||
static void cwrsi4(int _k,opus_uint32 _i,int *_y){
|
|
||||||
opus_uint32 p;
|
|
||||||
int s;
|
|
||||||
int yj;
|
|
||||||
int kl;
|
|
||||||
int kr;
|
|
||||||
p=ucwrs4(_k+1);
|
|
||||||
s=-(_i>=p);
|
|
||||||
_i-=p&s;
|
|
||||||
yj=_k;
|
|
||||||
/*We could solve a cubic for k here, but the form of the direct solution does
|
|
||||||
not lend itself well to exact integer arithmetic.
|
|
||||||
Instead we do a binary search on U(4,K).*/
|
|
||||||
kl=0;
|
|
||||||
kr=_k;
|
|
||||||
for(;;){
|
|
||||||
_k=(kl+kr)>>1;
|
|
||||||
p=_k?ucwrs4(_k):0;
|
|
||||||
if(p<_i){
|
|
||||||
if(_k>=kr)break;
|
|
||||||
kl=_k+1;
|
|
||||||
}
|
|
||||||
else if(p>_i)kr=_k-1;
|
|
||||||
else break;
|
|
||||||
}
|
|
||||||
_i-=p;
|
|
||||||
yj-=_k;
|
|
||||||
_y[0]=(yj+s)^s;
|
|
||||||
cwrsi3(_k,_i,_y+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* SMALL_FOOTPRINT */
|
|
||||||
|
|
||||||
/*Returns the _i'th combination of _k elements chosen from a set of size _n
|
|
||||||
with associated sign bits.
|
|
||||||
_y: Returns the vector of pulses.
|
|
||||||
_u: Must contain entries [0..._k+1] of row _n of U() on input.
|
|
||||||
Its contents will be destructively modified.*/
|
|
||||||
static void cwrsi(int _n,int _k,opus_uint32 _i,int *_y,opus_uint32 *_u){
|
|
||||||
int j;
|
|
||||||
celt_assert(_n>0);
|
|
||||||
j=0;
|
|
||||||
do{
|
|
||||||
opus_uint32 p;
|
|
||||||
int s;
|
|
||||||
int yj;
|
|
||||||
p=_u[_k+1];
|
|
||||||
s=-(_i>=p);
|
|
||||||
_i-=p&s;
|
|
||||||
yj=_k;
|
|
||||||
p=_u[_k];
|
|
||||||
while(p>_i)p=_u[--_k];
|
|
||||||
_i-=p;
|
|
||||||
yj-=_k;
|
|
||||||
_y[j]=(yj+s)^s;
|
|
||||||
uprev(_u,_k+2,0);
|
|
||||||
}
|
|
||||||
while(++j<_n);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Returns the index of the given combination of K elements chosen from a set
|
|
||||||
of size 1 with associated sign bits.
|
|
||||||
_y: The vector of pulses, whose sum of absolute values is K.
|
|
||||||
_k: Returns K.*/
|
|
||||||
static inline opus_uint32 icwrs1(const int *_y,int *_k){
|
|
||||||
*_k=abs(_y[0]);
|
|
||||||
return _y[0]<0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef SMALL_FOOTPRINT
|
|
||||||
|
|
||||||
/*Returns the index of the given combination of K elements chosen from a set
|
|
||||||
of size 2 with associated sign bits.
|
|
||||||
_y: The vector of pulses, whose sum of absolute values is K.
|
|
||||||
_k: Returns K.*/
|
|
||||||
static inline opus_uint32 icwrs2(const int *_y,int *_k){
|
|
||||||
opus_uint32 i;
|
|
||||||
int k;
|
|
||||||
i=icwrs1(_y+1,&k);
|
|
||||||
i+=k?ucwrs2(k):0;
|
|
||||||
k+=abs(_y[0]);
|
|
||||||
if(_y[0]<0)i+=ucwrs2(k+1U);
|
|
||||||
*_k=k;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Returns the index of the given combination of K elements chosen from a set
|
|
||||||
of size 3 with associated sign bits.
|
|
||||||
_y: The vector of pulses, whose sum of absolute values is K.
|
|
||||||
_k: Returns K.*/
|
|
||||||
static inline opus_uint32 icwrs3(const int *_y,int *_k){
|
|
||||||
opus_uint32 i;
|
|
||||||
int k;
|
|
||||||
i=icwrs2(_y+1,&k);
|
|
||||||
i+=k?ucwrs3(k):0;
|
|
||||||
k+=abs(_y[0]);
|
|
||||||
if(_y[0]<0)i+=ucwrs3(k+1U);
|
|
||||||
*_k=k;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*Returns the index of the given combination of K elements chosen from a set
|
|
||||||
of size 4 with associated sign bits.
|
|
||||||
_y: The vector of pulses, whose sum of absolute values is K.
|
|
||||||
_k: Returns K.*/
|
|
||||||
static inline opus_uint32 icwrs4(const int *_y,int *_k){
|
|
||||||
opus_uint32 i;
|
|
||||||
int k;
|
|
||||||
i=icwrs3(_y+1,&k);
|
|
||||||
i+=k?ucwrs4(k):0;
|
|
||||||
k+=abs(_y[0]);
|
|
||||||
if(_y[0]<0)i+=ucwrs4(k+1);
|
|
||||||
*_k=k;
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* SMALL_FOOTPRINT */
|
|
||||||
|
|
||||||
/*Returns the index of the given combination of K elements chosen from a set
|
|
||||||
of size _n with associated sign bits.
|
|
||||||
_y: The vector of pulses, whose sum of absolute values must be _k.
|
|
||||||
_nc: Returns V(_n,_k).*/
|
|
||||||
static inline opus_uint32 icwrs(int _n,int _k,opus_uint32 *_nc,const int *_y,
|
|
||||||
opus_uint32 *_u){
|
|
||||||
opus_uint32 i;
|
|
||||||
int j;
|
|
||||||
int k;
|
|
||||||
/*We can't unroll the first two iterations of the loop unless _n>=2.*/
|
|
||||||
celt_assert(_n>=2);
|
|
||||||
_u[0]=0;
|
|
||||||
for(k=1;k<=_k+1;k++)_u[k]=(k<<1)-1;
|
|
||||||
i=icwrs1(_y+_n-1,&k);
|
|
||||||
j=_n-2;
|
|
||||||
i+=_u[k];
|
|
||||||
k+=abs(_y[j]);
|
|
||||||
if(_y[j]<0)i+=_u[k+1];
|
|
||||||
while(j-->0){
|
|
||||||
unext(_u,_k+2,0);
|
|
||||||
i+=_u[k];
|
|
||||||
k+=abs(_y[j]);
|
|
||||||
if(_y[j]<0)i+=_u[k+1];
|
|
||||||
}
|
|
||||||
*_nc=_u[k]+_u[k+1];
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CUSTOM_MODES
|
|
||||||
void get_required_bits(opus_int16 *_bits,int _n,int _maxk,int _frac){
|
|
||||||
int k;
|
|
||||||
/*_maxk==0 => there's nothing to do.*/
|
|
||||||
celt_assert(_maxk>0);
|
|
||||||
_bits[0]=0;
|
|
||||||
if (_n==1)
|
|
||||||
{
|
|
||||||
for (k=1;k<=_maxk;k++)
|
|
||||||
_bits[k] = 1<<_frac;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
VARDECL(opus_uint32,u);
|
|
||||||
SAVE_STACK;
|
|
||||||
ALLOC(u,_maxk+2U,opus_uint32);
|
|
||||||
ncwrs_urow(_n,_maxk,u);
|
|
||||||
for(k=1;k<=_maxk;k++)
|
|
||||||
_bits[k]=log2_frac(u[k]+u[k+1],_frac);
|
|
||||||
RESTORE_STACK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* CUSTOM_MODES */
|
|
||||||
|
|
||||||
void encode_pulses(const int *_y,int _n,int _k,ec_enc *_enc){
|
|
||||||
opus_uint32 i;
|
|
||||||
celt_assert(_k>0);
|
|
||||||
#ifndef SMALL_FOOTPRINT
|
|
||||||
switch(_n){
|
|
||||||
case 2:{
|
|
||||||
i=icwrs2(_y,&_k);
|
|
||||||
ec_enc_uint(_enc,i,ncwrs2(_k));
|
|
||||||
}break;
|
|
||||||
case 3:{
|
|
||||||
i=icwrs3(_y,&_k);
|
|
||||||
ec_enc_uint(_enc,i,ncwrs3(_k));
|
|
||||||
}break;
|
|
||||||
case 4:{
|
|
||||||
i=icwrs4(_y,&_k);
|
|
||||||
ec_enc_uint(_enc,i,ncwrs4(_k));
|
|
||||||
}break;
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
VARDECL(opus_uint32,u);
|
|
||||||
opus_uint32 nc;
|
|
||||||
SAVE_STACK;
|
|
||||||
ALLOC(u,_k+2U,opus_uint32);
|
|
||||||
i=icwrs(_n,_k,&nc,_y,u);
|
|
||||||
ec_enc_uint(_enc,i,nc);
|
|
||||||
RESTORE_STACK;
|
|
||||||
#ifndef SMALL_FOOTPRINT
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void decode_pulses(int *_y,int _n,int _k,ec_dec *_dec)
|
|
||||||
{
|
|
||||||
celt_assert(_k>0);
|
|
||||||
#ifndef SMALL_FOOTPRINT
|
|
||||||
switch(_n){
|
|
||||||
case 2:cwrsi2(_k,ec_dec_uint(_dec,ncwrs2(_k)),_y);break;
|
|
||||||
case 3:cwrsi3(_k,ec_dec_uint(_dec,ncwrs3(_k)),_y);break;
|
|
||||||
case 4:cwrsi4(_k,ec_dec_uint(_dec,ncwrs4(_k)),_y);break;
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
VARDECL(opus_uint32,u);
|
|
||||||
SAVE_STACK;
|
|
||||||
ALLOC(u,_k+2U,opus_uint32);
|
|
||||||
cwrsi(_n,_k,ec_dec_uint(_dec,ncwrs_urow(_n,_k,u)),_y,u);
|
|
||||||
RESTORE_STACK;
|
|
||||||
#ifndef SMALL_FOOTPRINT
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load diff
|
@ -94,6 +94,14 @@
|
||||||
do {(res).r = ADD32((res).r,(a).r); (res).i = SUB32((res).i,(a).i); \
|
do {(res).r = ADD32((res).r,(a).r); (res).i = SUB32((res).i,(a).i); \
|
||||||
}while(0)
|
}while(0)
|
||||||
|
|
||||||
|
#if defined(OPUS_ARM_INLINE_ASM)
|
||||||
|
#include "arm/kiss_fft_armv4.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(OPUS_ARM_INLINE_EDSP)
|
||||||
|
#include "arm/kiss_fft_armv5e.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#else /* not FIXED_POINT*/
|
#else /* not FIXED_POINT*/
|
||||||
|
|
||||||
# define S_MUL(a,b) ( (a)*(b) )
|
# define S_MUL(a,b) ( (a)*(b) )
|
|
@ -35,6 +35,7 @@
|
||||||
#define ARCH_H
|
#define ARCH_H
|
||||||
|
|
||||||
#include "opus_types.h"
|
#include "opus_types.h"
|
||||||
|
#include "opus_defines.h"
|
||||||
|
|
||||||
# if !defined(__GNUC_PREREQ)
|
# if !defined(__GNUC_PREREQ)
|
||||||
# if defined(__GNUC__)&&defined(__GNUC_MINOR__)
|
# if defined(__GNUC__)&&defined(__GNUC_MINOR__)
|
||||||
|
@ -54,7 +55,7 @@
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
__attribute__((noreturn))
|
__attribute__((noreturn))
|
||||||
#endif
|
#endif
|
||||||
static inline void _celt_fatal(const char *str, const char *file, int line)
|
static OPUS_INLINE void _celt_fatal(const char *str, const char *file, int line)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str);
|
fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str);
|
||||||
abort();
|
abort();
|
||||||
|
@ -100,6 +101,7 @@ typedef opus_val32 celt_ener;
|
||||||
#define DB_SHIFT 10
|
#define DB_SHIFT 10
|
||||||
|
|
||||||
#define EPSILON 1
|
#define EPSILON 1
|
||||||
|
#define VERY_SMALL 0
|
||||||
#define VERY_LARGE16 ((opus_val16)32767)
|
#define VERY_LARGE16 ((opus_val16)32767)
|
||||||
#define Q15_ONE ((opus_val16)32767)
|
#define Q15_ONE ((opus_val16)32767)
|
||||||
|
|
||||||
|
@ -112,10 +114,10 @@ typedef opus_val32 celt_ener;
|
||||||
|
|
||||||
#include "fixed_generic.h"
|
#include "fixed_generic.h"
|
||||||
|
|
||||||
#ifdef ARM5E_ASM
|
#ifdef OPUS_ARM_INLINE_EDSP
|
||||||
#include "fixed_arm5e.h"
|
#include "arm/fixed_armv5e.h"
|
||||||
#elif defined (ARM4_ASM)
|
#elif defined (OPUS_ARM_INLINE_ASM)
|
||||||
#include "fixed_arm4.h"
|
#include "arm/fixed_armv4.h"
|
||||||
#elif defined (BFIN_ASM)
|
#elif defined (BFIN_ASM)
|
||||||
#include "fixed_bfin.h"
|
#include "fixed_bfin.h"
|
||||||
#elif defined (TI_C5X_ASM)
|
#elif defined (TI_C5X_ASM)
|
||||||
|
@ -140,6 +142,7 @@ typedef float celt_ener;
|
||||||
#define NORM_SCALING 1.f
|
#define NORM_SCALING 1.f
|
||||||
|
|
||||||
#define EPSILON 1e-15f
|
#define EPSILON 1e-15f
|
||||||
|
#define VERY_SMALL 1e-30f
|
||||||
#define VERY_LARGE16 1e15f
|
#define VERY_LARGE16 1e15f
|
||||||
#define Q15_ONE ((opus_val16)1.f)
|
#define Q15_ONE ((opus_val16)1.f)
|
||||||
|
|
||||||
|
@ -161,6 +164,7 @@ typedef float celt_ener;
|
||||||
#define SHR(a,shift) (a)
|
#define SHR(a,shift) (a)
|
||||||
#define SHL(a,shift) (a)
|
#define SHL(a,shift) (a)
|
||||||
#define SATURATE(x,a) (x)
|
#define SATURATE(x,a) (x)
|
||||||
|
#define SATURATE16(x) (x)
|
||||||
|
|
||||||
#define ROUND16(a,shift) (a)
|
#define ROUND16(a,shift) (a)
|
||||||
#define HALF16(x) (.5f*(x))
|
#define HALF16(x) (.5f*(x))
|
||||||
|
@ -182,6 +186,7 @@ typedef float celt_ener;
|
||||||
#define MAC16_32_Q15(c,a,b) ((c)+(a)*(b))
|
#define MAC16_32_Q15(c,a,b) ((c)+(a)*(b))
|
||||||
|
|
||||||
#define MULT16_16_Q11_32(a,b) ((a)*(b))
|
#define MULT16_16_Q11_32(a,b) ((a)*(b))
|
||||||
|
#define MULT16_16_Q11(a,b) ((a)*(b))
|
||||||
#define MULT16_16_Q13(a,b) ((a)*(b))
|
#define MULT16_16_Q13(a,b) ((a)*(b))
|
||||||
#define MULT16_16_Q14(a,b) ((a)*(b))
|
#define MULT16_16_Q14(a,b) ((a)*(b))
|
||||||
#define MULT16_16_Q15(a,b) ((a)*(b))
|
#define MULT16_16_Q15(a,b) ((a)*(b))
|
316
code/opus-1.1/celt/arm/arm2gnu.pl
Executable file
316
code/opus-1.1/celt/arm/arm2gnu.pl
Executable file
|
@ -0,0 +1,316 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
my $bigend; # little/big endian
|
||||||
|
my $nxstack;
|
||||||
|
|
||||||
|
$nxstack = 0;
|
||||||
|
|
||||||
|
eval 'exec /usr/local/bin/perl -S $0 ${1+"$@"}'
|
||||||
|
if $running_under_some_shell;
|
||||||
|
|
||||||
|
while ($ARGV[0] =~ /^-/) {
|
||||||
|
$_ = shift;
|
||||||
|
last if /^--/;
|
||||||
|
if (/^-n/) {
|
||||||
|
$nflag++;
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
die "I don't recognize this switch: $_\\n";
|
||||||
|
}
|
||||||
|
$printit++ unless $nflag;
|
||||||
|
|
||||||
|
$\ = "\n"; # automatically add newline on print
|
||||||
|
$n=0;
|
||||||
|
|
||||||
|
$thumb = 0; # ARM mode by default, not Thumb.
|
||||||
|
@proc_stack = ();
|
||||||
|
|
||||||
|
LINE:
|
||||||
|
while (<>) {
|
||||||
|
|
||||||
|
# For ADRLs we need to add a new line after the substituted one.
|
||||||
|
$addPadding = 0;
|
||||||
|
|
||||||
|
# First, we do not dare to touch *anything* inside double quotes, do we?
|
||||||
|
# Second, if you want a dollar character in the string,
|
||||||
|
# insert two of them -- that's how ARM C and assembler treat strings.
|
||||||
|
s/^([A-Za-z_]\w*)[ \t]+DCB[ \t]*\"/$1: .ascii \"/ && do { s/\$\$/\$/g; next };
|
||||||
|
s/\bDCB\b[ \t]*\"/.ascii \"/ && do { s/\$\$/\$/g; next };
|
||||||
|
s/^(\S+)\s+RN\s+(\S+)/$1 .req r$2/ && do { s/\$\$/\$/g; next };
|
||||||
|
# If there's nothing on a line but a comment, don't try to apply any further
|
||||||
|
# substitutions (this is a cheap hack to avoid mucking up the license header)
|
||||||
|
s/^([ \t]*);/$1@/ && do { s/\$\$/\$/g; next };
|
||||||
|
# If substituted -- leave immediately !
|
||||||
|
|
||||||
|
s/@/,:/;
|
||||||
|
s/;/@/;
|
||||||
|
while ( /@.*'/ ) {
|
||||||
|
s/(@.*)'/$1/g;
|
||||||
|
}
|
||||||
|
s/\{FALSE\}/0/g;
|
||||||
|
s/\{TRUE\}/1/g;
|
||||||
|
s/\{(\w\w\w\w+)\}/$1/g;
|
||||||
|
s/\bINCLUDE[ \t]*([^ \t\n]+)/.include \"$1\"/;
|
||||||
|
s/\bGET[ \t]*([^ \t\n]+)/.include \"${ my $x=$1; $x =~ s|\.s|-gnu.S|; \$x }\"/;
|
||||||
|
s/\bIMPORT\b/.extern/;
|
||||||
|
s/\bEXPORT\b/.global/;
|
||||||
|
s/^(\s+)\[/$1IF/;
|
||||||
|
s/^(\s+)\|/$1ELSE/;
|
||||||
|
s/^(\s+)\]/$1ENDIF/;
|
||||||
|
s/IF *:DEF:/ .ifdef/;
|
||||||
|
s/IF *:LNOT: *:DEF:/ .ifndef/;
|
||||||
|
s/ELSE/ .else/;
|
||||||
|
s/ENDIF/ .endif/;
|
||||||
|
|
||||||
|
if( /\bIF\b/ ) {
|
||||||
|
s/\bIF\b/ .if/;
|
||||||
|
s/=/==/;
|
||||||
|
}
|
||||||
|
if ( $n == 2) {
|
||||||
|
s/\$/\\/g;
|
||||||
|
}
|
||||||
|
if ($n == 1) {
|
||||||
|
s/\$//g;
|
||||||
|
s/label//g;
|
||||||
|
$n = 2;
|
||||||
|
}
|
||||||
|
if ( /MACRO/ ) {
|
||||||
|
s/MACRO *\n/.macro/;
|
||||||
|
$n=1;
|
||||||
|
}
|
||||||
|
if ( /\bMEND\b/ ) {
|
||||||
|
s/\bMEND\b/.endm/;
|
||||||
|
$n=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
# ".rdata" doesn't work in 'as' version 2.13.2, as it is ".rodata" there.
|
||||||
|
#
|
||||||
|
if ( /\bAREA\b/ ) {
|
||||||
|
my $align;
|
||||||
|
$align = "2";
|
||||||
|
if ( /ALIGN=(\d+)/ ) {
|
||||||
|
$align = $1;
|
||||||
|
}
|
||||||
|
if ( /CODE/ ) {
|
||||||
|
$nxstack = 1;
|
||||||
|
}
|
||||||
|
s/^(.+)CODE(.+)READONLY(.*)/ .text/;
|
||||||
|
s/^(.+)DATA(.+)READONLY(.*)/ .section .rdata/;
|
||||||
|
s/^(.+)\|\|\.data\|\|(.+)/ .data/;
|
||||||
|
s/^(.+)\|\|\.bss\|\|(.+)/ .bss/;
|
||||||
|
s/$/; .p2align $align/;
|
||||||
|
# Enable NEON instructions but don't produce a binary that requires
|
||||||
|
# ARMv7. RVCT does not have equivalent directives, so we just do this
|
||||||
|
# for all CODE areas.
|
||||||
|
if ( /.text/ ) {
|
||||||
|
# Separating .arch, .fpu, etc., by semicolons does not work (gas
|
||||||
|
# thinks the semicolon is part of the arch name, even when there's
|
||||||
|
# whitespace separating them). Sadly this means our line numbers
|
||||||
|
# won't match the original source file (we could use the .line
|
||||||
|
# directive, which is documented to be obsolete, but then gdb will
|
||||||
|
# show the wrong line in the translated source file).
|
||||||
|
s/$/; .arch armv7-a\n .fpu neon\n .object_arch armv4t/;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s/\|\|\.constdata\$(\d+)\|\|/.L_CONST$1/; # ||.constdata$3||
|
||||||
|
s/\|\|\.bss\$(\d+)\|\|/.L_BSS$1/; # ||.bss$2||
|
||||||
|
s/\|\|\.data\$(\d+)\|\|/.L_DATA$1/; # ||.data$2||
|
||||||
|
s/\|\|([a-zA-Z0-9_]+)\@([a-zA-Z0-9_]+)\|\|/@ $&/;
|
||||||
|
s/^(\s+)\%(\s)/ .space $1/;
|
||||||
|
|
||||||
|
s/\|(.+)\.(\d+)\|/\.$1_$2/; # |L80.123| -> .L80_123
|
||||||
|
s/\bCODE32\b/.code 32/ && do {$thumb = 0};
|
||||||
|
s/\bCODE16\b/.code 16/ && do {$thumb = 1};
|
||||||
|
if (/\bPROC\b/)
|
||||||
|
{
|
||||||
|
my $prefix;
|
||||||
|
my $proc;
|
||||||
|
/^([A-Za-z_\.]\w+)\b/;
|
||||||
|
$proc = $1;
|
||||||
|
$prefix = "";
|
||||||
|
if ($proc)
|
||||||
|
{
|
||||||
|
$prefix = $prefix.sprintf("\t.type\t%s, %%function; ",$proc);
|
||||||
|
push(@proc_stack, $proc);
|
||||||
|
s/^[A-Za-z_\.]\w+/$&:/;
|
||||||
|
}
|
||||||
|
$prefix = $prefix."\t.thumb_func; " if ($thumb);
|
||||||
|
s/\bPROC\b/@ $&/;
|
||||||
|
$_ = $prefix.$_;
|
||||||
|
}
|
||||||
|
s/^(\s*)(S|Q|SH|U|UQ|UH)ASX\b/$1$2ADDSUBX/;
|
||||||
|
s/^(\s*)(S|Q|SH|U|UQ|UH)SAX\b/$1$2SUBADDX/;
|
||||||
|
if (/\bENDP\b/)
|
||||||
|
{
|
||||||
|
my $proc;
|
||||||
|
s/\bENDP\b/@ $&/;
|
||||||
|
$proc = pop(@proc_stack);
|
||||||
|
$_ = "\t.size $proc, .-$proc".$_ if ($proc);
|
||||||
|
}
|
||||||
|
s/\bSUBT\b/@ $&/;
|
||||||
|
s/\bDATA\b/@ $&/; # DATA directive is deprecated -- Asm guide, p.7-25
|
||||||
|
s/\bKEEP\b/@ $&/;
|
||||||
|
s/\bEXPORTAS\b/@ $&/;
|
||||||
|
s/\|\|(.)+\bEQU\b/@ $&/;
|
||||||
|
s/\|\|([\w\$]+)\|\|/$1/;
|
||||||
|
s/\bENTRY\b/@ $&/;
|
||||||
|
s/\bASSERT\b/@ $&/;
|
||||||
|
s/\bGBLL\b/@ $&/;
|
||||||
|
s/\bGBLA\b/@ $&/;
|
||||||
|
s/^\W+OPT\b/@ $&/;
|
||||||
|
s/:OR:/|/g;
|
||||||
|
s/:SHL:/<</g;
|
||||||
|
s/:SHR:/>>/g;
|
||||||
|
s/:AND:/&/g;
|
||||||
|
s/:LAND:/&&/g;
|
||||||
|
s/CPSR/cpsr/;
|
||||||
|
s/SPSR/spsr/;
|
||||||
|
s/ALIGN$/.balign 4/;
|
||||||
|
s/ALIGN\s+([0-9x]+)$/.balign $1/;
|
||||||
|
s/psr_cxsf/psr_all/;
|
||||||
|
s/LTORG/.ltorg/;
|
||||||
|
s/^([A-Za-z_]\w*)[ \t]+EQU/ .set $1,/;
|
||||||
|
s/^([A-Za-z_]\w*)[ \t]+SETL/ .set $1,/;
|
||||||
|
s/^([A-Za-z_]\w*)[ \t]+SETA/ .set $1,/;
|
||||||
|
s/^([A-Za-z_]\w*)[ \t]+\*/ .set $1,/;
|
||||||
|
|
||||||
|
# {PC} + 0xdeadfeed --> . + 0xdeadfeed
|
||||||
|
s/\{PC\} \+/ \. +/;
|
||||||
|
|
||||||
|
# Single hex constant on the line !
|
||||||
|
#
|
||||||
|
# >>> NOTE <<<
|
||||||
|
# Double-precision floats in gcc are always mixed-endian, which means
|
||||||
|
# bytes in two words are little-endian, but words are big-endian.
|
||||||
|
# So, 0x0000deadfeed0000 would be stored as 0x0000dead at low address
|
||||||
|
# and 0xfeed0000 at high address.
|
||||||
|
#
|
||||||
|
s/\bDCFD\b[ \t]+0x([a-fA-F0-9]{8})([a-fA-F0-9]{8})/.long 0x$1, 0x$2/;
|
||||||
|
# Only decimal constants on the line, no hex !
|
||||||
|
s/\bDCFD\b[ \t]+([0-9\.\-]+)/.double $1/;
|
||||||
|
|
||||||
|
# Single hex constant on the line !
|
||||||
|
# s/\bDCFS\b[ \t]+0x([a-f0-9]{8})([a-f0-9]{8})/.long 0x$1, 0x$2/;
|
||||||
|
# Only decimal constants on the line, no hex !
|
||||||
|
# s/\bDCFS\b[ \t]+([0-9\.\-]+)/.double $1/;
|
||||||
|
s/\bDCFS[ \t]+0x/.word 0x/;
|
||||||
|
s/\bDCFS\b/.float/;
|
||||||
|
|
||||||
|
s/^([A-Za-z_]\w*)[ \t]+DCD/$1 .word/;
|
||||||
|
s/\bDCD\b/.word/;
|
||||||
|
s/^([A-Za-z_]\w*)[ \t]+DCW/$1 .short/;
|
||||||
|
s/\bDCW\b/.short/;
|
||||||
|
s/^([A-Za-z_]\w*)[ \t]+DCB/$1 .byte/;
|
||||||
|
s/\bDCB\b/.byte/;
|
||||||
|
s/^([A-Za-z_]\w*)[ \t]+\%/.comm $1,/;
|
||||||
|
s/^[A-Za-z_\.]\w+/$&:/;
|
||||||
|
s/^(\d+)/$1:/;
|
||||||
|
s/\%(\d+)/$1b_or_f/;
|
||||||
|
s/\%[Bb](\d+)/$1b/;
|
||||||
|
s/\%[Ff](\d+)/$1f/;
|
||||||
|
s/\%[Ff][Tt](\d+)/$1f/;
|
||||||
|
s/&([\dA-Fa-f]+)/0x$1/;
|
||||||
|
if ( /\b2_[01]+\b/ ) {
|
||||||
|
s/\b2_([01]+)\b/conv$1&&&&/g;
|
||||||
|
while ( /[01][01][01][01]&&&&/ ) {
|
||||||
|
s/0000&&&&/&&&&0/g;
|
||||||
|
s/0001&&&&/&&&&1/g;
|
||||||
|
s/0010&&&&/&&&&2/g;
|
||||||
|
s/0011&&&&/&&&&3/g;
|
||||||
|
s/0100&&&&/&&&&4/g;
|
||||||
|
s/0101&&&&/&&&&5/g;
|
||||||
|
s/0110&&&&/&&&&6/g;
|
||||||
|
s/0111&&&&/&&&&7/g;
|
||||||
|
s/1000&&&&/&&&&8/g;
|
||||||
|
s/1001&&&&/&&&&9/g;
|
||||||
|
s/1010&&&&/&&&&A/g;
|
||||||
|
s/1011&&&&/&&&&B/g;
|
||||||
|
s/1100&&&&/&&&&C/g;
|
||||||
|
s/1101&&&&/&&&&D/g;
|
||||||
|
s/1110&&&&/&&&&E/g;
|
||||||
|
s/1111&&&&/&&&&F/g;
|
||||||
|
}
|
||||||
|
s/000&&&&/&&&&0/g;
|
||||||
|
s/001&&&&/&&&&1/g;
|
||||||
|
s/010&&&&/&&&&2/g;
|
||||||
|
s/011&&&&/&&&&3/g;
|
||||||
|
s/100&&&&/&&&&4/g;
|
||||||
|
s/101&&&&/&&&&5/g;
|
||||||
|
s/110&&&&/&&&&6/g;
|
||||||
|
s/111&&&&/&&&&7/g;
|
||||||
|
s/00&&&&/&&&&0/g;
|
||||||
|
s/01&&&&/&&&&1/g;
|
||||||
|
s/10&&&&/&&&&2/g;
|
||||||
|
s/11&&&&/&&&&3/g;
|
||||||
|
s/0&&&&/&&&&0/g;
|
||||||
|
s/1&&&&/&&&&1/g;
|
||||||
|
s/conv&&&&/0x/g;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( /commandline/)
|
||||||
|
{
|
||||||
|
if( /-bigend/)
|
||||||
|
{
|
||||||
|
$bigend=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( /\bDCDU\b/ )
|
||||||
|
{
|
||||||
|
my $cmd=$_;
|
||||||
|
my $value;
|
||||||
|
my $prefix;
|
||||||
|
my $w1;
|
||||||
|
my $w2;
|
||||||
|
my $w3;
|
||||||
|
my $w4;
|
||||||
|
|
||||||
|
s/\s+DCDU\b/@ $&/;
|
||||||
|
|
||||||
|
$cmd =~ /\bDCDU\b\s+0x(\d+)/;
|
||||||
|
$value = $1;
|
||||||
|
$value =~ /(\w\w)(\w\w)(\w\w)(\w\w)/;
|
||||||
|
$w1 = $1;
|
||||||
|
$w2 = $2;
|
||||||
|
$w3 = $3;
|
||||||
|
$w4 = $4;
|
||||||
|
|
||||||
|
if( $bigend ne "")
|
||||||
|
{
|
||||||
|
# big endian
|
||||||
|
$prefix = "\t.byte\t0x".$w1.";".
|
||||||
|
"\t.byte\t0x".$w2.";".
|
||||||
|
"\t.byte\t0x".$w3.";".
|
||||||
|
"\t.byte\t0x".$w4."; ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
# little endian
|
||||||
|
$prefix = "\t.byte\t0x".$w4.";".
|
||||||
|
"\t.byte\t0x".$w3.";".
|
||||||
|
"\t.byte\t0x".$w2.";".
|
||||||
|
"\t.byte\t0x".$w1."; ";
|
||||||
|
}
|
||||||
|
$_=$prefix.$_;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( /\badrl\b/i )
|
||||||
|
{
|
||||||
|
s/\badrl\s+(\w+)\s*,\s*(\w+)/ldr $1,=$2/i;
|
||||||
|
$addPadding = 1;
|
||||||
|
}
|
||||||
|
s/\bEND\b/@ END/;
|
||||||
|
} continue {
|
||||||
|
printf ("%s", $_) if $printit;
|
||||||
|
if ($addPadding != 0)
|
||||||
|
{
|
||||||
|
printf (" mov r0,r0\n");
|
||||||
|
$addPadding = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#If we had a code section, mark that this object doesn't need an executable
|
||||||
|
# stack.
|
||||||
|
if ($nxstack) {
|
||||||
|
printf (" .section\t.note.GNU-stack,\"\",\%\%progbits\n");
|
||||||
|
}
|
49
code/opus-1.1/celt/arm/arm_celt_map.c
Normal file
49
code/opus-1.1/celt/arm/arm_celt_map.c
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/* Copyright (c) 2010 Xiph.Org Foundation
|
||||||
|
* Copyright (c) 2013 Parrot */
|
||||||
|
/*
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
- Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||||
|
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "pitch.h"
|
||||||
|
|
||||||
|
#if defined(OPUS_HAVE_RTCD)
|
||||||
|
|
||||||
|
# if defined(FIXED_POINT)
|
||||||
|
opus_val32 (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
|
||||||
|
const opus_val16 *, opus_val32 *, int , int) = {
|
||||||
|
celt_pitch_xcorr_c, /* ARMv4 */
|
||||||
|
MAY_HAVE_EDSP(celt_pitch_xcorr), /* EDSP */
|
||||||
|
MAY_HAVE_MEDIA(celt_pitch_xcorr), /* Media */
|
||||||
|
MAY_HAVE_NEON(celt_pitch_xcorr) /* NEON */
|
||||||
|
};
|
||||||
|
# else
|
||||||
|
# error "Floating-point implementation is not supported by ARM asm yet." \
|
||||||
|
"Reconfigure with --disable-rtcd or send patches."
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#endif
|
174
code/opus-1.1/celt/arm/armcpu.c
Normal file
174
code/opus-1.1/celt/arm/armcpu.c
Normal file
|
@ -0,0 +1,174 @@
|
||||||
|
/* Copyright (c) 2010 Xiph.Org Foundation
|
||||||
|
* Copyright (c) 2013 Parrot */
|
||||||
|
/*
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
- Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||||
|
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Original code from libtheora modified to suit to Opus */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OPUS_HAVE_RTCD
|
||||||
|
|
||||||
|
#include "armcpu.h"
|
||||||
|
#include "cpu_support.h"
|
||||||
|
#include "os_support.h"
|
||||||
|
#include "opus_types.h"
|
||||||
|
|
||||||
|
#define OPUS_CPU_ARM_V4 (1)
|
||||||
|
#define OPUS_CPU_ARM_EDSP (1<<1)
|
||||||
|
#define OPUS_CPU_ARM_MEDIA (1<<2)
|
||||||
|
#define OPUS_CPU_ARM_NEON (1<<3)
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
/*For GetExceptionCode() and EXCEPTION_ILLEGAL_INSTRUCTION.*/
|
||||||
|
# define WIN32_LEAN_AND_MEAN
|
||||||
|
# define WIN32_EXTRA_LEAN
|
||||||
|
# include <windows.h>
|
||||||
|
|
||||||
|
static OPUS_INLINE opus_uint32 opus_cpu_capabilities(void){
|
||||||
|
opus_uint32 flags;
|
||||||
|
flags=0;
|
||||||
|
/* MSVC has no OPUS_INLINE __asm support for ARM, but it does let you __emit
|
||||||
|
* instructions via their assembled hex code.
|
||||||
|
* All of these instructions should be essentially nops. */
|
||||||
|
# if defined(OPUS_ARM_MAY_HAVE_EDSP)
|
||||||
|
__try{
|
||||||
|
/*PLD [r13]*/
|
||||||
|
__emit(0xF5DDF000);
|
||||||
|
flags|=OPUS_CPU_ARM_EDSP;
|
||||||
|
}
|
||||||
|
__except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){
|
||||||
|
/*Ignore exception.*/
|
||||||
|
}
|
||||||
|
# if defined(OPUS_ARM_MAY_HAVE_MEDIA)
|
||||||
|
__try{
|
||||||
|
/*SHADD8 r3,r3,r3*/
|
||||||
|
__emit(0xE6333F93);
|
||||||
|
flags|=OPUS_CPU_ARM_MEDIA;
|
||||||
|
}
|
||||||
|
__except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){
|
||||||
|
/*Ignore exception.*/
|
||||||
|
}
|
||||||
|
# if defined(OPUS_ARM_MAY_HAVE_NEON)
|
||||||
|
__try{
|
||||||
|
/*VORR q0,q0,q0*/
|
||||||
|
__emit(0xF2200150);
|
||||||
|
flags|=OPUS_CPU_ARM_NEON;
|
||||||
|
}
|
||||||
|
__except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){
|
||||||
|
/*Ignore exception.*/
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(__linux__)
|
||||||
|
/* Linux based */
|
||||||
|
opus_uint32 opus_cpu_capabilities(void)
|
||||||
|
{
|
||||||
|
opus_uint32 flags = 0;
|
||||||
|
FILE *cpuinfo;
|
||||||
|
|
||||||
|
/* Reading /proc/self/auxv would be easier, but that doesn't work reliably on
|
||||||
|
* Android */
|
||||||
|
cpuinfo = fopen("/proc/cpuinfo", "r");
|
||||||
|
|
||||||
|
if(cpuinfo != NULL)
|
||||||
|
{
|
||||||
|
/* 512 should be enough for anybody (it's even enough for all the flags that
|
||||||
|
* x86 has accumulated... so far). */
|
||||||
|
char buf[512];
|
||||||
|
|
||||||
|
while(fgets(buf, 512, cpuinfo) != NULL)
|
||||||
|
{
|
||||||
|
# if defined(OPUS_ARM_MAY_HAVE_EDSP) || defined(OPUS_ARM_MAY_HAVE_NEON)
|
||||||
|
/* Search for edsp and neon flag */
|
||||||
|
if(memcmp(buf, "Features", 8) == 0)
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
# if defined(OPUS_ARM_MAY_HAVE_EDSP)
|
||||||
|
p = strstr(buf, " edsp");
|
||||||
|
if(p != NULL && (p[5] == ' ' || p[5] == '\n'))
|
||||||
|
flags |= OPUS_CPU_ARM_EDSP;
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if defined(OPUS_ARM_MAY_HAVE_NEON)
|
||||||
|
p = strstr(buf, " neon");
|
||||||
|
if(p != NULL && (p[5] == ' ' || p[5] == '\n'))
|
||||||
|
flags |= OPUS_CPU_ARM_NEON;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if defined(OPUS_ARM_MAY_HAVE_MEDIA)
|
||||||
|
/* Search for media capabilities (>= ARMv6) */
|
||||||
|
if(memcmp(buf, "CPU architecture:", 17) == 0)
|
||||||
|
{
|
||||||
|
int version;
|
||||||
|
version = atoi(buf+17);
|
||||||
|
|
||||||
|
if(version >= 6)
|
||||||
|
flags |= OPUS_CPU_ARM_MEDIA;
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(cpuinfo);
|
||||||
|
}
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* The feature registers which can tell us what the processor supports are
|
||||||
|
* accessible in priveleged modes only, so we can't have a general user-space
|
||||||
|
* detection method like on x86.*/
|
||||||
|
# error "Configured to use ARM asm but no CPU detection method available for " \
|
||||||
|
"your platform. Reconfigure with --disable-rtcd (or send patches)."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int opus_select_arch(void)
|
||||||
|
{
|
||||||
|
opus_uint32 flags = opus_cpu_capabilities();
|
||||||
|
int arch = 0;
|
||||||
|
|
||||||
|
if(!(flags & OPUS_CPU_ARM_EDSP))
|
||||||
|
return arch;
|
||||||
|
arch++;
|
||||||
|
|
||||||
|
if(!(flags & OPUS_CPU_ARM_MEDIA))
|
||||||
|
return arch;
|
||||||
|
arch++;
|
||||||
|
|
||||||
|
if(!(flags & OPUS_CPU_ARM_NEON))
|
||||||
|
return arch;
|
||||||
|
arch++;
|
||||||
|
|
||||||
|
return arch;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
71
code/opus-1.1/celt/arm/armcpu.h
Normal file
71
code/opus-1.1/celt/arm/armcpu.h
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
/* Copyright (c) 2010 Xiph.Org Foundation
|
||||||
|
* Copyright (c) 2013 Parrot */
|
||||||
|
/*
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
- Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||||
|
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(ARMCPU_H)
|
||||||
|
# define ARMCPU_H
|
||||||
|
|
||||||
|
# if defined(OPUS_ARM_MAY_HAVE_EDSP)
|
||||||
|
# define MAY_HAVE_EDSP(name) name ## _edsp
|
||||||
|
# else
|
||||||
|
# define MAY_HAVE_EDSP(name) name ## _c
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if defined(OPUS_ARM_MAY_HAVE_MEDIA)
|
||||||
|
# define MAY_HAVE_MEDIA(name) name ## _media
|
||||||
|
# else
|
||||||
|
# define MAY_HAVE_MEDIA(name) MAY_HAVE_EDSP(name)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if defined(OPUS_ARM_MAY_HAVE_NEON)
|
||||||
|
# define MAY_HAVE_NEON(name) name ## _neon
|
||||||
|
# else
|
||||||
|
# define MAY_HAVE_NEON(name) MAY_HAVE_MEDIA(name)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if defined(OPUS_ARM_PRESUME_EDSP)
|
||||||
|
# define PRESUME_EDSP(name) name ## _edsp
|
||||||
|
# else
|
||||||
|
# define PRESUME_EDSP(name) name ## _c
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if defined(OPUS_ARM_PRESUME_MEDIA)
|
||||||
|
# define PRESUME_MEDIA(name) name ## _media
|
||||||
|
# else
|
||||||
|
# define PRESUME_MEDIA(name) PRESUME_EDSP(name)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if defined(OPUS_ARM_PRESUME_NEON)
|
||||||
|
# define PRESUME_NEON(name) name ## _neon
|
||||||
|
# else
|
||||||
|
# define PRESUME_NEON(name) PRESUME_MEDIA(name)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if defined(OPUS_HAVE_RTCD)
|
||||||
|
int opus_select_arch(void);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,5 +1,4 @@
|
||||||
/* Copyright (c) 2011 Xiph.Org Foundation, Skype Limited
|
/* Copyright (C) 2013 Mozilla Corporation */
|
||||||
Written by Jean-Marc Valin and Koen Vos */
|
|
||||||
/*
|
/*
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions
|
modification, are permitted provided that the following conditions
|
||||||
|
@ -25,23 +24,14 @@
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
; Set the following to 1 if we have EDSP instructions
|
||||||
#include "config.h"
|
; (LDRD/STRD, etc., ARMv5E and later).
|
||||||
#endif
|
OPUS_ARM_MAY_HAVE_EDSP * @OPUS_ARM_MAY_HAVE_EDSP@
|
||||||
|
|
||||||
#include "opus.h"
|
; Set the following to 1 if we have ARMv6 media instructions.
|
||||||
#include "opus_private.h"
|
OPUS_ARM_MAY_HAVE_MEDIA * @OPUS_ARM_MAY_HAVE_MEDIA@
|
||||||
|
|
||||||
int encode_size(int size, unsigned char *data)
|
; Set the following to 1 if we have NEON (some ARMv7)
|
||||||
{
|
OPUS_ARM_MAY_HAVE_NEON * @OPUS_ARM_MAY_HAVE_NEON@
|
||||||
if (size < 252)
|
|
||||||
{
|
|
||||||
data[0] = size;
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
data[0] = 252+(size&0x3);
|
|
||||||
data[1] = (size-(int)data[0])>>2;
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
END
|
545
code/opus-1.1/celt/arm/celt_pitch_xcorr_arm.s
Normal file
545
code/opus-1.1/celt/arm/celt_pitch_xcorr_arm.s
Normal file
|
@ -0,0 +1,545 @@
|
||||||
|
; Copyright (c) 2007-2008 CSIRO
|
||||||
|
; Copyright (c) 2007-2009 Xiph.Org Foundation
|
||||||
|
; Copyright (c) 2013 Parrot
|
||||||
|
; Written by Aurélien Zanelli
|
||||||
|
;
|
||||||
|
; Redistribution and use in source and binary forms, with or without
|
||||||
|
; modification, are permitted provided that the following conditions
|
||||||
|
; are met:
|
||||||
|
;
|
||||||
|
; - Redistributions of source code must retain the above copyright
|
||||||
|
; notice, this list of conditions and the following disclaimer.
|
||||||
|
;
|
||||||
|
; - Redistributions in binary form must reproduce the above copyright
|
||||||
|
; notice, this list of conditions and the following disclaimer in the
|
||||||
|
; documentation and/or other materials provided with the distribution.
|
||||||
|
;
|
||||||
|
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
; ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||||
|
; OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
AREA |.text|, CODE, READONLY
|
||||||
|
|
||||||
|
GET celt/arm/armopts.s
|
||||||
|
|
||||||
|
IF OPUS_ARM_MAY_HAVE_EDSP
|
||||||
|
EXPORT celt_pitch_xcorr_edsp
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
IF OPUS_ARM_MAY_HAVE_NEON
|
||||||
|
EXPORT celt_pitch_xcorr_neon
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
IF OPUS_ARM_MAY_HAVE_NEON
|
||||||
|
|
||||||
|
; Compute sum[k]=sum(x[j]*y[j+k],j=0...len-1), k=0...3
|
||||||
|
xcorr_kernel_neon PROC
|
||||||
|
; input:
|
||||||
|
; r3 = int len
|
||||||
|
; r4 = opus_val16 *x
|
||||||
|
; r5 = opus_val16 *y
|
||||||
|
; q0 = opus_val32 sum[4]
|
||||||
|
; output:
|
||||||
|
; q0 = opus_val32 sum[4]
|
||||||
|
; preserved: r0-r3, r6-r11, d2, q4-q7, q9-q15
|
||||||
|
; internal usage:
|
||||||
|
; r12 = int j
|
||||||
|
; d3 = y_3|y_2|y_1|y_0
|
||||||
|
; q2 = y_B|y_A|y_9|y_8|y_7|y_6|y_5|y_4
|
||||||
|
; q3 = x_7|x_6|x_5|x_4|x_3|x_2|x_1|x_0
|
||||||
|
; q8 = scratch
|
||||||
|
;
|
||||||
|
; Load y[0...3]
|
||||||
|
; This requires len>0 to always be valid (which we assert in the C code).
|
||||||
|
VLD1.16 {d5}, [r5]!
|
||||||
|
SUBS r12, r3, #8
|
||||||
|
BLE xcorr_kernel_neon_process4
|
||||||
|
; Process 8 samples at a time.
|
||||||
|
; This loop loads one y value more than we actually need. Therefore we have to
|
||||||
|
; stop as soon as there are 8 or fewer samples left (instead of 7), to avoid
|
||||||
|
; reading past the end of the array.
|
||||||
|
xcorr_kernel_neon_process8
|
||||||
|
; This loop has 19 total instructions (10 cycles to issue, minimum), with
|
||||||
|
; - 2 cycles of ARM insrtuctions,
|
||||||
|
; - 10 cycles of load/store/byte permute instructions, and
|
||||||
|
; - 9 cycles of data processing instructions.
|
||||||
|
; On a Cortex A8, we dual-issue the maximum amount (9 cycles) between the
|
||||||
|
; latter two categories, meaning the whole loop should run in 10 cycles per
|
||||||
|
; iteration, barring cache misses.
|
||||||
|
;
|
||||||
|
; Load x[0...7]
|
||||||
|
VLD1.16 {d6, d7}, [r4]!
|
||||||
|
; Unlike VMOV, VAND is a data processsing instruction (and doesn't get
|
||||||
|
; assembled to VMOV, like VORR would), so it dual-issues with the prior VLD1.
|
||||||
|
VAND d3, d5, d5
|
||||||
|
SUBS r12, r12, #8
|
||||||
|
; Load y[4...11]
|
||||||
|
VLD1.16 {d4, d5}, [r5]!
|
||||||
|
VMLAL.S16 q0, d3, d6[0]
|
||||||
|
VEXT.16 d16, d3, d4, #1
|
||||||
|
VMLAL.S16 q0, d4, d7[0]
|
||||||
|
VEXT.16 d17, d4, d5, #1
|
||||||
|
VMLAL.S16 q0, d16, d6[1]
|
||||||
|
VEXT.16 d16, d3, d4, #2
|
||||||
|
VMLAL.S16 q0, d17, d7[1]
|
||||||
|
VEXT.16 d17, d4, d5, #2
|
||||||
|
VMLAL.S16 q0, d16, d6[2]
|
||||||
|
VEXT.16 d16, d3, d4, #3
|
||||||
|
VMLAL.S16 q0, d17, d7[2]
|
||||||
|
VEXT.16 d17, d4, d5, #3
|
||||||
|
VMLAL.S16 q0, d16, d6[3]
|
||||||
|
VMLAL.S16 q0, d17, d7[3]
|
||||||
|
BGT xcorr_kernel_neon_process8
|
||||||
|
; Process 4 samples here if we have > 4 left (still reading one extra y value).
|
||||||
|
xcorr_kernel_neon_process4
|
||||||
|
ADDS r12, r12, #4
|
||||||
|
BLE xcorr_kernel_neon_process2
|
||||||
|
; Load x[0...3]
|
||||||
|
VLD1.16 d6, [r4]!
|
||||||
|
; Use VAND since it's a data processing instruction again.
|
||||||
|
VAND d4, d5, d5
|
||||||
|
SUB r12, r12, #4
|
||||||
|
; Load y[4...7]
|
||||||
|
VLD1.16 d5, [r5]!
|
||||||
|
VMLAL.S16 q0, d4, d6[0]
|
||||||
|
VEXT.16 d16, d4, d5, #1
|
||||||
|
VMLAL.S16 q0, d16, d6[1]
|
||||||
|
VEXT.16 d16, d4, d5, #2
|
||||||
|
VMLAL.S16 q0, d16, d6[2]
|
||||||
|
VEXT.16 d16, d4, d5, #3
|
||||||
|
VMLAL.S16 q0, d16, d6[3]
|
||||||
|
; Process 2 samples here if we have > 2 left (still reading one extra y value).
|
||||||
|
xcorr_kernel_neon_process2
|
||||||
|
ADDS r12, r12, #2
|
||||||
|
BLE xcorr_kernel_neon_process1
|
||||||
|
; Load x[0...1]
|
||||||
|
VLD2.16 {d6[],d7[]}, [r4]!
|
||||||
|
; Use VAND since it's a data processing instruction again.
|
||||||
|
VAND d4, d5, d5
|
||||||
|
SUB r12, r12, #2
|
||||||
|
; Load y[4...5]
|
||||||
|
VLD1.32 {d5[]}, [r5]!
|
||||||
|
VMLAL.S16 q0, d4, d6
|
||||||
|
VEXT.16 d16, d4, d5, #1
|
||||||
|
; Replace bottom copy of {y5,y4} in d5 with {y3,y2} from d4, using VSRI
|
||||||
|
; instead of VEXT, since it's a data-processing instruction.
|
||||||
|
VSRI.64 d5, d4, #32
|
||||||
|
VMLAL.S16 q0, d16, d7
|
||||||
|
; Process 1 sample using the extra y value we loaded above.
|
||||||
|
xcorr_kernel_neon_process1
|
||||||
|
; Load next *x
|
||||||
|
VLD1.16 {d6[]}, [r4]!
|
||||||
|
ADDS r12, r12, #1
|
||||||
|
; y[0...3] are left in d5 from prior iteration(s) (if any)
|
||||||
|
VMLAL.S16 q0, d5, d6
|
||||||
|
MOVLE pc, lr
|
||||||
|
; Now process 1 last sample, not reading ahead.
|
||||||
|
; Load last *y
|
||||||
|
VLD1.16 {d4[]}, [r5]!
|
||||||
|
VSRI.64 d4, d5, #16
|
||||||
|
; Load last *x
|
||||||
|
VLD1.16 {d6[]}, [r4]!
|
||||||
|
VMLAL.S16 q0, d4, d6
|
||||||
|
MOV pc, lr
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
; opus_val32 celt_pitch_xcorr_neon(opus_val16 *_x, opus_val16 *_y,
|
||||||
|
; opus_val32 *xcorr, int len, int max_pitch)
|
||||||
|
celt_pitch_xcorr_neon PROC
|
||||||
|
; input:
|
||||||
|
; r0 = opus_val16 *_x
|
||||||
|
; r1 = opus_val16 *_y
|
||||||
|
; r2 = opus_val32 *xcorr
|
||||||
|
; r3 = int len
|
||||||
|
; output:
|
||||||
|
; r0 = int maxcorr
|
||||||
|
; internal usage:
|
||||||
|
; r4 = opus_val16 *x (for xcorr_kernel_neon())
|
||||||
|
; r5 = opus_val16 *y (for xcorr_kernel_neon())
|
||||||
|
; r6 = int max_pitch
|
||||||
|
; r12 = int j
|
||||||
|
; q15 = int maxcorr[4] (q15 is not used by xcorr_kernel_neon())
|
||||||
|
STMFD sp!, {r4-r6, lr}
|
||||||
|
LDR r6, [sp, #16]
|
||||||
|
VMOV.S32 q15, #1
|
||||||
|
; if (max_pitch < 4) goto celt_pitch_xcorr_neon_process4_done
|
||||||
|
SUBS r6, r6, #4
|
||||||
|
BLT celt_pitch_xcorr_neon_process4_done
|
||||||
|
celt_pitch_xcorr_neon_process4
|
||||||
|
; xcorr_kernel_neon parameters:
|
||||||
|
; r3 = len, r4 = _x, r5 = _y, q0 = {0, 0, 0, 0}
|
||||||
|
MOV r4, r0
|
||||||
|
MOV r5, r1
|
||||||
|
VEOR q0, q0, q0
|
||||||
|
; xcorr_kernel_neon only modifies r4, r5, r12, and q0...q3.
|
||||||
|
; So we don't save/restore any other registers.
|
||||||
|
BL xcorr_kernel_neon
|
||||||
|
SUBS r6, r6, #4
|
||||||
|
VST1.32 {q0}, [r2]!
|
||||||
|
; _y += 4
|
||||||
|
ADD r1, r1, #8
|
||||||
|
VMAX.S32 q15, q15, q0
|
||||||
|
; if (max_pitch < 4) goto celt_pitch_xcorr_neon_process4_done
|
||||||
|
BGE celt_pitch_xcorr_neon_process4
|
||||||
|
; We have less than 4 sums left to compute.
|
||||||
|
celt_pitch_xcorr_neon_process4_done
|
||||||
|
ADDS r6, r6, #4
|
||||||
|
; Reduce maxcorr to a single value
|
||||||
|
VMAX.S32 d30, d30, d31
|
||||||
|
VPMAX.S32 d30, d30, d30
|
||||||
|
; if (max_pitch <= 0) goto celt_pitch_xcorr_neon_done
|
||||||
|
BLE celt_pitch_xcorr_neon_done
|
||||||
|
; Now compute each remaining sum one at a time.
|
||||||
|
celt_pitch_xcorr_neon_process_remaining
|
||||||
|
MOV r4, r0
|
||||||
|
MOV r5, r1
|
||||||
|
VMOV.I32 q0, #0
|
||||||
|
SUBS r12, r3, #8
|
||||||
|
BLT celt_pitch_xcorr_neon_process_remaining4
|
||||||
|
; Sum terms 8 at a time.
|
||||||
|
celt_pitch_xcorr_neon_process_remaining_loop8
|
||||||
|
; Load x[0...7]
|
||||||
|
VLD1.16 {q1}, [r4]!
|
||||||
|
; Load y[0...7]
|
||||||
|
VLD1.16 {q2}, [r5]!
|
||||||
|
SUBS r12, r12, #8
|
||||||
|
VMLAL.S16 q0, d4, d2
|
||||||
|
VMLAL.S16 q0, d5, d3
|
||||||
|
BGE celt_pitch_xcorr_neon_process_remaining_loop8
|
||||||
|
; Sum terms 4 at a time.
|
||||||
|
celt_pitch_xcorr_neon_process_remaining4
|
||||||
|
ADDS r12, r12, #4
|
||||||
|
BLT celt_pitch_xcorr_neon_process_remaining4_done
|
||||||
|
; Load x[0...3]
|
||||||
|
VLD1.16 {d2}, [r4]!
|
||||||
|
; Load y[0...3]
|
||||||
|
VLD1.16 {d3}, [r5]!
|
||||||
|
SUB r12, r12, #4
|
||||||
|
VMLAL.S16 q0, d3, d2
|
||||||
|
celt_pitch_xcorr_neon_process_remaining4_done
|
||||||
|
; Reduce the sum to a single value.
|
||||||
|
VADD.S32 d0, d0, d1
|
||||||
|
VPADDL.S32 d0, d0
|
||||||
|
ADDS r12, r12, #4
|
||||||
|
BLE celt_pitch_xcorr_neon_process_remaining_loop_done
|
||||||
|
; Sum terms 1 at a time.
|
||||||
|
celt_pitch_xcorr_neon_process_remaining_loop1
|
||||||
|
VLD1.16 {d2[]}, [r4]!
|
||||||
|
VLD1.16 {d3[]}, [r5]!
|
||||||
|
SUBS r12, r12, #1
|
||||||
|
VMLAL.S16 q0, d2, d3
|
||||||
|
BGT celt_pitch_xcorr_neon_process_remaining_loop1
|
||||||
|
celt_pitch_xcorr_neon_process_remaining_loop_done
|
||||||
|
VST1.32 {d0[0]}, [r2]!
|
||||||
|
VMAX.S32 d30, d30, d0
|
||||||
|
SUBS r6, r6, #1
|
||||||
|
; _y++
|
||||||
|
ADD r1, r1, #2
|
||||||
|
; if (--max_pitch > 0) goto celt_pitch_xcorr_neon_process_remaining
|
||||||
|
BGT celt_pitch_xcorr_neon_process_remaining
|
||||||
|
celt_pitch_xcorr_neon_done
|
||||||
|
VMOV.32 r0, d30[0]
|
||||||
|
LDMFD sp!, {r4-r6, pc}
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
IF OPUS_ARM_MAY_HAVE_EDSP
|
||||||
|
|
||||||
|
; This will get used on ARMv7 devices without NEON, so it has been optimized
|
||||||
|
; to take advantage of dual-issuing where possible.
|
||||||
|
xcorr_kernel_edsp PROC
|
||||||
|
; input:
|
||||||
|
; r3 = int len
|
||||||
|
; r4 = opus_val16 *_x (must be 32-bit aligned)
|
||||||
|
; r5 = opus_val16 *_y (must be 32-bit aligned)
|
||||||
|
; r6...r9 = opus_val32 sum[4]
|
||||||
|
; output:
|
||||||
|
; r6...r9 = opus_val32 sum[4]
|
||||||
|
; preserved: r0-r5
|
||||||
|
; internal usage
|
||||||
|
; r2 = int j
|
||||||
|
; r12,r14 = opus_val16 x[4]
|
||||||
|
; r10,r11 = opus_val16 y[4]
|
||||||
|
STMFD sp!, {r2,r4,r5,lr}
|
||||||
|
LDR r10, [r5], #4 ; Load y[0...1]
|
||||||
|
SUBS r2, r3, #4 ; j = len-4
|
||||||
|
LDR r11, [r5], #4 ; Load y[2...3]
|
||||||
|
BLE xcorr_kernel_edsp_process4_done
|
||||||
|
LDR r12, [r4], #4 ; Load x[0...1]
|
||||||
|
; Stall
|
||||||
|
xcorr_kernel_edsp_process4
|
||||||
|
; The multiplies must issue from pipeline 0, and can't dual-issue with each
|
||||||
|
; other. Every other instruction here dual-issues with a multiply, and is
|
||||||
|
; thus "free". There should be no stalls in the body of the loop.
|
||||||
|
SMLABB r6, r12, r10, r6 ; sum[0] = MAC16_16(sum[0],x_0,y_0)
|
||||||
|
LDR r14, [r4], #4 ; Load x[2...3]
|
||||||
|
SMLABT r7, r12, r10, r7 ; sum[1] = MAC16_16(sum[1],x_0,y_1)
|
||||||
|
SUBS r2, r2, #4 ; j-=4
|
||||||
|
SMLABB r8, r12, r11, r8 ; sum[2] = MAC16_16(sum[2],x_0,y_2)
|
||||||
|
SMLABT r9, r12, r11, r9 ; sum[3] = MAC16_16(sum[3],x_0,y_3)
|
||||||
|
SMLATT r6, r12, r10, r6 ; sum[0] = MAC16_16(sum[0],x_1,y_1)
|
||||||
|
LDR r10, [r5], #4 ; Load y[4...5]
|
||||||
|
SMLATB r7, r12, r11, r7 ; sum[1] = MAC16_16(sum[1],x_1,y_2)
|
||||||
|
SMLATT r8, r12, r11, r8 ; sum[2] = MAC16_16(sum[2],x_1,y_3)
|
||||||
|
SMLATB r9, r12, r10, r9 ; sum[3] = MAC16_16(sum[3],x_1,y_4)
|
||||||
|
LDRGT r12, [r4], #4 ; Load x[0...1]
|
||||||
|
SMLABB r6, r14, r11, r6 ; sum[0] = MAC16_16(sum[0],x_2,y_2)
|
||||||
|
SMLABT r7, r14, r11, r7 ; sum[1] = MAC16_16(sum[1],x_2,y_3)
|
||||||
|
SMLABB r8, r14, r10, r8 ; sum[2] = MAC16_16(sum[2],x_2,y_4)
|
||||||
|
SMLABT r9, r14, r10, r9 ; sum[3] = MAC16_16(sum[3],x_2,y_5)
|
||||||
|
SMLATT r6, r14, r11, r6 ; sum[0] = MAC16_16(sum[0],x_3,y_3)
|
||||||
|
LDR r11, [r5], #4 ; Load y[6...7]
|
||||||
|
SMLATB r7, r14, r10, r7 ; sum[1] = MAC16_16(sum[1],x_3,y_4)
|
||||||
|
SMLATT r8, r14, r10, r8 ; sum[2] = MAC16_16(sum[2],x_3,y_5)
|
||||||
|
SMLATB r9, r14, r11, r9 ; sum[3] = MAC16_16(sum[3],x_3,y_6)
|
||||||
|
BGT xcorr_kernel_edsp_process4
|
||||||
|
xcorr_kernel_edsp_process4_done
|
||||||
|
ADDS r2, r2, #4
|
||||||
|
BLE xcorr_kernel_edsp_done
|
||||||
|
LDRH r12, [r4], #2 ; r12 = *x++
|
||||||
|
SUBS r2, r2, #1 ; j--
|
||||||
|
; Stall
|
||||||
|
SMLABB r6, r12, r10, r6 ; sum[0] = MAC16_16(sum[0],x,y_0)
|
||||||
|
LDRGTH r14, [r4], #2 ; r14 = *x++
|
||||||
|
SMLABT r7, r12, r10, r7 ; sum[1] = MAC16_16(sum[1],x,y_1)
|
||||||
|
SMLABB r8, r12, r11, r8 ; sum[2] = MAC16_16(sum[2],x,y_2)
|
||||||
|
SMLABT r9, r12, r11, r9 ; sum[3] = MAC16_16(sum[3],x,y_3)
|
||||||
|
BLE xcorr_kernel_edsp_done
|
||||||
|
SMLABT r6, r14, r10, r6 ; sum[0] = MAC16_16(sum[0],x,y_1)
|
||||||
|
SUBS r2, r2, #1 ; j--
|
||||||
|
SMLABB r7, r14, r11, r7 ; sum[1] = MAC16_16(sum[1],x,y_2)
|
||||||
|
LDRH r10, [r5], #2 ; r10 = y_4 = *y++
|
||||||
|
SMLABT r8, r14, r11, r8 ; sum[2] = MAC16_16(sum[2],x,y_3)
|
||||||
|
LDRGTH r12, [r4], #2 ; r12 = *x++
|
||||||
|
SMLABB r9, r14, r10, r9 ; sum[3] = MAC16_16(sum[3],x,y_4)
|
||||||
|
BLE xcorr_kernel_edsp_done
|
||||||
|
SMLABB r6, r12, r11, r6 ; sum[0] = MAC16_16(sum[0],tmp,y_2)
|
||||||
|
CMP r2, #1 ; j--
|
||||||
|
SMLABT r7, r12, r11, r7 ; sum[1] = MAC16_16(sum[1],tmp,y_3)
|
||||||
|
LDRH r2, [r5], #2 ; r2 = y_5 = *y++
|
||||||
|
SMLABB r8, r12, r10, r8 ; sum[2] = MAC16_16(sum[2],tmp,y_4)
|
||||||
|
LDRGTH r14, [r4] ; r14 = *x
|
||||||
|
SMLABB r9, r12, r2, r9 ; sum[3] = MAC16_16(sum[3],tmp,y_5)
|
||||||
|
BLE xcorr_kernel_edsp_done
|
||||||
|
SMLABT r6, r14, r11, r6 ; sum[0] = MAC16_16(sum[0],tmp,y_3)
|
||||||
|
LDRH r11, [r5] ; r11 = y_6 = *y
|
||||||
|
SMLABB r7, r14, r10, r7 ; sum[1] = MAC16_16(sum[1],tmp,y_4)
|
||||||
|
SMLABB r8, r14, r2, r8 ; sum[2] = MAC16_16(sum[2],tmp,y_5)
|
||||||
|
SMLABB r9, r14, r11, r9 ; sum[3] = MAC16_16(sum[3],tmp,y_6)
|
||||||
|
xcorr_kernel_edsp_done
|
||||||
|
LDMFD sp!, {r2,r4,r5,pc}
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
celt_pitch_xcorr_edsp PROC
|
||||||
|
; input:
|
||||||
|
; r0 = opus_val16 *_x (must be 32-bit aligned)
|
||||||
|
; r1 = opus_val16 *_y (only needs to be 16-bit aligned)
|
||||||
|
; r2 = opus_val32 *xcorr
|
||||||
|
; r3 = int len
|
||||||
|
; output:
|
||||||
|
; r0 = maxcorr
|
||||||
|
; internal usage
|
||||||
|
; r4 = opus_val16 *x
|
||||||
|
; r5 = opus_val16 *y
|
||||||
|
; r6 = opus_val32 sum0
|
||||||
|
; r7 = opus_val32 sum1
|
||||||
|
; r8 = opus_val32 sum2
|
||||||
|
; r9 = opus_val32 sum3
|
||||||
|
; r1 = int max_pitch
|
||||||
|
; r12 = int j
|
||||||
|
STMFD sp!, {r4-r11, lr}
|
||||||
|
MOV r5, r1
|
||||||
|
LDR r1, [sp, #36]
|
||||||
|
MOV r4, r0
|
||||||
|
TST r5, #3
|
||||||
|
; maxcorr = 1
|
||||||
|
MOV r0, #1
|
||||||
|
BEQ celt_pitch_xcorr_edsp_process1u_done
|
||||||
|
; Compute one sum at the start to make y 32-bit aligned.
|
||||||
|
SUBS r12, r3, #4
|
||||||
|
; r14 = sum = 0
|
||||||
|
MOV r14, #0
|
||||||
|
LDRH r8, [r5], #2
|
||||||
|
BLE celt_pitch_xcorr_edsp_process1u_loop4_done
|
||||||
|
LDR r6, [r4], #4
|
||||||
|
MOV r8, r8, LSL #16
|
||||||
|
celt_pitch_xcorr_edsp_process1u_loop4
|
||||||
|
LDR r9, [r5], #4
|
||||||
|
SMLABT r14, r6, r8, r14 ; sum = MAC16_16(sum, x_0, y_0)
|
||||||
|
LDR r7, [r4], #4
|
||||||
|
SMLATB r14, r6, r9, r14 ; sum = MAC16_16(sum, x_1, y_1)
|
||||||
|
LDR r8, [r5], #4
|
||||||
|
SMLABT r14, r7, r9, r14 ; sum = MAC16_16(sum, x_2, y_2)
|
||||||
|
SUBS r12, r12, #4 ; j-=4
|
||||||
|
SMLATB r14, r7, r8, r14 ; sum = MAC16_16(sum, x_3, y_3)
|
||||||
|
LDRGT r6, [r4], #4
|
||||||
|
BGT celt_pitch_xcorr_edsp_process1u_loop4
|
||||||
|
MOV r8, r8, LSR #16
|
||||||
|
celt_pitch_xcorr_edsp_process1u_loop4_done
|
||||||
|
ADDS r12, r12, #4
|
||||||
|
celt_pitch_xcorr_edsp_process1u_loop1
|
||||||
|
LDRGEH r6, [r4], #2
|
||||||
|
; Stall
|
||||||
|
SMLABBGE r14, r6, r8, r14 ; sum = MAC16_16(sum, *x, *y)
|
||||||
|
SUBGES r12, r12, #1
|
||||||
|
LDRGTH r8, [r5], #2
|
||||||
|
BGT celt_pitch_xcorr_edsp_process1u_loop1
|
||||||
|
; Restore _x
|
||||||
|
SUB r4, r4, r3, LSL #1
|
||||||
|
; Restore and advance _y
|
||||||
|
SUB r5, r5, r3, LSL #1
|
||||||
|
; maxcorr = max(maxcorr, sum)
|
||||||
|
CMP r0, r14
|
||||||
|
ADD r5, r5, #2
|
||||||
|
MOVLT r0, r14
|
||||||
|
SUBS r1, r1, #1
|
||||||
|
; xcorr[i] = sum
|
||||||
|
STR r14, [r2], #4
|
||||||
|
BLE celt_pitch_xcorr_edsp_done
|
||||||
|
celt_pitch_xcorr_edsp_process1u_done
|
||||||
|
; if (max_pitch < 4) goto celt_pitch_xcorr_edsp_process2
|
||||||
|
SUBS r1, r1, #4
|
||||||
|
BLT celt_pitch_xcorr_edsp_process2
|
||||||
|
celt_pitch_xcorr_edsp_process4
|
||||||
|
; xcorr_kernel_edsp parameters:
|
||||||
|
; r3 = len, r4 = _x, r5 = _y, r6...r9 = sum[4] = {0, 0, 0, 0}
|
||||||
|
MOV r6, #0
|
||||||
|
MOV r7, #0
|
||||||
|
MOV r8, #0
|
||||||
|
MOV r9, #0
|
||||||
|
BL xcorr_kernel_edsp ; xcorr_kernel_edsp(_x, _y+i, xcorr+i, len)
|
||||||
|
; maxcorr = max(maxcorr, sum0, sum1, sum2, sum3)
|
||||||
|
CMP r0, r6
|
||||||
|
; _y+=4
|
||||||
|
ADD r5, r5, #8
|
||||||
|
MOVLT r0, r6
|
||||||
|
CMP r0, r7
|
||||||
|
MOVLT r0, r7
|
||||||
|
CMP r0, r8
|
||||||
|
MOVLT r0, r8
|
||||||
|
CMP r0, r9
|
||||||
|
MOVLT r0, r9
|
||||||
|
STMIA r2!, {r6-r9}
|
||||||
|
SUBS r1, r1, #4
|
||||||
|
BGE celt_pitch_xcorr_edsp_process4
|
||||||
|
celt_pitch_xcorr_edsp_process2
|
||||||
|
ADDS r1, r1, #2
|
||||||
|
BLT celt_pitch_xcorr_edsp_process1a
|
||||||
|
SUBS r12, r3, #4
|
||||||
|
; {r10, r11} = {sum0, sum1} = {0, 0}
|
||||||
|
MOV r10, #0
|
||||||
|
MOV r11, #0
|
||||||
|
LDR r8, [r5], #4
|
||||||
|
BLE celt_pitch_xcorr_edsp_process2_loop_done
|
||||||
|
LDR r6, [r4], #4
|
||||||
|
LDR r9, [r5], #4
|
||||||
|
celt_pitch_xcorr_edsp_process2_loop4
|
||||||
|
SMLABB r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_0, y_0)
|
||||||
|
LDR r7, [r4], #4
|
||||||
|
SMLABT r11, r6, r8, r11 ; sum1 = MAC16_16(sum1, x_0, y_1)
|
||||||
|
SUBS r12, r12, #4 ; j-=4
|
||||||
|
SMLATT r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_1, y_1)
|
||||||
|
LDR r8, [r5], #4
|
||||||
|
SMLATB r11, r6, r9, r11 ; sum1 = MAC16_16(sum1, x_1, y_2)
|
||||||
|
LDRGT r6, [r4], #4
|
||||||
|
SMLABB r10, r7, r9, r10 ; sum0 = MAC16_16(sum0, x_2, y_2)
|
||||||
|
SMLABT r11, r7, r9, r11 ; sum1 = MAC16_16(sum1, x_2, y_3)
|
||||||
|
SMLATT r10, r7, r9, r10 ; sum0 = MAC16_16(sum0, x_3, y_3)
|
||||||
|
LDRGT r9, [r5], #4
|
||||||
|
SMLATB r11, r7, r8, r11 ; sum1 = MAC16_16(sum1, x_3, y_4)
|
||||||
|
BGT celt_pitch_xcorr_edsp_process2_loop4
|
||||||
|
celt_pitch_xcorr_edsp_process2_loop_done
|
||||||
|
ADDS r12, r12, #2
|
||||||
|
BLE celt_pitch_xcorr_edsp_process2_1
|
||||||
|
LDR r6, [r4], #4
|
||||||
|
; Stall
|
||||||
|
SMLABB r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_0, y_0)
|
||||||
|
LDR r9, [r5], #4
|
||||||
|
SMLABT r11, r6, r8, r11 ; sum1 = MAC16_16(sum1, x_0, y_1)
|
||||||
|
SUB r12, r12, #2
|
||||||
|
SMLATT r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_1, y_1)
|
||||||
|
MOV r8, r9
|
||||||
|
SMLATB r11, r6, r9, r11 ; sum1 = MAC16_16(sum1, x_1, y_2)
|
||||||
|
celt_pitch_xcorr_edsp_process2_1
|
||||||
|
LDRH r6, [r4], #2
|
||||||
|
ADDS r12, r12, #1
|
||||||
|
; Stall
|
||||||
|
SMLABB r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_0, y_0)
|
||||||
|
LDRGTH r7, [r4], #2
|
||||||
|
SMLABT r11, r6, r8, r11 ; sum1 = MAC16_16(sum1, x_0, y_1)
|
||||||
|
BLE celt_pitch_xcorr_edsp_process2_done
|
||||||
|
LDRH r9, [r5], #2
|
||||||
|
SMLABT r10, r7, r8, r10 ; sum0 = MAC16_16(sum0, x_0, y_1)
|
||||||
|
SMLABB r11, r7, r9, r11 ; sum1 = MAC16_16(sum1, x_0, y_2)
|
||||||
|
celt_pitch_xcorr_edsp_process2_done
|
||||||
|
; Restore _x
|
||||||
|
SUB r4, r4, r3, LSL #1
|
||||||
|
; Restore and advance _y
|
||||||
|
SUB r5, r5, r3, LSL #1
|
||||||
|
; maxcorr = max(maxcorr, sum0)
|
||||||
|
CMP r0, r10
|
||||||
|
ADD r5, r5, #2
|
||||||
|
MOVLT r0, r10
|
||||||
|
SUB r1, r1, #2
|
||||||
|
; maxcorr = max(maxcorr, sum1)
|
||||||
|
CMP r0, r11
|
||||||
|
; xcorr[i] = sum
|
||||||
|
STR r10, [r2], #4
|
||||||
|
MOVLT r0, r11
|
||||||
|
STR r11, [r2], #4
|
||||||
|
celt_pitch_xcorr_edsp_process1a
|
||||||
|
ADDS r1, r1, #1
|
||||||
|
BLT celt_pitch_xcorr_edsp_done
|
||||||
|
SUBS r12, r3, #4
|
||||||
|
; r14 = sum = 0
|
||||||
|
MOV r14, #0
|
||||||
|
BLT celt_pitch_xcorr_edsp_process1a_loop_done
|
||||||
|
LDR r6, [r4], #4
|
||||||
|
LDR r8, [r5], #4
|
||||||
|
LDR r7, [r4], #4
|
||||||
|
LDR r9, [r5], #4
|
||||||
|
celt_pitch_xcorr_edsp_process1a_loop4
|
||||||
|
SMLABB r14, r6, r8, r14 ; sum = MAC16_16(sum, x_0, y_0)
|
||||||
|
SUBS r12, r12, #4 ; j-=4
|
||||||
|
SMLATT r14, r6, r8, r14 ; sum = MAC16_16(sum, x_1, y_1)
|
||||||
|
LDRGE r6, [r4], #4
|
||||||
|
SMLABB r14, r7, r9, r14 ; sum = MAC16_16(sum, x_2, y_2)
|
||||||
|
LDRGE r8, [r5], #4
|
||||||
|
SMLATT r14, r7, r9, r14 ; sum = MAC16_16(sum, x_3, y_3)
|
||||||
|
LDRGE r7, [r4], #4
|
||||||
|
LDRGE r9, [r5], #4
|
||||||
|
BGE celt_pitch_xcorr_edsp_process1a_loop4
|
||||||
|
celt_pitch_xcorr_edsp_process1a_loop_done
|
||||||
|
ADDS r12, r12, #2
|
||||||
|
LDRGE r6, [r4], #4
|
||||||
|
LDRGE r8, [r5], #4
|
||||||
|
; Stall
|
||||||
|
SMLABBGE r14, r6, r8, r14 ; sum = MAC16_16(sum, x_0, y_0)
|
||||||
|
SUBGE r12, r12, #2
|
||||||
|
SMLATTGE r14, r6, r8, r14 ; sum = MAC16_16(sum, x_1, y_1)
|
||||||
|
ADDS r12, r12, #1
|
||||||
|
LDRGEH r6, [r4], #2
|
||||||
|
LDRGEH r8, [r5], #2
|
||||||
|
; Stall
|
||||||
|
SMLABBGE r14, r6, r8, r14 ; sum = MAC16_16(sum, *x, *y)
|
||||||
|
; maxcorr = max(maxcorr, sum)
|
||||||
|
CMP r0, r14
|
||||||
|
; xcorr[i] = sum
|
||||||
|
STR r14, [r2], #4
|
||||||
|
MOVLT r0, r14
|
||||||
|
celt_pitch_xcorr_edsp_done
|
||||||
|
LDMFD sp!, {r4-r11, pc}
|
||||||
|
ENDP
|
||||||
|
|
||||||
|
ENDIF
|
||||||
|
|
||||||
|
END
|
76
code/opus-1.1/celt/arm/fixed_armv4.h
Normal file
76
code/opus-1.1/celt/arm/fixed_armv4.h
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
/* Copyright (C) 2013 Xiph.Org Foundation and contributors */
|
||||||
|
/*
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
- Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||||
|
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FIXED_ARMv4_H
|
||||||
|
#define FIXED_ARMv4_H
|
||||||
|
|
||||||
|
/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */
|
||||||
|
#undef MULT16_32_Q16
|
||||||
|
static OPUS_INLINE opus_val32 MULT16_32_Q16_armv4(opus_val16 a, opus_val32 b)
|
||||||
|
{
|
||||||
|
unsigned rd_lo;
|
||||||
|
int rd_hi;
|
||||||
|
__asm__(
|
||||||
|
"#MULT16_32_Q16\n\t"
|
||||||
|
"smull %0, %1, %2, %3\n\t"
|
||||||
|
: "=&r"(rd_lo), "=&r"(rd_hi)
|
||||||
|
: "%r"(b),"r"(a<<16)
|
||||||
|
);
|
||||||
|
return rd_hi;
|
||||||
|
}
|
||||||
|
#define MULT16_32_Q16(a, b) (MULT16_32_Q16_armv4(a, b))
|
||||||
|
|
||||||
|
|
||||||
|
/** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */
|
||||||
|
#undef MULT16_32_Q15
|
||||||
|
static OPUS_INLINE opus_val32 MULT16_32_Q15_armv4(opus_val16 a, opus_val32 b)
|
||||||
|
{
|
||||||
|
unsigned rd_lo;
|
||||||
|
int rd_hi;
|
||||||
|
__asm__(
|
||||||
|
"#MULT16_32_Q15\n\t"
|
||||||
|
"smull %0, %1, %2, %3\n\t"
|
||||||
|
: "=&r"(rd_lo), "=&r"(rd_hi)
|
||||||
|
: "%r"(b), "r"(a<<16)
|
||||||
|
);
|
||||||
|
/*We intentionally don't OR in the high bit of rd_lo for speed.*/
|
||||||
|
return rd_hi<<1;
|
||||||
|
}
|
||||||
|
#define MULT16_32_Q15(a, b) (MULT16_32_Q15_armv4(a, b))
|
||||||
|
|
||||||
|
|
||||||
|
/** 16x32 multiply, followed by a 15-bit shift right and 32-bit add.
|
||||||
|
b must fit in 31 bits.
|
||||||
|
Result fits in 32 bits. */
|
||||||
|
#undef MAC16_32_Q15
|
||||||
|
#define MAC16_32_Q15(c, a, b) ADD32(c, MULT16_32_Q15(a, b))
|
||||||
|
|
||||||
|
|
||||||
|
/** 32x32 multiplication, followed by a 31-bit shift right. Results fits in 32 bits */
|
||||||
|
#undef MULT32_32_Q31
|
||||||
|
#define MULT32_32_Q31(a,b) (opus_val32)((((opus_int64)(a)) * ((opus_int64)(b)))>>31)
|
||||||
|
|
||||||
|
#endif
|
116
code/opus-1.1/celt/arm/fixed_armv5e.h
Normal file
116
code/opus-1.1/celt/arm/fixed_armv5e.h
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
/* Copyright (C) 2007-2009 Xiph.Org Foundation
|
||||||
|
Copyright (C) 2003-2008 Jean-Marc Valin
|
||||||
|
Copyright (C) 2007-2008 CSIRO
|
||||||
|
Copyright (C) 2013 Parrot */
|
||||||
|
/*
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
- Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||||
|
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FIXED_ARMv5E_H
|
||||||
|
#define FIXED_ARMv5E_H
|
||||||
|
|
||||||
|
#include "fixed_armv4.h"
|
||||||
|
|
||||||
|
/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */
|
||||||
|
#undef MULT16_32_Q16
|
||||||
|
static OPUS_INLINE opus_val32 MULT16_32_Q16_armv5e(opus_val16 a, opus_val32 b)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
__asm__(
|
||||||
|
"#MULT16_32_Q16\n\t"
|
||||||
|
"smulwb %0, %1, %2\n\t"
|
||||||
|
: "=r"(res)
|
||||||
|
: "r"(b),"r"(a)
|
||||||
|
);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#define MULT16_32_Q16(a, b) (MULT16_32_Q16_armv5e(a, b))
|
||||||
|
|
||||||
|
|
||||||
|
/** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */
|
||||||
|
#undef MULT16_32_Q15
|
||||||
|
static OPUS_INLINE opus_val32 MULT16_32_Q15_armv5e(opus_val16 a, opus_val32 b)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
__asm__(
|
||||||
|
"#MULT16_32_Q15\n\t"
|
||||||
|
"smulwb %0, %1, %2\n\t"
|
||||||
|
: "=r"(res)
|
||||||
|
: "r"(b), "r"(a)
|
||||||
|
);
|
||||||
|
return res<<1;
|
||||||
|
}
|
||||||
|
#define MULT16_32_Q15(a, b) (MULT16_32_Q15_armv5e(a, b))
|
||||||
|
|
||||||
|
|
||||||
|
/** 16x32 multiply, followed by a 15-bit shift right and 32-bit add.
|
||||||
|
b must fit in 31 bits.
|
||||||
|
Result fits in 32 bits. */
|
||||||
|
#undef MAC16_32_Q15
|
||||||
|
static OPUS_INLINE opus_val32 MAC16_32_Q15_armv5e(opus_val32 c, opus_val16 a,
|
||||||
|
opus_val32 b)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
__asm__(
|
||||||
|
"#MAC16_32_Q15\n\t"
|
||||||
|
"smlawb %0, %1, %2, %3;\n"
|
||||||
|
: "=r"(res)
|
||||||
|
: "r"(b<<1), "r"(a), "r"(c)
|
||||||
|
);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#define MAC16_32_Q15(c, a, b) (MAC16_32_Q15_armv5e(c, a, b))
|
||||||
|
|
||||||
|
/** 16x16 multiply-add where the result fits in 32 bits */
|
||||||
|
#undef MAC16_16
|
||||||
|
static OPUS_INLINE opus_val32 MAC16_16_armv5e(opus_val32 c, opus_val16 a,
|
||||||
|
opus_val16 b)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
__asm__(
|
||||||
|
"#MAC16_16\n\t"
|
||||||
|
"smlabb %0, %1, %2, %3;\n"
|
||||||
|
: "=r"(res)
|
||||||
|
: "r"(a), "r"(b), "r"(c)
|
||||||
|
);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#define MAC16_16(c, a, b) (MAC16_16_armv5e(c, a, b))
|
||||||
|
|
||||||
|
/** 16x16 multiplication where the result fits in 32 bits */
|
||||||
|
#undef MULT16_16
|
||||||
|
static OPUS_INLINE opus_val32 MULT16_16_armv5e(opus_val16 a, opus_val16 b)
|
||||||
|
{
|
||||||
|
int res;
|
||||||
|
__asm__(
|
||||||
|
"#MULT16_16\n\t"
|
||||||
|
"smulbb %0, %1, %2;\n"
|
||||||
|
: "=r"(res)
|
||||||
|
: "r"(a), "r"(b)
|
||||||
|
);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#define MULT16_16(a, b) (MULT16_16_armv5e(a, b))
|
||||||
|
|
||||||
|
#endif
|
121
code/opus-1.1/celt/arm/kiss_fft_armv4.h
Normal file
121
code/opus-1.1/celt/arm/kiss_fft_armv4.h
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
/*Copyright (c) 2013, Xiph.Org Foundation and contributors.
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.*/
|
||||||
|
|
||||||
|
#ifndef KISS_FFT_ARMv4_H
|
||||||
|
#define KISS_FFT_ARMv4_H
|
||||||
|
|
||||||
|
#if !defined(KISS_FFT_GUTS_H)
|
||||||
|
#error "This file should only be included from _kiss_fft_guts.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef FIXED_POINT
|
||||||
|
|
||||||
|
#undef C_MUL
|
||||||
|
#define C_MUL(m,a,b) \
|
||||||
|
do{ \
|
||||||
|
int br__; \
|
||||||
|
int bi__; \
|
||||||
|
int tt__; \
|
||||||
|
__asm__ __volatile__( \
|
||||||
|
"#C_MUL\n\t" \
|
||||||
|
"ldrsh %[br], [%[bp], #0]\n\t" \
|
||||||
|
"ldm %[ap], {r0,r1}\n\t" \
|
||||||
|
"ldrsh %[bi], [%[bp], #2]\n\t" \
|
||||||
|
"smull %[tt], %[mi], r1, %[br]\n\t" \
|
||||||
|
"smlal %[tt], %[mi], r0, %[bi]\n\t" \
|
||||||
|
"rsb %[bi], %[bi], #0\n\t" \
|
||||||
|
"smull %[br], %[mr], r0, %[br]\n\t" \
|
||||||
|
"mov %[tt], %[tt], lsr #15\n\t" \
|
||||||
|
"smlal %[br], %[mr], r1, %[bi]\n\t" \
|
||||||
|
"orr %[mi], %[tt], %[mi], lsl #17\n\t" \
|
||||||
|
"mov %[br], %[br], lsr #15\n\t" \
|
||||||
|
"orr %[mr], %[br], %[mr], lsl #17\n\t" \
|
||||||
|
: [mr]"=r"((m).r), [mi]"=r"((m).i), \
|
||||||
|
[br]"=&r"(br__), [bi]"=r"(bi__), [tt]"=r"(tt__) \
|
||||||
|
: [ap]"r"(&(a)), [bp]"r"(&(b)) \
|
||||||
|
: "r0", "r1" \
|
||||||
|
); \
|
||||||
|
} \
|
||||||
|
while(0)
|
||||||
|
|
||||||
|
#undef C_MUL4
|
||||||
|
#define C_MUL4(m,a,b) \
|
||||||
|
do{ \
|
||||||
|
int br__; \
|
||||||
|
int bi__; \
|
||||||
|
int tt__; \
|
||||||
|
__asm__ __volatile__( \
|
||||||
|
"#C_MUL4\n\t" \
|
||||||
|
"ldrsh %[br], [%[bp], #0]\n\t" \
|
||||||
|
"ldm %[ap], {r0,r1}\n\t" \
|
||||||
|
"ldrsh %[bi], [%[bp], #2]\n\t" \
|
||||||
|
"smull %[tt], %[mi], r1, %[br]\n\t" \
|
||||||
|
"smlal %[tt], %[mi], r0, %[bi]\n\t" \
|
||||||
|
"rsb %[bi], %[bi], #0\n\t" \
|
||||||
|
"smull %[br], %[mr], r0, %[br]\n\t" \
|
||||||
|
"mov %[tt], %[tt], lsr #17\n\t" \
|
||||||
|
"smlal %[br], %[mr], r1, %[bi]\n\t" \
|
||||||
|
"orr %[mi], %[tt], %[mi], lsl #15\n\t" \
|
||||||
|
"mov %[br], %[br], lsr #17\n\t" \
|
||||||
|
"orr %[mr], %[br], %[mr], lsl #15\n\t" \
|
||||||
|
: [mr]"=r"((m).r), [mi]"=r"((m).i), \
|
||||||
|
[br]"=&r"(br__), [bi]"=r"(bi__), [tt]"=r"(tt__) \
|
||||||
|
: [ap]"r"(&(a)), [bp]"r"(&(b)) \
|
||||||
|
: "r0", "r1" \
|
||||||
|
); \
|
||||||
|
} \
|
||||||
|
while(0)
|
||||||
|
|
||||||
|
#undef C_MULC
|
||||||
|
#define C_MULC(m,a,b) \
|
||||||
|
do{ \
|
||||||
|
int br__; \
|
||||||
|
int bi__; \
|
||||||
|
int tt__; \
|
||||||
|
__asm__ __volatile__( \
|
||||||
|
"#C_MULC\n\t" \
|
||||||
|
"ldrsh %[br], [%[bp], #0]\n\t" \
|
||||||
|
"ldm %[ap], {r0,r1}\n\t" \
|
||||||
|
"ldrsh %[bi], [%[bp], #2]\n\t" \
|
||||||
|
"smull %[tt], %[mr], r0, %[br]\n\t" \
|
||||||
|
"smlal %[tt], %[mr], r1, %[bi]\n\t" \
|
||||||
|
"rsb %[bi], %[bi], #0\n\t" \
|
||||||
|
"smull %[br], %[mi], r1, %[br]\n\t" \
|
||||||
|
"mov %[tt], %[tt], lsr #15\n\t" \
|
||||||
|
"smlal %[br], %[mi], r0, %[bi]\n\t" \
|
||||||
|
"orr %[mr], %[tt], %[mr], lsl #17\n\t" \
|
||||||
|
"mov %[br], %[br], lsr #15\n\t" \
|
||||||
|
"orr %[mi], %[br], %[mi], lsl #17\n\t" \
|
||||||
|
: [mr]"=r"((m).r), [mi]"=r"((m).i), \
|
||||||
|
[br]"=&r"(br__), [bi]"=r"(bi__), [tt]"=r"(tt__) \
|
||||||
|
: [ap]"r"(&(a)), [bp]"r"(&(b)) \
|
||||||
|
: "r0", "r1" \
|
||||||
|
); \
|
||||||
|
} \
|
||||||
|
while(0)
|
||||||
|
|
||||||
|
#endif /* FIXED_POINT */
|
||||||
|
|
||||||
|
#endif /* KISS_FFT_ARMv4_H */
|
118
code/opus-1.1/celt/arm/kiss_fft_armv5e.h
Normal file
118
code/opus-1.1/celt/arm/kiss_fft_armv5e.h
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
/*Copyright (c) 2013, Xiph.Org Foundation and contributors.
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.*/
|
||||||
|
|
||||||
|
#ifndef KISS_FFT_ARMv5E_H
|
||||||
|
#define KISS_FFT_ARMv5E_H
|
||||||
|
|
||||||
|
#if !defined(KISS_FFT_GUTS_H)
|
||||||
|
#error "This file should only be included from _kiss_fft_guts.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef FIXED_POINT
|
||||||
|
|
||||||
|
#if defined(__thumb__)||defined(__thumb2__)
|
||||||
|
#define LDRD_CONS "Q"
|
||||||
|
#else
|
||||||
|
#define LDRD_CONS "Uq"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef C_MUL
|
||||||
|
#define C_MUL(m,a,b) \
|
||||||
|
do{ \
|
||||||
|
int mr1__; \
|
||||||
|
int mr2__; \
|
||||||
|
int mi__; \
|
||||||
|
long long aval__; \
|
||||||
|
int bval__; \
|
||||||
|
__asm__( \
|
||||||
|
"#C_MUL\n\t" \
|
||||||
|
"ldrd %[aval], %H[aval], %[ap]\n\t" \
|
||||||
|
"ldr %[bval], %[bp]\n\t" \
|
||||||
|
"smulwb %[mi], %H[aval], %[bval]\n\t" \
|
||||||
|
"smulwb %[mr1], %[aval], %[bval]\n\t" \
|
||||||
|
"smulwt %[mr2], %H[aval], %[bval]\n\t" \
|
||||||
|
"smlawt %[mi], %[aval], %[bval], %[mi]\n\t" \
|
||||||
|
: [mr1]"=r"(mr1__), [mr2]"=r"(mr2__), [mi]"=r"(mi__), \
|
||||||
|
[aval]"=&r"(aval__), [bval]"=r"(bval__) \
|
||||||
|
: [ap]LDRD_CONS(a), [bp]"m"(b) \
|
||||||
|
); \
|
||||||
|
(m).r = SHL32(SUB32(mr1__, mr2__), 1); \
|
||||||
|
(m).i = SHL32(mi__, 1); \
|
||||||
|
} \
|
||||||
|
while(0)
|
||||||
|
|
||||||
|
#undef C_MUL4
|
||||||
|
#define C_MUL4(m,a,b) \
|
||||||
|
do{ \
|
||||||
|
int mr1__; \
|
||||||
|
int mr2__; \
|
||||||
|
int mi__; \
|
||||||
|
long long aval__; \
|
||||||
|
int bval__; \
|
||||||
|
__asm__( \
|
||||||
|
"#C_MUL4\n\t" \
|
||||||
|
"ldrd %[aval], %H[aval], %[ap]\n\t" \
|
||||||
|
"ldr %[bval], %[bp]\n\t" \
|
||||||
|
"smulwb %[mi], %H[aval], %[bval]\n\t" \
|
||||||
|
"smulwb %[mr1], %[aval], %[bval]\n\t" \
|
||||||
|
"smulwt %[mr2], %H[aval], %[bval]\n\t" \
|
||||||
|
"smlawt %[mi], %[aval], %[bval], %[mi]\n\t" \
|
||||||
|
: [mr1]"=r"(mr1__), [mr2]"=r"(mr2__), [mi]"=r"(mi__), \
|
||||||
|
[aval]"=&r"(aval__), [bval]"=r"(bval__) \
|
||||||
|
: [ap]LDRD_CONS(a), [bp]"m"(b) \
|
||||||
|
); \
|
||||||
|
(m).r = SHR32(SUB32(mr1__, mr2__), 1); \
|
||||||
|
(m).i = SHR32(mi__, 1); \
|
||||||
|
} \
|
||||||
|
while(0)
|
||||||
|
|
||||||
|
#undef C_MULC
|
||||||
|
#define C_MULC(m,a,b) \
|
||||||
|
do{ \
|
||||||
|
int mr__; \
|
||||||
|
int mi1__; \
|
||||||
|
int mi2__; \
|
||||||
|
long long aval__; \
|
||||||
|
int bval__; \
|
||||||
|
__asm__( \
|
||||||
|
"#C_MULC\n\t" \
|
||||||
|
"ldrd %[aval], %H[aval], %[ap]\n\t" \
|
||||||
|
"ldr %[bval], %[bp]\n\t" \
|
||||||
|
"smulwb %[mr], %[aval], %[bval]\n\t" \
|
||||||
|
"smulwb %[mi1], %H[aval], %[bval]\n\t" \
|
||||||
|
"smulwt %[mi2], %[aval], %[bval]\n\t" \
|
||||||
|
"smlawt %[mr], %H[aval], %[bval], %[mr]\n\t" \
|
||||||
|
: [mr]"=r"(mr__), [mi1]"=r"(mi1__), [mi2]"=r"(mi2__), \
|
||||||
|
[aval]"=&r"(aval__), [bval]"=r"(bval__) \
|
||||||
|
: [ap]LDRD_CONS(a), [bp]"m"(b) \
|
||||||
|
); \
|
||||||
|
(m).r = SHL32(mr__, 1); \
|
||||||
|
(m).i = SHL32(SUB32(mi1__, mi2__), 1); \
|
||||||
|
} \
|
||||||
|
while(0)
|
||||||
|
|
||||||
|
#endif /* FIXED_POINT */
|
||||||
|
|
||||||
|
#endif /* KISS_FFT_GUTS_H */
|
57
code/opus-1.1/celt/arm/pitch_arm.h
Normal file
57
code/opus-1.1/celt/arm/pitch_arm.h
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/* Copyright (c) 2010 Xiph.Org Foundation
|
||||||
|
* Copyright (c) 2013 Parrot */
|
||||||
|
/*
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
- Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||||
|
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(PITCH_ARM_H)
|
||||||
|
# define PITCH_ARM_H
|
||||||
|
|
||||||
|
# include "armcpu.h"
|
||||||
|
|
||||||
|
# if defined(FIXED_POINT)
|
||||||
|
|
||||||
|
# if defined(OPUS_ARM_MAY_HAVE_NEON)
|
||||||
|
opus_val32 celt_pitch_xcorr_neon(const opus_val16 *_x, const opus_val16 *_y,
|
||||||
|
opus_val32 *xcorr, int len, int max_pitch);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if defined(OPUS_ARM_MAY_HAVE_MEDIA)
|
||||||
|
# define celt_pitch_xcorr_media MAY_HAVE_EDSP(celt_pitch_xcorr)
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if defined(OPUS_ARM_MAY_HAVE_EDSP)
|
||||||
|
opus_val32 celt_pitch_xcorr_edsp(const opus_val16 *_x, const opus_val16 *_y,
|
||||||
|
opus_val32 *xcorr, int len, int max_pitch);
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# if !defined(OPUS_HAVE_RTCD)
|
||||||
|
# define OVERRIDE_PITCH_XCORR (1)
|
||||||
|
# define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
|
||||||
|
((void)(arch),PRESUME_NEON(celt_pitch_xcorr)(_x, _y, xcorr, len, max_pitch))
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#endif
|
File diff suppressed because it is too large
Load diff
|
@ -39,7 +39,7 @@
|
||||||
/** Compute the amplitude (sqrt energy) in each of the bands
|
/** Compute the amplitude (sqrt energy) in each of the bands
|
||||||
* @param m Mode data
|
* @param m Mode data
|
||||||
* @param X Spectrum
|
* @param X Spectrum
|
||||||
* @param bands Square root of the energy for each band (returned)
|
* @param bandE Square root of the energy for each band (returned)
|
||||||
*/
|
*/
|
||||||
void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int M);
|
void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int M);
|
||||||
|
|
||||||
|
@ -49,16 +49,17 @@ void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *band
|
||||||
equal to 1
|
equal to 1
|
||||||
* @param m Mode data
|
* @param m Mode data
|
||||||
* @param X Spectrum (returned normalised)
|
* @param X Spectrum (returned normalised)
|
||||||
* @param bands Square root of the energy for each band
|
* @param bandE Square root of the energy for each band
|
||||||
*/
|
*/
|
||||||
void normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, celt_norm * OPUS_RESTRICT X, const celt_ener *bandE, int end, int C, int M);
|
void normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, celt_norm * OPUS_RESTRICT X, const celt_ener *bandE, int end, int C, int M);
|
||||||
|
|
||||||
/** Denormalise each band of X to restore full amplitude
|
/** Denormalise each band of X to restore full amplitude
|
||||||
* @param m Mode data
|
* @param m Mode data
|
||||||
* @param X Spectrum (returned de-normalised)
|
* @param X Spectrum (returned de-normalised)
|
||||||
* @param bands Square root of the energy for each band
|
* @param bandE Square root of the energy for each band
|
||||||
*/
|
*/
|
||||||
void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X, celt_sig * OPUS_RESTRICT freq, const celt_ener *bandE, int end, int C, int M);
|
void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X,
|
||||||
|
celt_sig * OPUS_RESTRICT freq, const opus_val16 *bandE, int start, int end, int C, int M);
|
||||||
|
|
||||||
#define SPREAD_NONE (0)
|
#define SPREAD_NONE (0)
|
||||||
#define SPREAD_LIGHT (1)
|
#define SPREAD_LIGHT (1)
|
||||||
|
@ -76,14 +77,30 @@ void measure_norm_mse(const CELTMode *m, float *X, float *X0, float *bandE, floa
|
||||||
void haar1(celt_norm *X, int N0, int stride);
|
void haar1(celt_norm *X, int N0, int stride);
|
||||||
|
|
||||||
/** Quantisation/encoding of the residual spectrum
|
/** Quantisation/encoding of the residual spectrum
|
||||||
|
* @param encode flag that indicates whether we're encoding (1) or decoding (0)
|
||||||
* @param m Mode data
|
* @param m Mode data
|
||||||
|
* @param start First band to process
|
||||||
|
* @param end Last band to process + 1
|
||||||
* @param X Residual (normalised)
|
* @param X Residual (normalised)
|
||||||
|
* @param Y Residual (normalised) for second channel (or NULL for mono)
|
||||||
|
* @param collapse_masks Anti-collapse tracking mask
|
||||||
|
* @param bandE Square root of the energy for each band
|
||||||
|
* @param pulses Bit allocation (per band) for PVQ
|
||||||
|
* @param shortBlocks Zero for long blocks, non-zero for short blocks
|
||||||
|
* @param spread Amount of spreading to use
|
||||||
|
* @param dual_stereo Zero for MS stereo, non-zero for dual stereo
|
||||||
|
* @param intensity First band to use intensity stereo
|
||||||
|
* @param tf_res Time-frequency resolution change
|
||||||
* @param total_bits Total number of bits that can be used for the frame (including the ones already spent)
|
* @param total_bits Total number of bits that can be used for the frame (including the ones already spent)
|
||||||
* @param enc Entropy encoder
|
* @param balance Number of unallocated bits
|
||||||
|
* @param en Entropy coder state
|
||||||
|
* @param LM log2() of the number of 2.5 subframes in the frame
|
||||||
|
* @param codedBands Last band to receive bits + 1
|
||||||
|
* @param seed Random generator seed
|
||||||
*/
|
*/
|
||||||
void quant_all_bands(int encode, const CELTMode *m, int start, int end,
|
void quant_all_bands(int encode, const CELTMode *m, int start, int end,
|
||||||
celt_norm * X, celt_norm * Y, unsigned char *collapse_masks, const celt_ener *bandE, int *pulses,
|
celt_norm * X, celt_norm * Y, unsigned char *collapse_masks, const celt_ener *bandE, int *pulses,
|
||||||
int time_domain, int fold, int dual_stereo, int intensity, int *tf_res,
|
int shortBlocks, int spread, int dual_stereo, int intensity, int *tf_res,
|
||||||
opus_int32 total_bits, opus_int32 balance, ec_ctx *ec, int M, int codedBands, opus_uint32 *seed);
|
opus_int32 total_bits, opus_int32 balance, ec_ctx *ec, int M, int codedBands, opus_uint32 *seed);
|
||||||
|
|
||||||
void anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_masks, int LM, int C, int size,
|
void anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_masks, int LM, int C, int size,
|
||||||
|
@ -92,4 +109,6 @@ void anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_mas
|
||||||
|
|
||||||
opus_uint32 celt_lcg_rand(opus_uint32 seed);
|
opus_uint32 celt_lcg_rand(opus_uint32 seed);
|
||||||
|
|
||||||
|
int hysteresis_decision(opus_val16 val, const opus_val16 *thresholds, const opus_val16 *hysteresis, int N, int prev);
|
||||||
|
|
||||||
#endif /* BANDS_H */
|
#endif /* BANDS_H */
|
223
code/opus-1.1/celt/celt.c
Normal file
223
code/opus-1.1/celt/celt.c
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
/* Copyright (c) 2007-2008 CSIRO
|
||||||
|
Copyright (c) 2007-2010 Xiph.Org Foundation
|
||||||
|
Copyright (c) 2008 Gregory Maxwell
|
||||||
|
Written by Jean-Marc Valin and Gregory Maxwell */
|
||||||
|
/*
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
- Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||||
|
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CELT_C
|
||||||
|
|
||||||
|
#include "os_support.h"
|
||||||
|
#include "mdct.h"
|
||||||
|
#include <math.h>
|
||||||
|
#include "celt.h"
|
||||||
|
#include "pitch.h"
|
||||||
|
#include "bands.h"
|
||||||
|
#include "modes.h"
|
||||||
|
#include "entcode.h"
|
||||||
|
#include "quant_bands.h"
|
||||||
|
#include "rate.h"
|
||||||
|
#include "stack_alloc.h"
|
||||||
|
#include "mathops.h"
|
||||||
|
#include "float_cast.h"
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include "celt_lpc.h"
|
||||||
|
#include "vq.h"
|
||||||
|
|
||||||
|
#ifndef PACKAGE_VERSION
|
||||||
|
#define PACKAGE_VERSION "unknown"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
int resampling_factor(opus_int32 rate)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
switch (rate)
|
||||||
|
{
|
||||||
|
case 48000:
|
||||||
|
ret = 1;
|
||||||
|
break;
|
||||||
|
case 24000:
|
||||||
|
ret = 2;
|
||||||
|
break;
|
||||||
|
case 16000:
|
||||||
|
ret = 3;
|
||||||
|
break;
|
||||||
|
case 12000:
|
||||||
|
ret = 4;
|
||||||
|
break;
|
||||||
|
case 8000:
|
||||||
|
ret = 6;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
#ifndef CUSTOM_MODES
|
||||||
|
celt_assert(0);
|
||||||
|
#endif
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef OVERRIDE_COMB_FILTER_CONST
|
||||||
|
static void comb_filter_const(opus_val32 *y, opus_val32 *x, int T, int N,
|
||||||
|
opus_val16 g10, opus_val16 g11, opus_val16 g12)
|
||||||
|
{
|
||||||
|
opus_val32 x0, x1, x2, x3, x4;
|
||||||
|
int i;
|
||||||
|
x4 = x[-T-2];
|
||||||
|
x3 = x[-T-1];
|
||||||
|
x2 = x[-T];
|
||||||
|
x1 = x[-T+1];
|
||||||
|
for (i=0;i<N;i++)
|
||||||
|
{
|
||||||
|
x0=x[i-T+2];
|
||||||
|
y[i] = x[i]
|
||||||
|
+ MULT16_32_Q15(g10,x2)
|
||||||
|
+ MULT16_32_Q15(g11,ADD32(x1,x3))
|
||||||
|
+ MULT16_32_Q15(g12,ADD32(x0,x4));
|
||||||
|
x4=x3;
|
||||||
|
x3=x2;
|
||||||
|
x2=x1;
|
||||||
|
x1=x0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
|
||||||
|
opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,
|
||||||
|
const opus_val16 *window, int overlap)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
/* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
|
||||||
|
opus_val16 g00, g01, g02, g10, g11, g12;
|
||||||
|
opus_val32 x0, x1, x2, x3, x4;
|
||||||
|
static const opus_val16 gains[3][3] = {
|
||||||
|
{QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},
|
||||||
|
{QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},
|
||||||
|
{QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}};
|
||||||
|
|
||||||
|
if (g0==0 && g1==0)
|
||||||
|
{
|
||||||
|
/* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
|
||||||
|
if (x!=y)
|
||||||
|
OPUS_MOVE(y, x, N);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g00 = MULT16_16_Q15(g0, gains[tapset0][0]);
|
||||||
|
g01 = MULT16_16_Q15(g0, gains[tapset0][1]);
|
||||||
|
g02 = MULT16_16_Q15(g0, gains[tapset0][2]);
|
||||||
|
g10 = MULT16_16_Q15(g1, gains[tapset1][0]);
|
||||||
|
g11 = MULT16_16_Q15(g1, gains[tapset1][1]);
|
||||||
|
g12 = MULT16_16_Q15(g1, gains[tapset1][2]);
|
||||||
|
x1 = x[-T1+1];
|
||||||
|
x2 = x[-T1 ];
|
||||||
|
x3 = x[-T1-1];
|
||||||
|
x4 = x[-T1-2];
|
||||||
|
for (i=0;i<overlap;i++)
|
||||||
|
{
|
||||||
|
opus_val16 f;
|
||||||
|
x0=x[i-T1+2];
|
||||||
|
f = MULT16_16_Q15(window[i],window[i]);
|
||||||
|
y[i] = x[i]
|
||||||
|
+ MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g00),x[i-T0])
|
||||||
|
+ MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g01),ADD32(x[i-T0+1],x[i-T0-1]))
|
||||||
|
+ MULT16_32_Q15(MULT16_16_Q15((Q15ONE-f),g02),ADD32(x[i-T0+2],x[i-T0-2]))
|
||||||
|
+ MULT16_32_Q15(MULT16_16_Q15(f,g10),x2)
|
||||||
|
+ MULT16_32_Q15(MULT16_16_Q15(f,g11),ADD32(x1,x3))
|
||||||
|
+ MULT16_32_Q15(MULT16_16_Q15(f,g12),ADD32(x0,x4));
|
||||||
|
x4=x3;
|
||||||
|
x3=x2;
|
||||||
|
x2=x1;
|
||||||
|
x1=x0;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (g1==0)
|
||||||
|
{
|
||||||
|
/* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
|
||||||
|
if (x!=y)
|
||||||
|
OPUS_MOVE(y+overlap, x+overlap, N-overlap);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute the part with the constant filter. */
|
||||||
|
comb_filter_const(y+i, x+i, T1, N-i, g10, g11, g12);
|
||||||
|
}
|
||||||
|
|
||||||
|
const signed char tf_select_table[4][8] = {
|
||||||
|
{0, -1, 0, -1, 0,-1, 0,-1},
|
||||||
|
{0, -1, 0, -2, 1, 0, 1,-1},
|
||||||
|
{0, -2, 0, -3, 2, 0, 1,-1},
|
||||||
|
{0, -2, 0, -3, 3, 0, 1,-1},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void init_caps(const CELTMode *m,int *cap,int LM,int C)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i=0;i<m->nbEBands;i++)
|
||||||
|
{
|
||||||
|
int N;
|
||||||
|
N=(m->eBands[i+1]-m->eBands[i])<<LM;
|
||||||
|
cap[i] = (m->cache.caps[m->nbEBands*(2*LM+C-1)+i]+64)*C*N>>2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const char *opus_strerror(int error)
|
||||||
|
{
|
||||||
|
static const char * const error_strings[8] = {
|
||||||
|
"success",
|
||||||
|
"invalid argument",
|
||||||
|
"buffer too small",
|
||||||
|
"internal error",
|
||||||
|
"corrupted stream",
|
||||||
|
"request not implemented",
|
||||||
|
"invalid state",
|
||||||
|
"memory allocation failed"
|
||||||
|
};
|
||||||
|
if (error > 0 || error < -7)
|
||||||
|
return "unknown error";
|
||||||
|
else
|
||||||
|
return error_strings[-error];
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *opus_get_version_string(void)
|
||||||
|
{
|
||||||
|
return "libopus " PACKAGE_VERSION
|
||||||
|
#ifdef FIXED_POINT
|
||||||
|
"-fixed"
|
||||||
|
#endif
|
||||||
|
#ifdef FUZZING
|
||||||
|
"-fuzzing"
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
}
|
|
@ -50,10 +50,26 @@ extern "C" {
|
||||||
#define CELTDecoder OpusCustomDecoder
|
#define CELTDecoder OpusCustomDecoder
|
||||||
#define CELTMode OpusCustomMode
|
#define CELTMode OpusCustomMode
|
||||||
|
|
||||||
#define _celt_check_mode_ptr_ptr(ptr) ((ptr) + ((ptr) - (const CELTMode**)(ptr)))
|
typedef struct {
|
||||||
|
int valid;
|
||||||
|
float tonality;
|
||||||
|
float tonality_slope;
|
||||||
|
float noisiness;
|
||||||
|
float activity;
|
||||||
|
float music_prob;
|
||||||
|
int bandwidth;
|
||||||
|
}AnalysisInfo;
|
||||||
|
|
||||||
|
#define __celt_check_mode_ptr_ptr(ptr) ((ptr) + ((ptr) - (const CELTMode**)(ptr)))
|
||||||
|
|
||||||
|
#define __celt_check_analysis_ptr(ptr) ((ptr) + ((ptr) - (const AnalysisInfo*)(ptr)))
|
||||||
|
|
||||||
/* Encoder/decoder Requests */
|
/* Encoder/decoder Requests */
|
||||||
|
|
||||||
|
/* Expose this option again when variable framesize actually works */
|
||||||
|
#define OPUS_FRAMESIZE_VARIABLE 5010 /**< Optimize the frame size dynamically */
|
||||||
|
|
||||||
|
|
||||||
#define CELT_SET_PREDICTION_REQUEST 10002
|
#define CELT_SET_PREDICTION_REQUEST 10002
|
||||||
/** Controls the use of interframe prediction.
|
/** Controls the use of interframe prediction.
|
||||||
0=Independent frames
|
0=Independent frames
|
||||||
|
@ -81,12 +97,24 @@ extern "C" {
|
||||||
|
|
||||||
#define CELT_GET_MODE_REQUEST 10015
|
#define CELT_GET_MODE_REQUEST 10015
|
||||||
/** Get the CELTMode used by an encoder or decoder */
|
/** Get the CELTMode used by an encoder or decoder */
|
||||||
#define CELT_GET_MODE(x) CELT_GET_MODE_REQUEST, _celt_check_mode_ptr_ptr(x)
|
#define CELT_GET_MODE(x) CELT_GET_MODE_REQUEST, __celt_check_mode_ptr_ptr(x)
|
||||||
|
|
||||||
#define CELT_SET_SIGNALLING_REQUEST 10016
|
#define CELT_SET_SIGNALLING_REQUEST 10016
|
||||||
#define CELT_SET_SIGNALLING(x) CELT_SET_SIGNALLING_REQUEST, __opus_check_int(x)
|
#define CELT_SET_SIGNALLING(x) CELT_SET_SIGNALLING_REQUEST, __opus_check_int(x)
|
||||||
|
|
||||||
|
#define CELT_SET_TONALITY_REQUEST 10018
|
||||||
|
#define CELT_SET_TONALITY(x) CELT_SET_TONALITY_REQUEST, __opus_check_int(x)
|
||||||
|
#define CELT_SET_TONALITY_SLOPE_REQUEST 10020
|
||||||
|
#define CELT_SET_TONALITY_SLOPE(x) CELT_SET_TONALITY_SLOPE_REQUEST, __opus_check_int(x)
|
||||||
|
|
||||||
|
#define CELT_SET_ANALYSIS_REQUEST 10022
|
||||||
|
#define CELT_SET_ANALYSIS(x) CELT_SET_ANALYSIS_REQUEST, __celt_check_analysis_ptr(x)
|
||||||
|
|
||||||
|
#define OPUS_SET_LFE_REQUEST 10024
|
||||||
|
#define OPUS_SET_LFE(x) OPUS_SET_LFE_REQUEST, __opus_check_int(x)
|
||||||
|
|
||||||
|
#define OPUS_SET_ENERGY_MASK_REQUEST 10026
|
||||||
|
#define OPUS_SET_ENERGY_MASK(x) OPUS_SET_ENERGY_MASK_REQUEST, __opus_check_val16_ptr(x)
|
||||||
|
|
||||||
/* Encoder stuff */
|
/* Encoder stuff */
|
||||||
|
|
||||||
|
@ -94,7 +122,8 @@ int celt_encoder_get_size(int channels);
|
||||||
|
|
||||||
int celt_encode_with_ec(OpusCustomEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc);
|
int celt_encode_with_ec(OpusCustomEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc);
|
||||||
|
|
||||||
int celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels);
|
int celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels,
|
||||||
|
int arch);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -110,6 +139,78 @@ int celt_decode_with_ec(OpusCustomDecoder * OPUS_RESTRICT st, const unsigned cha
|
||||||
#define celt_encoder_ctl opus_custom_encoder_ctl
|
#define celt_encoder_ctl opus_custom_encoder_ctl
|
||||||
#define celt_decoder_ctl opus_custom_decoder_ctl
|
#define celt_decoder_ctl opus_custom_decoder_ctl
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef CUSTOM_MODES
|
||||||
|
#define OPUS_CUSTOM_NOSTATIC
|
||||||
|
#else
|
||||||
|
#define OPUS_CUSTOM_NOSTATIC static OPUS_INLINE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const unsigned char trim_icdf[11] = {126, 124, 119, 109, 87, 41, 19, 9, 4, 2, 0};
|
||||||
|
/* Probs: NONE: 21.875%, LIGHT: 6.25%, NORMAL: 65.625%, AGGRESSIVE: 6.25% */
|
||||||
|
static const unsigned char spread_icdf[4] = {25, 23, 2, 0};
|
||||||
|
|
||||||
|
static const unsigned char tapset_icdf[3]={2,1,0};
|
||||||
|
|
||||||
|
#ifdef CUSTOM_MODES
|
||||||
|
static const unsigned char toOpusTable[20] = {
|
||||||
|
0xE0, 0xE8, 0xF0, 0xF8,
|
||||||
|
0xC0, 0xC8, 0xD0, 0xD8,
|
||||||
|
0xA0, 0xA8, 0xB0, 0xB8,
|
||||||
|
0x00, 0x00, 0x00, 0x00,
|
||||||
|
0x80, 0x88, 0x90, 0x98,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char fromOpusTable[16] = {
|
||||||
|
0x80, 0x88, 0x90, 0x98,
|
||||||
|
0x40, 0x48, 0x50, 0x58,
|
||||||
|
0x20, 0x28, 0x30, 0x38,
|
||||||
|
0x00, 0x08, 0x10, 0x18
|
||||||
|
};
|
||||||
|
|
||||||
|
static OPUS_INLINE int toOpus(unsigned char c)
|
||||||
|
{
|
||||||
|
int ret=0;
|
||||||
|
if (c<0xA0)
|
||||||
|
ret = toOpusTable[c>>3];
|
||||||
|
if (ret == 0)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return ret|(c&0x7);
|
||||||
|
}
|
||||||
|
|
||||||
|
static OPUS_INLINE int fromOpus(unsigned char c)
|
||||||
|
{
|
||||||
|
if (c<0x80)
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return fromOpusTable[(c>>3)-16] | (c&0x7);
|
||||||
|
}
|
||||||
|
#endif /* CUSTOM_MODES */
|
||||||
|
|
||||||
|
#define COMBFILTER_MAXPERIOD 1024
|
||||||
|
#define COMBFILTER_MINPERIOD 15
|
||||||
|
|
||||||
|
extern const signed char tf_select_table[4][8];
|
||||||
|
|
||||||
|
int resampling_factor(opus_int32 rate);
|
||||||
|
|
||||||
|
void celt_preemphasis(const opus_val16 * OPUS_RESTRICT pcmp, celt_sig * OPUS_RESTRICT inp,
|
||||||
|
int N, int CC, int upsample, const opus_val16 *coef, celt_sig *mem, int clip);
|
||||||
|
|
||||||
|
void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
|
||||||
|
opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,
|
||||||
|
const opus_val16 *window, int overlap);
|
||||||
|
|
||||||
|
void init_caps(const CELTMode *m,int *cap,int LM,int C);
|
||||||
|
|
||||||
|
#ifdef RESYNTH
|
||||||
|
void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, const opus_val16 *coef, celt_sig *mem, celt_sig * OPUS_RESTRICT scratch);
|
||||||
|
|
||||||
|
void compute_inv_mdcts(const CELTMode *mode, int shortBlocks, celt_sig *X,
|
||||||
|
celt_sig * OPUS_RESTRICT out_mem[], int C, int LM);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
1195
code/opus-1.1/celt/celt_decoder.c
Normal file
1195
code/opus-1.1/celt/celt_decoder.c
Normal file
File diff suppressed because it is too large
Load diff
2353
code/opus-1.1/celt/celt_encoder.c
Normal file
2353
code/opus-1.1/celt/celt_encoder.c
Normal file
File diff suppressed because it is too large
Load diff
309
code/opus-1.1/celt/celt_lpc.c
Normal file
309
code/opus-1.1/celt/celt_lpc.c
Normal file
|
@ -0,0 +1,309 @@
|
||||||
|
/* Copyright (c) 2009-2010 Xiph.Org Foundation
|
||||||
|
Written by Jean-Marc Valin */
|
||||||
|
/*
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
- Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||||
|
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "celt_lpc.h"
|
||||||
|
#include "stack_alloc.h"
|
||||||
|
#include "mathops.h"
|
||||||
|
#include "pitch.h"
|
||||||
|
|
||||||
|
void _celt_lpc(
|
||||||
|
opus_val16 *_lpc, /* out: [0...p-1] LPC coefficients */
|
||||||
|
const opus_val32 *ac, /* in: [0...p] autocorrelation values */
|
||||||
|
int p
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
opus_val32 r;
|
||||||
|
opus_val32 error = ac[0];
|
||||||
|
#ifdef FIXED_POINT
|
||||||
|
opus_val32 lpc[LPC_ORDER];
|
||||||
|
#else
|
||||||
|
float *lpc = _lpc;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (i = 0; i < p; i++)
|
||||||
|
lpc[i] = 0;
|
||||||
|
if (ac[0] != 0)
|
||||||
|
{
|
||||||
|
for (i = 0; i < p; i++) {
|
||||||
|
/* Sum up this iteration's reflection coefficient */
|
||||||
|
opus_val32 rr = 0;
|
||||||
|
for (j = 0; j < i; j++)
|
||||||
|
rr += MULT32_32_Q31(lpc[j],ac[i - j]);
|
||||||
|
rr += SHR32(ac[i + 1],3);
|
||||||
|
r = -frac_div32(SHL32(rr,3), error);
|
||||||
|
/* Update LPC coefficients and total error */
|
||||||
|
lpc[i] = SHR32(r,3);
|
||||||
|
for (j = 0; j < (i+1)>>1; j++)
|
||||||
|
{
|
||||||
|
opus_val32 tmp1, tmp2;
|
||||||
|
tmp1 = lpc[j];
|
||||||
|
tmp2 = lpc[i-1-j];
|
||||||
|
lpc[j] = tmp1 + MULT32_32_Q31(r,tmp2);
|
||||||
|
lpc[i-1-j] = tmp2 + MULT32_32_Q31(r,tmp1);
|
||||||
|
}
|
||||||
|
|
||||||
|
error = error - MULT32_32_Q31(MULT32_32_Q31(r,r),error);
|
||||||
|
/* Bail out once we get 30 dB gain */
|
||||||
|
#ifdef FIXED_POINT
|
||||||
|
if (error<SHR32(ac[0],10))
|
||||||
|
break;
|
||||||
|
#else
|
||||||
|
if (error<.001f*ac[0])
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef FIXED_POINT
|
||||||
|
for (i=0;i<p;i++)
|
||||||
|
_lpc[i] = ROUND16(lpc[i],16);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void celt_fir(const opus_val16 *_x,
|
||||||
|
const opus_val16 *num,
|
||||||
|
opus_val16 *_y,
|
||||||
|
int N,
|
||||||
|
int ord,
|
||||||
|
opus_val16 *mem)
|
||||||
|
{
|
||||||
|
int i,j;
|
||||||
|
VARDECL(opus_val16, rnum);
|
||||||
|
VARDECL(opus_val16, x);
|
||||||
|
SAVE_STACK;
|
||||||
|
|
||||||
|
ALLOC(rnum, ord, opus_val16);
|
||||||
|
ALLOC(x, N+ord, opus_val16);
|
||||||
|
for(i=0;i<ord;i++)
|
||||||
|
rnum[i] = num[ord-i-1];
|
||||||
|
for(i=0;i<ord;i++)
|
||||||
|
x[i] = mem[ord-i-1];
|
||||||
|
for (i=0;i<N;i++)
|
||||||
|
x[i+ord]=_x[i];
|
||||||
|
for(i=0;i<ord;i++)
|
||||||
|
mem[i] = _x[N-i-1];
|
||||||
|
#ifdef SMALL_FOOTPRINT
|
||||||
|
for (i=0;i<N;i++)
|
||||||
|
{
|
||||||
|
opus_val32 sum = SHL32(EXTEND32(_x[i]), SIG_SHIFT);
|
||||||
|
for (j=0;j<ord;j++)
|
||||||
|
{
|
||||||
|
sum = MAC16_16(sum,rnum[j],x[i+j]);
|
||||||
|
}
|
||||||
|
_y[i] = SATURATE16(PSHR32(sum, SIG_SHIFT));
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
for (i=0;i<N-3;i+=4)
|
||||||
|
{
|
||||||
|
opus_val32 sum[4]={0,0,0,0};
|
||||||
|
xcorr_kernel(rnum, x+i, sum, ord);
|
||||||
|
_y[i ] = SATURATE16(ADD32(EXTEND32(_x[i ]), PSHR32(sum[0], SIG_SHIFT)));
|
||||||
|
_y[i+1] = SATURATE16(ADD32(EXTEND32(_x[i+1]), PSHR32(sum[1], SIG_SHIFT)));
|
||||||
|
_y[i+2] = SATURATE16(ADD32(EXTEND32(_x[i+2]), PSHR32(sum[2], SIG_SHIFT)));
|
||||||
|
_y[i+3] = SATURATE16(ADD32(EXTEND32(_x[i+3]), PSHR32(sum[3], SIG_SHIFT)));
|
||||||
|
}
|
||||||
|
for (;i<N;i++)
|
||||||
|
{
|
||||||
|
opus_val32 sum = 0;
|
||||||
|
for (j=0;j<ord;j++)
|
||||||
|
sum = MAC16_16(sum,rnum[j],x[i+j]);
|
||||||
|
_y[i] = SATURATE16(ADD32(EXTEND32(_x[i]), PSHR32(sum, SIG_SHIFT)));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
RESTORE_STACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void celt_iir(const opus_val32 *_x,
|
||||||
|
const opus_val16 *den,
|
||||||
|
opus_val32 *_y,
|
||||||
|
int N,
|
||||||
|
int ord,
|
||||||
|
opus_val16 *mem)
|
||||||
|
{
|
||||||
|
#ifdef SMALL_FOOTPRINT
|
||||||
|
int i,j;
|
||||||
|
for (i=0;i<N;i++)
|
||||||
|
{
|
||||||
|
opus_val32 sum = _x[i];
|
||||||
|
for (j=0;j<ord;j++)
|
||||||
|
{
|
||||||
|
sum -= MULT16_16(den[j],mem[j]);
|
||||||
|
}
|
||||||
|
for (j=ord-1;j>=1;j--)
|
||||||
|
{
|
||||||
|
mem[j]=mem[j-1];
|
||||||
|
}
|
||||||
|
mem[0] = ROUND16(sum,SIG_SHIFT);
|
||||||
|
_y[i] = sum;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int i,j;
|
||||||
|
VARDECL(opus_val16, rden);
|
||||||
|
VARDECL(opus_val16, y);
|
||||||
|
SAVE_STACK;
|
||||||
|
|
||||||
|
celt_assert((ord&3)==0);
|
||||||
|
ALLOC(rden, ord, opus_val16);
|
||||||
|
ALLOC(y, N+ord, opus_val16);
|
||||||
|
for(i=0;i<ord;i++)
|
||||||
|
rden[i] = den[ord-i-1];
|
||||||
|
for(i=0;i<ord;i++)
|
||||||
|
y[i] = -mem[ord-i-1];
|
||||||
|
for(;i<N+ord;i++)
|
||||||
|
y[i]=0;
|
||||||
|
for (i=0;i<N-3;i+=4)
|
||||||
|
{
|
||||||
|
/* Unroll by 4 as if it were an FIR filter */
|
||||||
|
opus_val32 sum[4];
|
||||||
|
sum[0]=_x[i];
|
||||||
|
sum[1]=_x[i+1];
|
||||||
|
sum[2]=_x[i+2];
|
||||||
|
sum[3]=_x[i+3];
|
||||||
|
xcorr_kernel(rden, y+i, sum, ord);
|
||||||
|
|
||||||
|
/* Patch up the result to compensate for the fact that this is an IIR */
|
||||||
|
y[i+ord ] = -ROUND16(sum[0],SIG_SHIFT);
|
||||||
|
_y[i ] = sum[0];
|
||||||
|
sum[1] = MAC16_16(sum[1], y[i+ord ], den[0]);
|
||||||
|
y[i+ord+1] = -ROUND16(sum[1],SIG_SHIFT);
|
||||||
|
_y[i+1] = sum[1];
|
||||||
|
sum[2] = MAC16_16(sum[2], y[i+ord+1], den[0]);
|
||||||
|
sum[2] = MAC16_16(sum[2], y[i+ord ], den[1]);
|
||||||
|
y[i+ord+2] = -ROUND16(sum[2],SIG_SHIFT);
|
||||||
|
_y[i+2] = sum[2];
|
||||||
|
|
||||||
|
sum[3] = MAC16_16(sum[3], y[i+ord+2], den[0]);
|
||||||
|
sum[3] = MAC16_16(sum[3], y[i+ord+1], den[1]);
|
||||||
|
sum[3] = MAC16_16(sum[3], y[i+ord ], den[2]);
|
||||||
|
y[i+ord+3] = -ROUND16(sum[3],SIG_SHIFT);
|
||||||
|
_y[i+3] = sum[3];
|
||||||
|
}
|
||||||
|
for (;i<N;i++)
|
||||||
|
{
|
||||||
|
opus_val32 sum = _x[i];
|
||||||
|
for (j=0;j<ord;j++)
|
||||||
|
sum -= MULT16_16(rden[j],y[i+j]);
|
||||||
|
y[i+ord] = ROUND16(sum,SIG_SHIFT);
|
||||||
|
_y[i] = sum;
|
||||||
|
}
|
||||||
|
for(i=0;i<ord;i++)
|
||||||
|
mem[i] = _y[N-i-1];
|
||||||
|
RESTORE_STACK;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int _celt_autocorr(
|
||||||
|
const opus_val16 *x, /* in: [0...n-1] samples x */
|
||||||
|
opus_val32 *ac, /* out: [0...lag-1] ac values */
|
||||||
|
const opus_val16 *window,
|
||||||
|
int overlap,
|
||||||
|
int lag,
|
||||||
|
int n,
|
||||||
|
int arch
|
||||||
|
)
|
||||||
|
{
|
||||||
|
opus_val32 d;
|
||||||
|
int i, k;
|
||||||
|
int fastN=n-lag;
|
||||||
|
int shift;
|
||||||
|
const opus_val16 *xptr;
|
||||||
|
VARDECL(opus_val16, xx);
|
||||||
|
SAVE_STACK;
|
||||||
|
ALLOC(xx, n, opus_val16);
|
||||||
|
celt_assert(n>0);
|
||||||
|
celt_assert(overlap>=0);
|
||||||
|
if (overlap == 0)
|
||||||
|
{
|
||||||
|
xptr = x;
|
||||||
|
} else {
|
||||||
|
for (i=0;i<n;i++)
|
||||||
|
xx[i] = x[i];
|
||||||
|
for (i=0;i<overlap;i++)
|
||||||
|
{
|
||||||
|
xx[i] = MULT16_16_Q15(x[i],window[i]);
|
||||||
|
xx[n-i-1] = MULT16_16_Q15(x[n-i-1],window[i]);
|
||||||
|
}
|
||||||
|
xptr = xx;
|
||||||
|
}
|
||||||
|
shift=0;
|
||||||
|
#ifdef FIXED_POINT
|
||||||
|
{
|
||||||
|
opus_val32 ac0;
|
||||||
|
ac0 = 1+(n<<7);
|
||||||
|
if (n&1) ac0 += SHR32(MULT16_16(xptr[0],xptr[0]),9);
|
||||||
|
for(i=(n&1);i<n;i+=2)
|
||||||
|
{
|
||||||
|
ac0 += SHR32(MULT16_16(xptr[i],xptr[i]),9);
|
||||||
|
ac0 += SHR32(MULT16_16(xptr[i+1],xptr[i+1]),9);
|
||||||
|
}
|
||||||
|
|
||||||
|
shift = celt_ilog2(ac0)-30+10;
|
||||||
|
shift = (shift)/2;
|
||||||
|
if (shift>0)
|
||||||
|
{
|
||||||
|
for(i=0;i<n;i++)
|
||||||
|
xx[i] = PSHR32(xptr[i], shift);
|
||||||
|
xptr = xx;
|
||||||
|
} else
|
||||||
|
shift = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
celt_pitch_xcorr(xptr, xptr, ac, fastN, lag+1, arch);
|
||||||
|
for (k=0;k<=lag;k++)
|
||||||
|
{
|
||||||
|
for (i = k+fastN, d = 0; i < n; i++)
|
||||||
|
d = MAC16_16(d, xptr[i], xptr[i-k]);
|
||||||
|
ac[k] += d;
|
||||||
|
}
|
||||||
|
#ifdef FIXED_POINT
|
||||||
|
shift = 2*shift;
|
||||||
|
if (shift<=0)
|
||||||
|
ac[0] += SHL32((opus_int32)1, -shift);
|
||||||
|
if (ac[0] < 268435456)
|
||||||
|
{
|
||||||
|
int shift2 = 29 - EC_ILOG(ac[0]);
|
||||||
|
for (i=0;i<=lag;i++)
|
||||||
|
ac[i] = SHL32(ac[i], shift2);
|
||||||
|
shift -= shift2;
|
||||||
|
} else if (ac[0] >= 536870912)
|
||||||
|
{
|
||||||
|
int shift2=1;
|
||||||
|
if (ac[0] >= 1073741824)
|
||||||
|
shift2++;
|
||||||
|
for (i=0;i<=lag;i++)
|
||||||
|
ac[i] = SHR32(ac[i], shift2);
|
||||||
|
shift += shift2;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RESTORE_STACK;
|
||||||
|
return shift;
|
||||||
|
}
|
|
@ -48,6 +48,7 @@ void celt_iir(const opus_val32 *x,
|
||||||
int ord,
|
int ord,
|
||||||
opus_val16 *mem);
|
opus_val16 *mem);
|
||||||
|
|
||||||
void _celt_autocorr(const opus_val16 *x, opus_val32 *ac, const opus_val16 *window, int overlap, int lag, int n);
|
int _celt_autocorr(const opus_val16 *x, opus_val32 *ac,
|
||||||
|
const opus_val16 *window, int overlap, int lag, int n, int arch);
|
||||||
|
|
||||||
#endif /* PLC_H */
|
#endif /* PLC_H */
|
|
@ -1,11 +1,5 @@
|
||||||
/* Copyright (c) 2007-2008 CSIRO
|
/* Copyright (c) 2010 Xiph.Org Foundation
|
||||||
Copyright (c) 2007-2009 Xiph.Org Foundation
|
* Copyright (c) 2013 Parrot */
|
||||||
Written by Jean-Marc Valin */
|
|
||||||
/**
|
|
||||||
@file pitch.h
|
|
||||||
@brief Pitch analysis
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions
|
modification, are permitted provided that the following conditions
|
||||||
|
@ -31,18 +25,30 @@
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef PITCH_H
|
#ifndef CPU_SUPPORT_H
|
||||||
#define PITCH_H
|
#define CPU_SUPPORT_H
|
||||||
|
|
||||||
#include "modes.h"
|
#include "opus_types.h"
|
||||||
|
#include "opus_defines.h"
|
||||||
|
|
||||||
void pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x_lp,
|
#if defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_ASM)
|
||||||
int len, int C);
|
#include "arm/armcpu.h"
|
||||||
|
|
||||||
void pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTRICT y,
|
/* We currently support 4 ARM variants:
|
||||||
int len, int max_pitch, int *pitch);
|
* arch[0] -> ARMv4
|
||||||
|
* arch[1] -> ARMv5E
|
||||||
|
* arch[2] -> ARMv6
|
||||||
|
* arch[3] -> NEON
|
||||||
|
*/
|
||||||
|
#define OPUS_ARCHMASK 3
|
||||||
|
|
||||||
opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
|
#else
|
||||||
int N, int *T0, int prev_period, opus_val16 prev_gain);
|
#define OPUS_ARCHMASK 0
|
||||||
|
|
||||||
|
static OPUS_INLINE int opus_select_arch(void)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
697
code/opus-1.1/celt/cwrs.c
Normal file
697
code/opus-1.1/celt/cwrs.c
Normal file
|
@ -0,0 +1,697 @@
|
||||||
|
/* Copyright (c) 2007-2008 CSIRO
|
||||||
|
Copyright (c) 2007-2009 Xiph.Org Foundation
|
||||||
|
Copyright (c) 2007-2009 Timothy B. Terriberry
|
||||||
|
Written by Timothy B. Terriberry and Jean-Marc Valin */
|
||||||
|
/*
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
- Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||||
|
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "os_support.h"
|
||||||
|
#include "cwrs.h"
|
||||||
|
#include "mathops.h"
|
||||||
|
#include "arch.h"
|
||||||
|
|
||||||
|
#ifdef CUSTOM_MODES
|
||||||
|
|
||||||
|
/*Guaranteed to return a conservatively large estimate of the binary logarithm
|
||||||
|
with frac bits of fractional precision.
|
||||||
|
Tested for all possible 32-bit inputs with frac=4, where the maximum
|
||||||
|
overestimation is 0.06254243 bits.*/
|
||||||
|
int log2_frac(opus_uint32 val, int frac)
|
||||||
|
{
|
||||||
|
int l;
|
||||||
|
l=EC_ILOG(val);
|
||||||
|
if(val&(val-1)){
|
||||||
|
/*This is (val>>l-16), but guaranteed to round up, even if adding a bias
|
||||||
|
before the shift would cause overflow (e.g., for 0xFFFFxxxx).
|
||||||
|
Doesn't work for val=0, but that case fails the test above.*/
|
||||||
|
if(l>16)val=((val-1)>>(l-16))+1;
|
||||||
|
else val<<=16-l;
|
||||||
|
l=(l-1)<<frac;
|
||||||
|
/*Note that we always need one iteration, since the rounding up above means
|
||||||
|
that we might need to adjust the integer part of the logarithm.*/
|
||||||
|
do{
|
||||||
|
int b;
|
||||||
|
b=(int)(val>>16);
|
||||||
|
l+=b<<frac;
|
||||||
|
val=(val+b)>>b;
|
||||||
|
val=(val*val+0x7FFF)>>15;
|
||||||
|
}
|
||||||
|
while(frac-->0);
|
||||||
|
/*If val is not exactly 0x8000, then we have to round up the remainder.*/
|
||||||
|
return l+(val>0x8000);
|
||||||
|
}
|
||||||
|
/*Exact powers of two require no rounding.*/
|
||||||
|
else return (l-1)<<frac;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*Although derived separately, the pulse vector coding scheme is equivalent to
|
||||||
|
a Pyramid Vector Quantizer \cite{Fis86}.
|
||||||
|
Some additional notes about an early version appear at
|
||||||
|
http://people.xiph.org/~tterribe/notes/cwrs.html, but the codebook ordering
|
||||||
|
and the definitions of some terms have evolved since that was written.
|
||||||
|
|
||||||
|
The conversion from a pulse vector to an integer index (encoding) and back
|
||||||
|
(decoding) is governed by two related functions, V(N,K) and U(N,K).
|
||||||
|
|
||||||
|
V(N,K) = the number of combinations, with replacement, of N items, taken K
|
||||||
|
at a time, when a sign bit is added to each item taken at least once (i.e.,
|
||||||
|
the number of N-dimensional unit pulse vectors with K pulses).
|
||||||
|
One way to compute this is via
|
||||||
|
V(N,K) = K>0 ? sum(k=1...K,2**k*choose(N,k)*choose(K-1,k-1)) : 1,
|
||||||
|
where choose() is the binomial function.
|
||||||
|
A table of values for N<10 and K<10 looks like:
|
||||||
|
V[10][10] = {
|
||||||
|
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
{1, 2, 2, 2, 2, 2, 2, 2, 2, 2},
|
||||||
|
{1, 4, 8, 12, 16, 20, 24, 28, 32, 36},
|
||||||
|
{1, 6, 18, 38, 66, 102, 146, 198, 258, 326},
|
||||||
|
{1, 8, 32, 88, 192, 360, 608, 952, 1408, 1992},
|
||||||
|
{1, 10, 50, 170, 450, 1002, 1970, 3530, 5890, 9290},
|
||||||
|
{1, 12, 72, 292, 912, 2364, 5336, 10836, 20256, 35436},
|
||||||
|
{1, 14, 98, 462, 1666, 4942, 12642, 28814, 59906, 115598},
|
||||||
|
{1, 16, 128, 688, 2816, 9424, 27008, 68464, 157184, 332688},
|
||||||
|
{1, 18, 162, 978, 4482, 16722, 53154, 148626, 374274, 864146}
|
||||||
|
};
|
||||||
|
|
||||||
|
U(N,K) = the number of such combinations wherein N-1 objects are taken at
|
||||||
|
most K-1 at a time.
|
||||||
|
This is given by
|
||||||
|
U(N,K) = sum(k=0...K-1,V(N-1,k))
|
||||||
|
= K>0 ? (V(N-1,K-1) + V(N,K-1))/2 : 0.
|
||||||
|
The latter expression also makes clear that U(N,K) is half the number of such
|
||||||
|
combinations wherein the first object is taken at least once.
|
||||||
|
Although it may not be clear from either of these definitions, U(N,K) is the
|
||||||
|
natural function to work with when enumerating the pulse vector codebooks,
|
||||||
|
not V(N,K).
|
||||||
|
U(N,K) is not well-defined for N=0, but with the extension
|
||||||
|
U(0,K) = K>0 ? 0 : 1,
|
||||||
|
the function becomes symmetric: U(N,K) = U(K,N), with a similar table:
|
||||||
|
U[10][10] = {
|
||||||
|
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||||
|
{0, 1, 1, 1, 1, 1, 1, 1, 1, 1},
|
||||||
|
{0, 1, 3, 5, 7, 9, 11, 13, 15, 17},
|
||||||
|
{0, 1, 5, 13, 25, 41, 61, 85, 113, 145},
|
||||||
|
{0, 1, 7, 25, 63, 129, 231, 377, 575, 833},
|
||||||
|
{0, 1, 9, 41, 129, 321, 681, 1289, 2241, 3649},
|
||||||
|
{0, 1, 11, 61, 231, 681, 1683, 3653, 7183, 13073},
|
||||||
|
{0, 1, 13, 85, 377, 1289, 3653, 8989, 19825, 40081},
|
||||||
|
{0, 1, 15, 113, 575, 2241, 7183, 19825, 48639, 108545},
|
||||||
|
{0, 1, 17, 145, 833, 3649, 13073, 40081, 108545, 265729}
|
||||||
|
};
|
||||||
|
|
||||||
|
With this extension, V(N,K) may be written in terms of U(N,K):
|
||||||
|
V(N,K) = U(N,K) + U(N,K+1)
|
||||||
|
for all N>=0, K>=0.
|
||||||
|
Thus U(N,K+1) represents the number of combinations where the first element
|
||||||
|
is positive or zero, and U(N,K) represents the number of combinations where
|
||||||
|
it is negative.
|
||||||
|
With a large enough table of U(N,K) values, we could write O(N) encoding
|
||||||
|
and O(min(N*log(K),N+K)) decoding routines, but such a table would be
|
||||||
|
prohibitively large for small embedded devices (K may be as large as 32767
|
||||||
|
for small N, and N may be as large as 200).
|
||||||
|
|
||||||
|
Both functions obey the same recurrence relation:
|
||||||
|
V(N,K) = V(N-1,K) + V(N,K-1) + V(N-1,K-1),
|
||||||
|
U(N,K) = U(N-1,K) + U(N,K-1) + U(N-1,K-1),
|
||||||
|
for all N>0, K>0, with different initial conditions at N=0 or K=0.
|
||||||
|
This allows us to construct a row of one of the tables above given the
|
||||||
|
previous row or the next row.
|
||||||
|
Thus we can derive O(NK) encoding and decoding routines with O(K) memory
|
||||||
|
using only addition and subtraction.
|
||||||
|
|
||||||
|
When encoding, we build up from the U(2,K) row and work our way forwards.
|
||||||
|
When decoding, we need to start at the U(N,K) row and work our way backwards,
|
||||||
|
which requires a means of computing U(N,K).
|
||||||
|
U(N,K) may be computed from two previous values with the same N:
|
||||||
|
U(N,K) = ((2*N-1)*U(N,K-1) - U(N,K-2))/(K-1) + U(N,K-2)
|
||||||
|
for all N>1, and since U(N,K) is symmetric, a similar relation holds for two
|
||||||
|
previous values with the same K:
|
||||||
|
U(N,K>1) = ((2*K-1)*U(N-1,K) - U(N-2,K))/(N-1) + U(N-2,K)
|
||||||
|
for all K>1.
|
||||||
|
This allows us to construct an arbitrary row of the U(N,K) table by starting
|
||||||
|
with the first two values, which are constants.
|
||||||
|
This saves roughly 2/3 the work in our O(NK) decoding routine, but costs O(K)
|
||||||
|
multiplications.
|
||||||
|
Similar relations can be derived for V(N,K), but are not used here.
|
||||||
|
|
||||||
|
For N>0 and K>0, U(N,K) and V(N,K) take on the form of an (N-1)-degree
|
||||||
|
polynomial for fixed N.
|
||||||
|
The first few are
|
||||||
|
U(1,K) = 1,
|
||||||
|
U(2,K) = 2*K-1,
|
||||||
|
U(3,K) = (2*K-2)*K+1,
|
||||||
|
U(4,K) = (((4*K-6)*K+8)*K-3)/3,
|
||||||
|
U(5,K) = ((((2*K-4)*K+10)*K-8)*K+3)/3,
|
||||||
|
and
|
||||||
|
V(1,K) = 2,
|
||||||
|
V(2,K) = 4*K,
|
||||||
|
V(3,K) = 4*K*K+2,
|
||||||
|
V(4,K) = 8*(K*K+2)*K/3,
|
||||||
|
V(5,K) = ((4*K*K+20)*K*K+6)/3,
|
||||||
|
for all K>0.
|
||||||
|
This allows us to derive O(N) encoding and O(N*log(K)) decoding routines for
|
||||||
|
small N (and indeed decoding is also O(N) for N<3).
|
||||||
|
|
||||||
|
@ARTICLE{Fis86,
|
||||||
|
author="Thomas R. Fischer",
|
||||||
|
title="A Pyramid Vector Quantizer",
|
||||||
|
journal="IEEE Transactions on Information Theory",
|
||||||
|
volume="IT-32",
|
||||||
|
number=4,
|
||||||
|
pages="568--583",
|
||||||
|
month=Jul,
|
||||||
|
year=1986
|
||||||
|
}*/
|
||||||
|
|
||||||
|
#if !defined(SMALL_FOOTPRINT)
|
||||||
|
|
||||||
|
/*U(N,K) = U(K,N) := N>0?K>0?U(N-1,K)+U(N,K-1)+U(N-1,K-1):0:K>0?1:0*/
|
||||||
|
# define CELT_PVQ_U(_n,_k) (CELT_PVQ_U_ROW[IMIN(_n,_k)][IMAX(_n,_k)])
|
||||||
|
/*V(N,K) := U(N,K)+U(N,K+1) = the number of PVQ codewords for a band of size N
|
||||||
|
with K pulses allocated to it.*/
|
||||||
|
# define CELT_PVQ_V(_n,_k) (CELT_PVQ_U(_n,_k)+CELT_PVQ_U(_n,(_k)+1))
|
||||||
|
|
||||||
|
/*For each V(N,K) supported, we will access element U(min(N,K+1),max(N,K+1)).
|
||||||
|
Thus, the number of entries in row I is the larger of the maximum number of
|
||||||
|
pulses we will ever allocate for a given N=I (K=128, or however many fit in
|
||||||
|
32 bits, whichever is smaller), plus one, and the maximum N for which
|
||||||
|
K=I-1 pulses fit in 32 bits.
|
||||||
|
The largest band size in an Opus Custom mode is 208.
|
||||||
|
Otherwise, we can limit things to the set of N which can be achieved by
|
||||||
|
splitting a band from a standard Opus mode: 176, 144, 96, 88, 72, 64, 48,
|
||||||
|
44, 36, 32, 24, 22, 18, 16, 8, 4, 2).*/
|
||||||
|
#if defined(CUSTOM_MODES)
|
||||||
|
static const opus_uint32 CELT_PVQ_U_DATA[1488]={
|
||||||
|
#else
|
||||||
|
static const opus_uint32 CELT_PVQ_U_DATA[1272]={
|
||||||
|
#endif
|
||||||
|
/*N=0, K=0...176:*/
|
||||||
|
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
#if defined(CUSTOM_MODES)
|
||||||
|
/*...208:*/
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0,
|
||||||
|
#endif
|
||||||
|
/*N=1, K=1...176:*/
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
#if defined(CUSTOM_MODES)
|
||||||
|
/*...208:*/
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1,
|
||||||
|
#endif
|
||||||
|
/*N=2, K=2...176:*/
|
||||||
|
3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41,
|
||||||
|
43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79,
|
||||||
|
81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103, 105, 107, 109, 111, 113,
|
||||||
|
115, 117, 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, 139, 141, 143,
|
||||||
|
145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173,
|
||||||
|
175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203,
|
||||||
|
205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233,
|
||||||
|
235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255, 257, 259, 261, 263,
|
||||||
|
265, 267, 269, 271, 273, 275, 277, 279, 281, 283, 285, 287, 289, 291, 293,
|
||||||
|
295, 297, 299, 301, 303, 305, 307, 309, 311, 313, 315, 317, 319, 321, 323,
|
||||||
|
325, 327, 329, 331, 333, 335, 337, 339, 341, 343, 345, 347, 349, 351,
|
||||||
|
#if defined(CUSTOM_MODES)
|
||||||
|
/*...208:*/
|
||||||
|
353, 355, 357, 359, 361, 363, 365, 367, 369, 371, 373, 375, 377, 379, 381,
|
||||||
|
383, 385, 387, 389, 391, 393, 395, 397, 399, 401, 403, 405, 407, 409, 411,
|
||||||
|
413, 415,
|
||||||
|
#endif
|
||||||
|
/*N=3, K=3...176:*/
|
||||||
|
13, 25, 41, 61, 85, 113, 145, 181, 221, 265, 313, 365, 421, 481, 545, 613,
|
||||||
|
685, 761, 841, 925, 1013, 1105, 1201, 1301, 1405, 1513, 1625, 1741, 1861,
|
||||||
|
1985, 2113, 2245, 2381, 2521, 2665, 2813, 2965, 3121, 3281, 3445, 3613, 3785,
|
||||||
|
3961, 4141, 4325, 4513, 4705, 4901, 5101, 5305, 5513, 5725, 5941, 6161, 6385,
|
||||||
|
6613, 6845, 7081, 7321, 7565, 7813, 8065, 8321, 8581, 8845, 9113, 9385, 9661,
|
||||||
|
9941, 10225, 10513, 10805, 11101, 11401, 11705, 12013, 12325, 12641, 12961,
|
||||||
|
13285, 13613, 13945, 14281, 14621, 14965, 15313, 15665, 16021, 16381, 16745,
|
||||||
|
17113, 17485, 17861, 18241, 18625, 19013, 19405, 19801, 20201, 20605, 21013,
|
||||||
|
21425, 21841, 22261, 22685, 23113, 23545, 23981, 24421, 24865, 25313, 25765,
|
||||||
|
26221, 26681, 27145, 27613, 28085, 28561, 29041, 29525, 30013, 30505, 31001,
|
||||||
|
31501, 32005, 32513, 33025, 33541, 34061, 34585, 35113, 35645, 36181, 36721,
|
||||||
|
37265, 37813, 38365, 38921, 39481, 40045, 40613, 41185, 41761, 42341, 42925,
|
||||||
|
43513, 44105, 44701, 45301, 45905, 46513, 47125, 47741, 48361, 48985, 49613,
|
||||||
|
50245, 50881, 51521, 52165, 52813, 53465, 54121, 54781, 55445, 56113, 56785,
|
||||||
|
57461, 58141, 58825, 59513, 60205, 60901, 61601,
|
||||||
|
#if defined(CUSTOM_MODES)
|
||||||
|
/*...208:*/
|
||||||
|
62305, 63013, 63725, 64441, 65161, 65885, 66613, 67345, 68081, 68821, 69565,
|
||||||
|
70313, 71065, 71821, 72581, 73345, 74113, 74885, 75661, 76441, 77225, 78013,
|
||||||
|
78805, 79601, 80401, 81205, 82013, 82825, 83641, 84461, 85285, 86113,
|
||||||
|
#endif
|
||||||
|
/*N=4, K=4...176:*/
|
||||||
|
63, 129, 231, 377, 575, 833, 1159, 1561, 2047, 2625, 3303, 4089, 4991, 6017,
|
||||||
|
7175, 8473, 9919, 11521, 13287, 15225, 17343, 19649, 22151, 24857, 27775,
|
||||||
|
30913, 34279, 37881, 41727, 45825, 50183, 54809, 59711, 64897, 70375, 76153,
|
||||||
|
82239, 88641, 95367, 102425, 109823, 117569, 125671, 134137, 142975, 152193,
|
||||||
|
161799, 171801, 182207, 193025, 204263, 215929, 228031, 240577, 253575,
|
||||||
|
267033, 280959, 295361, 310247, 325625, 341503, 357889, 374791, 392217,
|
||||||
|
410175, 428673, 447719, 467321, 487487, 508225, 529543, 551449, 573951,
|
||||||
|
597057, 620775, 645113, 670079, 695681, 721927, 748825, 776383, 804609,
|
||||||
|
833511, 863097, 893375, 924353, 956039, 988441, 1021567, 1055425, 1090023,
|
||||||
|
1125369, 1161471, 1198337, 1235975, 1274393, 1313599, 1353601, 1394407,
|
||||||
|
1436025, 1478463, 1521729, 1565831, 1610777, 1656575, 1703233, 1750759,
|
||||||
|
1799161, 1848447, 1898625, 1949703, 2001689, 2054591, 2108417, 2163175,
|
||||||
|
2218873, 2275519, 2333121, 2391687, 2451225, 2511743, 2573249, 2635751,
|
||||||
|
2699257, 2763775, 2829313, 2895879, 2963481, 3032127, 3101825, 3172583,
|
||||||
|
3244409, 3317311, 3391297, 3466375, 3542553, 3619839, 3698241, 3777767,
|
||||||
|
3858425, 3940223, 4023169, 4107271, 4192537, 4278975, 4366593, 4455399,
|
||||||
|
4545401, 4636607, 4729025, 4822663, 4917529, 5013631, 5110977, 5209575,
|
||||||
|
5309433, 5410559, 5512961, 5616647, 5721625, 5827903, 5935489, 6044391,
|
||||||
|
6154617, 6266175, 6379073, 6493319, 6608921, 6725887, 6844225, 6963943,
|
||||||
|
7085049, 7207551,
|
||||||
|
#if defined(CUSTOM_MODES)
|
||||||
|
/*...208:*/
|
||||||
|
7331457, 7456775, 7583513, 7711679, 7841281, 7972327, 8104825, 8238783,
|
||||||
|
8374209, 8511111, 8649497, 8789375, 8930753, 9073639, 9218041, 9363967,
|
||||||
|
9511425, 9660423, 9810969, 9963071, 10116737, 10271975, 10428793, 10587199,
|
||||||
|
10747201, 10908807, 11072025, 11236863, 11403329, 11571431, 11741177,
|
||||||
|
11912575,
|
||||||
|
#endif
|
||||||
|
/*N=5, K=5...176:*/
|
||||||
|
321, 681, 1289, 2241, 3649, 5641, 8361, 11969, 16641, 22569, 29961, 39041,
|
||||||
|
50049, 63241, 78889, 97281, 118721, 143529, 172041, 204609, 241601, 283401,
|
||||||
|
330409, 383041, 441729, 506921, 579081, 658689, 746241, 842249, 947241,
|
||||||
|
1061761, 1186369, 1321641, 1468169, 1626561, 1797441, 1981449, 2179241,
|
||||||
|
2391489, 2618881, 2862121, 3121929, 3399041, 3694209, 4008201, 4341801,
|
||||||
|
4695809, 5071041, 5468329, 5888521, 6332481, 6801089, 7295241, 7815849,
|
||||||
|
8363841, 8940161, 9545769, 10181641, 10848769, 11548161, 12280841, 13047849,
|
||||||
|
13850241, 14689089, 15565481, 16480521, 17435329, 18431041, 19468809,
|
||||||
|
20549801, 21675201, 22846209, 24064041, 25329929, 26645121, 28010881,
|
||||||
|
29428489, 30899241, 32424449, 34005441, 35643561, 37340169, 39096641,
|
||||||
|
40914369, 42794761, 44739241, 46749249, 48826241, 50971689, 53187081,
|
||||||
|
55473921, 57833729, 60268041, 62778409, 65366401, 68033601, 70781609,
|
||||||
|
73612041, 76526529, 79526721, 82614281, 85790889, 89058241, 92418049,
|
||||||
|
95872041, 99421961, 103069569, 106816641, 110664969, 114616361, 118672641,
|
||||||
|
122835649, 127107241, 131489289, 135983681, 140592321, 145317129, 150160041,
|
||||||
|
155123009, 160208001, 165417001, 170752009, 176215041, 181808129, 187533321,
|
||||||
|
193392681, 199388289, 205522241, 211796649, 218213641, 224775361, 231483969,
|
||||||
|
238341641, 245350569, 252512961, 259831041, 267307049, 274943241, 282741889,
|
||||||
|
290705281, 298835721, 307135529, 315607041, 324252609, 333074601, 342075401,
|
||||||
|
351257409, 360623041, 370174729, 379914921, 389846081, 399970689, 410291241,
|
||||||
|
420810249, 431530241, 442453761, 453583369, 464921641, 476471169, 488234561,
|
||||||
|
500214441, 512413449, 524834241, 537479489, 550351881, 563454121, 576788929,
|
||||||
|
590359041, 604167209, 618216201, 632508801,
|
||||||
|
#if defined(CUSTOM_MODES)
|
||||||
|
/*...208:*/
|
||||||
|
647047809, 661836041, 676876329, 692171521, 707724481, 723538089, 739615241,
|
||||||
|
755958849, 772571841, 789457161, 806617769, 824056641, 841776769, 859781161,
|
||||||
|
878072841, 896654849, 915530241, 934702089, 954173481, 973947521, 994027329,
|
||||||
|
1014416041, 1035116809, 1056132801, 1077467201, 1099123209, 1121104041,
|
||||||
|
1143412929, 1166053121, 1189027881, 1212340489, 1235994241,
|
||||||
|
#endif
|
||||||
|
/*N=6, K=6...96:*/
|
||||||
|
1683, 3653, 7183, 13073, 22363, 36365, 56695, 85305, 124515, 177045, 246047,
|
||||||
|
335137, 448427, 590557, 766727, 982729, 1244979, 1560549, 1937199, 2383409,
|
||||||
|
2908411, 3522221, 4235671, 5060441, 6009091, 7095093, 8332863, 9737793,
|
||||||
|
11326283, 13115773, 15124775, 17372905, 19880915, 22670725, 25765455,
|
||||||
|
29189457, 32968347, 37129037, 41699767, 46710137, 52191139, 58175189,
|
||||||
|
64696159, 71789409, 79491819, 87841821, 96879431, 106646281, 117185651,
|
||||||
|
128542501, 140763503, 153897073, 167993403, 183104493, 199284183, 216588185,
|
||||||
|
235074115, 254801525, 275831935, 298228865, 322057867, 347386557, 374284647,
|
||||||
|
402823977, 433078547, 465124549, 499040399, 534906769, 572806619, 612825229,
|
||||||
|
655050231, 699571641, 746481891, 795875861, 847850911, 902506913, 959946283,
|
||||||
|
1020274013, 1083597703, 1150027593, 1219676595, 1292660325, 1369097135,
|
||||||
|
1449108145, 1532817275, 1620351277, 1711839767, 1807415257, 1907213187,
|
||||||
|
2011371957, 2120032959,
|
||||||
|
#if defined(CUSTOM_MODES)
|
||||||
|
/*...109:*/
|
||||||
|
2233340609U, 2351442379U, 2474488829U, 2602633639U, 2736033641U, 2874848851U,
|
||||||
|
3019242501U, 3169381071U, 3325434321U, 3487575323U, 3655980493U, 3830829623U,
|
||||||
|
4012305913U,
|
||||||
|
#endif
|
||||||
|
/*N=7, K=7...54*/
|
||||||
|
8989, 19825, 40081, 75517, 134245, 227305, 369305, 579125, 880685, 1303777,
|
||||||
|
1884961, 2668525, 3707509, 5064793, 6814249, 9041957, 11847485, 15345233,
|
||||||
|
19665841, 24957661, 31388293, 39146185, 48442297, 59511829, 72616013,
|
||||||
|
88043969, 106114625, 127178701, 151620757, 179861305, 212358985, 249612805,
|
||||||
|
292164445, 340600625, 395555537, 457713341, 527810725, 606639529, 695049433,
|
||||||
|
793950709, 904317037, 1027188385, 1163673953, 1314955181, 1482288821,
|
||||||
|
1667010073, 1870535785, 2094367717,
|
||||||
|
#if defined(CUSTOM_MODES)
|
||||||
|
/*...60:*/
|
||||||
|
2340095869U, 2609401873U, 2904062449U, 3225952925U, 3577050821U, 3959439497U,
|
||||||
|
#endif
|
||||||
|
/*N=8, K=8...37*/
|
||||||
|
48639, 108545, 224143, 433905, 795455, 1392065, 2340495, 3800305, 5984767,
|
||||||
|
9173505, 13726991, 20103025, 28875327, 40754369, 56610575, 77500017,
|
||||||
|
104692735, 139703809, 184327311, 240673265, 311207743, 398796225, 506750351,
|
||||||
|
638878193, 799538175, 993696769, 1226990095, 1505789553, 1837271615,
|
||||||
|
2229491905U,
|
||||||
|
#if defined(CUSTOM_MODES)
|
||||||
|
/*...40:*/
|
||||||
|
2691463695U, 3233240945U, 3866006015U,
|
||||||
|
#endif
|
||||||
|
/*N=9, K=9...28:*/
|
||||||
|
265729, 598417, 1256465, 2485825, 4673345, 8405905, 14546705, 24331777,
|
||||||
|
39490049, 62390545, 96220561, 145198913, 214828609, 312193553, 446304145,
|
||||||
|
628496897, 872893441, 1196924561, 1621925137, 2173806145U,
|
||||||
|
#if defined(CUSTOM_MODES)
|
||||||
|
/*...29:*/
|
||||||
|
2883810113U,
|
||||||
|
#endif
|
||||||
|
/*N=10, K=10...24:*/
|
||||||
|
1462563, 3317445, 7059735, 14218905, 27298155, 50250765, 89129247, 152951073,
|
||||||
|
254831667, 413442773, 654862247, 1014889769, 1541911931, 2300409629U,
|
||||||
|
3375210671U,
|
||||||
|
/*N=11, K=11...19:*/
|
||||||
|
8097453, 18474633, 39753273, 81270333, 158819253, 298199265, 540279585,
|
||||||
|
948062325, 1616336765,
|
||||||
|
#if defined(CUSTOM_MODES)
|
||||||
|
/*...20:*/
|
||||||
|
2684641785U,
|
||||||
|
#endif
|
||||||
|
/*N=12, K=12...18:*/
|
||||||
|
45046719, 103274625, 224298231, 464387817, 921406335, 1759885185,
|
||||||
|
3248227095U,
|
||||||
|
/*N=13, K=13...16:*/
|
||||||
|
251595969, 579168825, 1267854873, 2653649025U,
|
||||||
|
/*N=14, K=14:*/
|
||||||
|
1409933619
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(CUSTOM_MODES)
|
||||||
|
static const opus_uint32 *const CELT_PVQ_U_ROW[15]={
|
||||||
|
CELT_PVQ_U_DATA+ 0,CELT_PVQ_U_DATA+ 208,CELT_PVQ_U_DATA+ 415,
|
||||||
|
CELT_PVQ_U_DATA+ 621,CELT_PVQ_U_DATA+ 826,CELT_PVQ_U_DATA+1030,
|
||||||
|
CELT_PVQ_U_DATA+1233,CELT_PVQ_U_DATA+1336,CELT_PVQ_U_DATA+1389,
|
||||||
|
CELT_PVQ_U_DATA+1421,CELT_PVQ_U_DATA+1441,CELT_PVQ_U_DATA+1455,
|
||||||
|
CELT_PVQ_U_DATA+1464,CELT_PVQ_U_DATA+1470,CELT_PVQ_U_DATA+1473
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
static const opus_uint32 *const CELT_PVQ_U_ROW[15]={
|
||||||
|
CELT_PVQ_U_DATA+ 0,CELT_PVQ_U_DATA+ 176,CELT_PVQ_U_DATA+ 351,
|
||||||
|
CELT_PVQ_U_DATA+ 525,CELT_PVQ_U_DATA+ 698,CELT_PVQ_U_DATA+ 870,
|
||||||
|
CELT_PVQ_U_DATA+1041,CELT_PVQ_U_DATA+1131,CELT_PVQ_U_DATA+1178,
|
||||||
|
CELT_PVQ_U_DATA+1207,CELT_PVQ_U_DATA+1226,CELT_PVQ_U_DATA+1240,
|
||||||
|
CELT_PVQ_U_DATA+1248,CELT_PVQ_U_DATA+1254,CELT_PVQ_U_DATA+1257
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CUSTOM_MODES)
|
||||||
|
void get_required_bits(opus_int16 *_bits,int _n,int _maxk,int _frac){
|
||||||
|
int k;
|
||||||
|
/*_maxk==0 => there's nothing to do.*/
|
||||||
|
celt_assert(_maxk>0);
|
||||||
|
_bits[0]=0;
|
||||||
|
for(k=1;k<=_maxk;k++)_bits[k]=log2_frac(CELT_PVQ_V(_n,k),_frac);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static opus_uint32 icwrs(int _n,const int *_y){
|
||||||
|
opus_uint32 i;
|
||||||
|
int j;
|
||||||
|
int k;
|
||||||
|
celt_assert(_n>=2);
|
||||||
|
j=_n-1;
|
||||||
|
i=_y[j]<0;
|
||||||
|
k=abs(_y[j]);
|
||||||
|
do{
|
||||||
|
j--;
|
||||||
|
i+=CELT_PVQ_U(_n-j,k);
|
||||||
|
k+=abs(_y[j]);
|
||||||
|
if(_y[j]<0)i+=CELT_PVQ_U(_n-j,k+1);
|
||||||
|
}
|
||||||
|
while(j>0);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void encode_pulses(const int *_y,int _n,int _k,ec_enc *_enc){
|
||||||
|
celt_assert(_k>0);
|
||||||
|
ec_enc_uint(_enc,icwrs(_n,_y),CELT_PVQ_V(_n,_k));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cwrsi(int _n,int _k,opus_uint32 _i,int *_y){
|
||||||
|
opus_uint32 p;
|
||||||
|
int s;
|
||||||
|
int k0;
|
||||||
|
celt_assert(_k>0);
|
||||||
|
celt_assert(_n>1);
|
||||||
|
while(_n>2){
|
||||||
|
opus_uint32 q;
|
||||||
|
/*Lots of pulses case:*/
|
||||||
|
if(_k>=_n){
|
||||||
|
const opus_uint32 *row;
|
||||||
|
row=CELT_PVQ_U_ROW[_n];
|
||||||
|
/*Are the pulses in this dimension negative?*/
|
||||||
|
p=row[_k+1];
|
||||||
|
s=-(_i>=p);
|
||||||
|
_i-=p&s;
|
||||||
|
/*Count how many pulses were placed in this dimension.*/
|
||||||
|
k0=_k;
|
||||||
|
q=row[_n];
|
||||||
|
if(q>_i){
|
||||||
|
celt_assert(p>q);
|
||||||
|
_k=_n;
|
||||||
|
do p=CELT_PVQ_U_ROW[--_k][_n];
|
||||||
|
while(p>_i);
|
||||||
|
}
|
||||||
|
else for(p=row[_k];p>_i;p=row[_k])_k--;
|
||||||
|
_i-=p;
|
||||||
|
*_y++=(k0-_k+s)^s;
|
||||||
|
}
|
||||||
|
/*Lots of dimensions case:*/
|
||||||
|
else{
|
||||||
|
/*Are there any pulses in this dimension at all?*/
|
||||||
|
p=CELT_PVQ_U_ROW[_k][_n];
|
||||||
|
q=CELT_PVQ_U_ROW[_k+1][_n];
|
||||||
|
if(p<=_i&&_i<q){
|
||||||
|
_i-=p;
|
||||||
|
*_y++=0;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
/*Are the pulses in this dimension negative?*/
|
||||||
|
s=-(_i>=q);
|
||||||
|
_i-=q&s;
|
||||||
|
/*Count how many pulses were placed in this dimension.*/
|
||||||
|
k0=_k;
|
||||||
|
do p=CELT_PVQ_U_ROW[--_k][_n];
|
||||||
|
while(p>_i);
|
||||||
|
_i-=p;
|
||||||
|
*_y++=(k0-_k+s)^s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_n--;
|
||||||
|
}
|
||||||
|
/*_n==2*/
|
||||||
|
p=2*_k+1;
|
||||||
|
s=-(_i>=p);
|
||||||
|
_i-=p&s;
|
||||||
|
k0=_k;
|
||||||
|
_k=(_i+1)>>1;
|
||||||
|
if(_k)_i-=2*_k-1;
|
||||||
|
*_y++=(k0-_k+s)^s;
|
||||||
|
/*_n==1*/
|
||||||
|
s=-(int)_i;
|
||||||
|
*_y=(_k+s)^s;
|
||||||
|
}
|
||||||
|
|
||||||
|
void decode_pulses(int *_y,int _n,int _k,ec_dec *_dec){
|
||||||
|
cwrsi(_n,_k,ec_dec_uint(_dec,CELT_PVQ_V(_n,_k)),_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* SMALL_FOOTPRINT */
|
||||||
|
|
||||||
|
/*Computes the next row/column of any recurrence that obeys the relation
|
||||||
|
u[i][j]=u[i-1][j]+u[i][j-1]+u[i-1][j-1].
|
||||||
|
_ui0 is the base case for the new row/column.*/
|
||||||
|
static OPUS_INLINE void unext(opus_uint32 *_ui,unsigned _len,opus_uint32 _ui0){
|
||||||
|
opus_uint32 ui1;
|
||||||
|
unsigned j;
|
||||||
|
/*This do-while will overrun the array if we don't have storage for at least
|
||||||
|
2 values.*/
|
||||||
|
j=1; do {
|
||||||
|
ui1=UADD32(UADD32(_ui[j],_ui[j-1]),_ui0);
|
||||||
|
_ui[j-1]=_ui0;
|
||||||
|
_ui0=ui1;
|
||||||
|
} while (++j<_len);
|
||||||
|
_ui[j-1]=_ui0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Computes the previous row/column of any recurrence that obeys the relation
|
||||||
|
u[i-1][j]=u[i][j]-u[i][j-1]-u[i-1][j-1].
|
||||||
|
_ui0 is the base case for the new row/column.*/
|
||||||
|
static OPUS_INLINE void uprev(opus_uint32 *_ui,unsigned _n,opus_uint32 _ui0){
|
||||||
|
opus_uint32 ui1;
|
||||||
|
unsigned j;
|
||||||
|
/*This do-while will overrun the array if we don't have storage for at least
|
||||||
|
2 values.*/
|
||||||
|
j=1; do {
|
||||||
|
ui1=USUB32(USUB32(_ui[j],_ui[j-1]),_ui0);
|
||||||
|
_ui[j-1]=_ui0;
|
||||||
|
_ui0=ui1;
|
||||||
|
} while (++j<_n);
|
||||||
|
_ui[j-1]=_ui0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Compute V(_n,_k), as well as U(_n,0..._k+1).
|
||||||
|
_u: On exit, _u[i] contains U(_n,i) for i in [0..._k+1].*/
|
||||||
|
static opus_uint32 ncwrs_urow(unsigned _n,unsigned _k,opus_uint32 *_u){
|
||||||
|
opus_uint32 um2;
|
||||||
|
unsigned len;
|
||||||
|
unsigned k;
|
||||||
|
len=_k+2;
|
||||||
|
/*We require storage at least 3 values (e.g., _k>0).*/
|
||||||
|
celt_assert(len>=3);
|
||||||
|
_u[0]=0;
|
||||||
|
_u[1]=um2=1;
|
||||||
|
/*If _n==0, _u[0] should be 1 and the rest should be 0.*/
|
||||||
|
/*If _n==1, _u[i] should be 1 for i>1.*/
|
||||||
|
celt_assert(_n>=2);
|
||||||
|
/*If _k==0, the following do-while loop will overflow the buffer.*/
|
||||||
|
celt_assert(_k>0);
|
||||||
|
k=2;
|
||||||
|
do _u[k]=(k<<1)-1;
|
||||||
|
while(++k<len);
|
||||||
|
for(k=2;k<_n;k++)unext(_u+1,_k+1,1);
|
||||||
|
return _u[_k]+_u[_k+1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Returns the _i'th combination of _k elements chosen from a set of size _n
|
||||||
|
with associated sign bits.
|
||||||
|
_y: Returns the vector of pulses.
|
||||||
|
_u: Must contain entries [0..._k+1] of row _n of U() on input.
|
||||||
|
Its contents will be destructively modified.*/
|
||||||
|
static void cwrsi(int _n,int _k,opus_uint32 _i,int *_y,opus_uint32 *_u){
|
||||||
|
int j;
|
||||||
|
celt_assert(_n>0);
|
||||||
|
j=0;
|
||||||
|
do{
|
||||||
|
opus_uint32 p;
|
||||||
|
int s;
|
||||||
|
int yj;
|
||||||
|
p=_u[_k+1];
|
||||||
|
s=-(_i>=p);
|
||||||
|
_i-=p&s;
|
||||||
|
yj=_k;
|
||||||
|
p=_u[_k];
|
||||||
|
while(p>_i)p=_u[--_k];
|
||||||
|
_i-=p;
|
||||||
|
yj-=_k;
|
||||||
|
_y[j]=(yj+s)^s;
|
||||||
|
uprev(_u,_k+2,0);
|
||||||
|
}
|
||||||
|
while(++j<_n);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Returns the index of the given combination of K elements chosen from a set
|
||||||
|
of size 1 with associated sign bits.
|
||||||
|
_y: The vector of pulses, whose sum of absolute values is K.
|
||||||
|
_k: Returns K.*/
|
||||||
|
static OPUS_INLINE opus_uint32 icwrs1(const int *_y,int *_k){
|
||||||
|
*_k=abs(_y[0]);
|
||||||
|
return _y[0]<0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Returns the index of the given combination of K elements chosen from a set
|
||||||
|
of size _n with associated sign bits.
|
||||||
|
_y: The vector of pulses, whose sum of absolute values must be _k.
|
||||||
|
_nc: Returns V(_n,_k).*/
|
||||||
|
static OPUS_INLINE opus_uint32 icwrs(int _n,int _k,opus_uint32 *_nc,const int *_y,
|
||||||
|
opus_uint32 *_u){
|
||||||
|
opus_uint32 i;
|
||||||
|
int j;
|
||||||
|
int k;
|
||||||
|
/*We can't unroll the first two iterations of the loop unless _n>=2.*/
|
||||||
|
celt_assert(_n>=2);
|
||||||
|
_u[0]=0;
|
||||||
|
for(k=1;k<=_k+1;k++)_u[k]=(k<<1)-1;
|
||||||
|
i=icwrs1(_y+_n-1,&k);
|
||||||
|
j=_n-2;
|
||||||
|
i+=_u[k];
|
||||||
|
k+=abs(_y[j]);
|
||||||
|
if(_y[j]<0)i+=_u[k+1];
|
||||||
|
while(j-->0){
|
||||||
|
unext(_u,_k+2,0);
|
||||||
|
i+=_u[k];
|
||||||
|
k+=abs(_y[j]);
|
||||||
|
if(_y[j]<0)i+=_u[k+1];
|
||||||
|
}
|
||||||
|
*_nc=_u[k]+_u[k+1];
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CUSTOM_MODES
|
||||||
|
void get_required_bits(opus_int16 *_bits,int _n,int _maxk,int _frac){
|
||||||
|
int k;
|
||||||
|
/*_maxk==0 => there's nothing to do.*/
|
||||||
|
celt_assert(_maxk>0);
|
||||||
|
_bits[0]=0;
|
||||||
|
if (_n==1)
|
||||||
|
{
|
||||||
|
for (k=1;k<=_maxk;k++)
|
||||||
|
_bits[k] = 1<<_frac;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
VARDECL(opus_uint32,u);
|
||||||
|
SAVE_STACK;
|
||||||
|
ALLOC(u,_maxk+2U,opus_uint32);
|
||||||
|
ncwrs_urow(_n,_maxk,u);
|
||||||
|
for(k=1;k<=_maxk;k++)
|
||||||
|
_bits[k]=log2_frac(u[k]+u[k+1],_frac);
|
||||||
|
RESTORE_STACK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CUSTOM_MODES */
|
||||||
|
|
||||||
|
void encode_pulses(const int *_y,int _n,int _k,ec_enc *_enc){
|
||||||
|
opus_uint32 i;
|
||||||
|
VARDECL(opus_uint32,u);
|
||||||
|
opus_uint32 nc;
|
||||||
|
SAVE_STACK;
|
||||||
|
celt_assert(_k>0);
|
||||||
|
ALLOC(u,_k+2U,opus_uint32);
|
||||||
|
i=icwrs(_n,_k,&nc,_y,u);
|
||||||
|
ec_enc_uint(_enc,i,nc);
|
||||||
|
RESTORE_STACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void decode_pulses(int *_y,int _n,int _k,ec_dec *_dec){
|
||||||
|
VARDECL(opus_uint32,u);
|
||||||
|
SAVE_STACK;
|
||||||
|
celt_assert(_k>0);
|
||||||
|
ALLOC(u,_k+2U,opus_uint32);
|
||||||
|
cwrsi(_n,_k,ec_dec_uint(_dec,ncwrs_urow(_n,_k,u)),_y,u);
|
||||||
|
RESTORE_STACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* SMALL_FOOTPRINT */
|
|
@ -33,7 +33,7 @@
|
||||||
#if !defined(_ecintrin_H)
|
#if !defined(_ecintrin_H)
|
||||||
# define _ecintrin_H (1)
|
# define _ecintrin_H (1)
|
||||||
|
|
||||||
/*Some specific platforms may have optimized intrinsic or inline assembly
|
/*Some specific platforms may have optimized intrinsic or OPUS_INLINE assembly
|
||||||
versions of these functions which can substantially improve performance.
|
versions of these functions which can substantially improve performance.
|
||||||
We define macros for them to allow easy incorporation of these non-ANSI
|
We define macros for them to allow easy incorporation of these non-ANSI
|
||||||
features.*/
|
features.*/
|
|
@ -26,6 +26,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "opus_types.h"
|
#include "opus_types.h"
|
||||||
|
#include "opus_defines.h"
|
||||||
|
|
||||||
#if !defined(_entcode_H)
|
#if !defined(_entcode_H)
|
||||||
# define _entcode_H (1)
|
# define _entcode_H (1)
|
||||||
|
@ -83,15 +84,15 @@ struct ec_ctx{
|
||||||
int error;
|
int error;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline opus_uint32 ec_range_bytes(ec_ctx *_this){
|
static OPUS_INLINE opus_uint32 ec_range_bytes(ec_ctx *_this){
|
||||||
return _this->offs;
|
return _this->offs;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned char *ec_get_buffer(ec_ctx *_this){
|
static OPUS_INLINE unsigned char *ec_get_buffer(ec_ctx *_this){
|
||||||
return _this->buf;
|
return _this->buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int ec_get_error(ec_ctx *_this){
|
static OPUS_INLINE int ec_get_error(ec_ctx *_this){
|
||||||
return _this->error;
|
return _this->error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +102,7 @@ static inline int ec_get_error(ec_ctx *_this){
|
||||||
Return: The number of bits.
|
Return: The number of bits.
|
||||||
This will always be slightly larger than the exact value (e.g., all
|
This will always be slightly larger than the exact value (e.g., all
|
||||||
rounding error is in the positive direction).*/
|
rounding error is in the positive direction).*/
|
||||||
static inline int ec_tell(ec_ctx *_this){
|
static OPUS_INLINE int ec_tell(ec_ctx *_this){
|
||||||
return _this->nbits_total-EC_ILOG(_this->rng);
|
return _this->nbits_total-EC_ILOG(_this->rng);
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@
|
||||||
number=3,
|
number=3,
|
||||||
pages="256--294",
|
pages="256--294",
|
||||||
month=Jul,
|
month=Jul,
|
||||||
URL="http://www.stanford.edu/class/ee398/handouts/papers/Moffat98ArithmCoding.pdf"
|
URL="http://www.stanford.edu/class/ee398a/handouts/papers/Moffat98ArithmCoding.pdf"
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
static int ec_read_byte(ec_dec *_this){
|
static int ec_read_byte(ec_dec *_this){
|
|
@ -33,9 +33,9 @@
|
||||||
#define FIXED_DEBUG_H
|
#define FIXED_DEBUG_H
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include "opus_defines.h"
|
||||||
|
|
||||||
#ifdef CELT_C
|
#ifdef CELT_C
|
||||||
#include "opus_defines.h"
|
|
||||||
OPUS_EXPORT opus_int64 celt_mips=0;
|
OPUS_EXPORT opus_int64 celt_mips=0;
|
||||||
#else
|
#else
|
||||||
extern opus_int64 celt_mips;
|
extern opus_int64 celt_mips;
|
||||||
|
@ -59,7 +59,7 @@ extern opus_int64 celt_mips;
|
||||||
#define SHR(a,b) SHR32(a,b)
|
#define SHR(a,b) SHR32(a,b)
|
||||||
#define PSHR(a,b) PSHR32(a,b)
|
#define PSHR(a,b) PSHR32(a,b)
|
||||||
|
|
||||||
static inline short NEG16(int x)
|
static OPUS_INLINE short NEG16(int x)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
if (!VERIFY_SHORT(x))
|
if (!VERIFY_SHORT(x))
|
||||||
|
@ -80,7 +80,7 @@ static inline short NEG16(int x)
|
||||||
celt_mips++;
|
celt_mips++;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
static inline int NEG32(opus_int64 x)
|
static OPUS_INLINE int NEG32(opus_int64 x)
|
||||||
{
|
{
|
||||||
opus_int64 res;
|
opus_int64 res;
|
||||||
if (!VERIFY_INT(x))
|
if (!VERIFY_INT(x))
|
||||||
|
@ -103,7 +103,7 @@ static inline int NEG32(opus_int64 x)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define EXTRACT16(x) EXTRACT16_(x, __FILE__, __LINE__)
|
#define EXTRACT16(x) EXTRACT16_(x, __FILE__, __LINE__)
|
||||||
static inline short EXTRACT16_(int x, char *file, int line)
|
static OPUS_INLINE short EXTRACT16_(int x, char *file, int line)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
if (!VERIFY_SHORT(x))
|
if (!VERIFY_SHORT(x))
|
||||||
|
@ -119,7 +119,7 @@ static inline short EXTRACT16_(int x, char *file, int line)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define EXTEND32(x) EXTEND32_(x, __FILE__, __LINE__)
|
#define EXTEND32(x) EXTEND32_(x, __FILE__, __LINE__)
|
||||||
static inline int EXTEND32_(int x, char *file, int line)
|
static OPUS_INLINE int EXTEND32_(int x, char *file, int line)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
if (!VERIFY_SHORT(x))
|
if (!VERIFY_SHORT(x))
|
||||||
|
@ -135,7 +135,7 @@ static inline int EXTEND32_(int x, char *file, int line)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SHR16(a, shift) SHR16_(a, shift, __FILE__, __LINE__)
|
#define SHR16(a, shift) SHR16_(a, shift, __FILE__, __LINE__)
|
||||||
static inline short SHR16_(int a, int shift, char *file, int line)
|
static OPUS_INLINE short SHR16_(int a, int shift, char *file, int line)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
|
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
|
||||||
|
@ -157,7 +157,7 @@ static inline short SHR16_(int a, int shift, char *file, int line)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
#define SHL16(a, shift) SHL16_(a, shift, __FILE__, __LINE__)
|
#define SHL16(a, shift) SHL16_(a, shift, __FILE__, __LINE__)
|
||||||
static inline short SHL16_(int a, int shift, char *file, int line)
|
static OPUS_INLINE short SHL16_(int a, int shift, char *file, int line)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
|
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
|
||||||
|
@ -179,7 +179,7 @@ static inline short SHL16_(int a, int shift, char *file, int line)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int SHR32(opus_int64 a, int shift)
|
static OPUS_INLINE int SHR32(opus_int64 a, int shift)
|
||||||
{
|
{
|
||||||
opus_int64 res;
|
opus_int64 res;
|
||||||
if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
|
if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
|
||||||
|
@ -201,7 +201,7 @@ static inline int SHR32(opus_int64 a, int shift)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
#define SHL32(a, shift) SHL32_(a, shift, __FILE__, __LINE__)
|
#define SHL32(a, shift) SHL32_(a, shift, __FILE__, __LINE__)
|
||||||
static inline int SHL32_(opus_int64 a, int shift, char *file, int line)
|
static OPUS_INLINE int SHL32_(opus_int64 a, int shift, char *file, int line)
|
||||||
{
|
{
|
||||||
opus_int64 res;
|
opus_int64 res;
|
||||||
if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
|
if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
|
||||||
|
@ -234,7 +234,7 @@ static inline int SHL32_(opus_int64 a, int shift, char *file, int line)
|
||||||
//#define SHL(a,shift) ((a) << (shift))
|
//#define SHL(a,shift) ((a) << (shift))
|
||||||
|
|
||||||
#define ADD16(a, b) ADD16_(a, b, __FILE__, __LINE__)
|
#define ADD16(a, b) ADD16_(a, b, __FILE__, __LINE__)
|
||||||
static inline short ADD16_(int a, int b, char *file, int line)
|
static OPUS_INLINE short ADD16_(int a, int b, char *file, int line)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||||
|
@ -257,7 +257,7 @@ static inline short ADD16_(int a, int b, char *file, int line)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SUB16(a, b) SUB16_(a, b, __FILE__, __LINE__)
|
#define SUB16(a, b) SUB16_(a, b, __FILE__, __LINE__)
|
||||||
static inline short SUB16_(int a, int b, char *file, int line)
|
static OPUS_INLINE short SUB16_(int a, int b, char *file, int line)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||||
|
@ -280,7 +280,7 @@ static inline short SUB16_(int a, int b, char *file, int line)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ADD32(a, b) ADD32_(a, b, __FILE__, __LINE__)
|
#define ADD32(a, b) ADD32_(a, b, __FILE__, __LINE__)
|
||||||
static inline int ADD32_(opus_int64 a, opus_int64 b, char *file, int line)
|
static OPUS_INLINE int ADD32_(opus_int64 a, opus_int64 b, char *file, int line)
|
||||||
{
|
{
|
||||||
opus_int64 res;
|
opus_int64 res;
|
||||||
if (!VERIFY_INT(a) || !VERIFY_INT(b))
|
if (!VERIFY_INT(a) || !VERIFY_INT(b))
|
||||||
|
@ -303,7 +303,7 @@ static inline int ADD32_(opus_int64 a, opus_int64 b, char *file, int line)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SUB32(a, b) SUB32_(a, b, __FILE__, __LINE__)
|
#define SUB32(a, b) SUB32_(a, b, __FILE__, __LINE__)
|
||||||
static inline int SUB32_(opus_int64 a, opus_int64 b, char *file, int line)
|
static OPUS_INLINE int SUB32_(opus_int64 a, opus_int64 b, char *file, int line)
|
||||||
{
|
{
|
||||||
opus_int64 res;
|
opus_int64 res;
|
||||||
if (!VERIFY_INT(a) || !VERIFY_INT(b))
|
if (!VERIFY_INT(a) || !VERIFY_INT(b))
|
||||||
|
@ -327,7 +327,7 @@ static inline int SUB32_(opus_int64 a, opus_int64 b, char *file, int line)
|
||||||
|
|
||||||
#undef UADD32
|
#undef UADD32
|
||||||
#define UADD32(a, b) UADD32_(a, b, __FILE__, __LINE__)
|
#define UADD32(a, b) UADD32_(a, b, __FILE__, __LINE__)
|
||||||
static inline unsigned int UADD32_(opus_uint64 a, opus_uint64 b, char *file, int line)
|
static OPUS_INLINE unsigned int UADD32_(opus_uint64 a, opus_uint64 b, char *file, int line)
|
||||||
{
|
{
|
||||||
opus_uint64 res;
|
opus_uint64 res;
|
||||||
if (!VERIFY_UINT(a) || !VERIFY_UINT(b))
|
if (!VERIFY_UINT(a) || !VERIFY_UINT(b))
|
||||||
|
@ -351,7 +351,7 @@ static inline unsigned int UADD32_(opus_uint64 a, opus_uint64 b, char *file, int
|
||||||
|
|
||||||
#undef USUB32
|
#undef USUB32
|
||||||
#define USUB32(a, b) USUB32_(a, b, __FILE__, __LINE__)
|
#define USUB32(a, b) USUB32_(a, b, __FILE__, __LINE__)
|
||||||
static inline unsigned int USUB32_(opus_uint64 a, opus_uint64 b, char *file, int line)
|
static OPUS_INLINE unsigned int USUB32_(opus_uint64 a, opus_uint64 b, char *file, int line)
|
||||||
{
|
{
|
||||||
opus_uint64 res;
|
opus_uint64 res;
|
||||||
if (!VERIFY_UINT(a) || !VERIFY_UINT(b))
|
if (!VERIFY_UINT(a) || !VERIFY_UINT(b))
|
||||||
|
@ -381,7 +381,7 @@ static inline unsigned int USUB32_(opus_uint64 a, opus_uint64 b, char *file, int
|
||||||
}
|
}
|
||||||
|
|
||||||
/* result fits in 16 bits */
|
/* result fits in 16 bits */
|
||||||
static inline short MULT16_16_16(int a, int b)
|
static OPUS_INLINE short MULT16_16_16(int a, int b)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||||
|
@ -404,7 +404,7 @@ static inline short MULT16_16_16(int a, int b)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MULT16_16(a, b) MULT16_16_(a, b, __FILE__, __LINE__)
|
#define MULT16_16(a, b) MULT16_16_(a, b, __FILE__, __LINE__)
|
||||||
static inline int MULT16_16_(int a, int b, char *file, int line)
|
static OPUS_INLINE int MULT16_16_(int a, int b, char *file, int line)
|
||||||
{
|
{
|
||||||
opus_int64 res;
|
opus_int64 res;
|
||||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||||
|
@ -429,7 +429,7 @@ static inline int MULT16_16_(int a, int b, char *file, int line)
|
||||||
#define MAC16_16(c,a,b) (celt_mips-=2,ADD32((c),MULT16_16((a),(b))))
|
#define MAC16_16(c,a,b) (celt_mips-=2,ADD32((c),MULT16_16((a),(b))))
|
||||||
|
|
||||||
#define MULT16_32_QX(a, b, Q) MULT16_32_QX_(a, b, Q, __FILE__, __LINE__)
|
#define MULT16_32_QX(a, b, Q) MULT16_32_QX_(a, b, Q, __FILE__, __LINE__)
|
||||||
static inline int MULT16_32_QX_(int a, opus_int64 b, int Q, char *file, int line)
|
static OPUS_INLINE int MULT16_32_QX_(int a, opus_int64 b, int Q, char *file, int line)
|
||||||
{
|
{
|
||||||
opus_int64 res;
|
opus_int64 res;
|
||||||
if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
|
if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
|
||||||
|
@ -462,7 +462,7 @@ static inline int MULT16_32_QX_(int a, opus_int64 b, int Q, char *file, int line
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MULT16_32_PX(a, b, Q) MULT16_32_PX_(a, b, Q, __FILE__, __LINE__)
|
#define MULT16_32_PX(a, b, Q) MULT16_32_PX_(a, b, Q, __FILE__, __LINE__)
|
||||||
static inline int MULT16_32_PX_(int a, opus_int64 b, int Q, char *file, int line)
|
static OPUS_INLINE int MULT16_32_PX_(int a, opus_int64 b, int Q, char *file, int line)
|
||||||
{
|
{
|
||||||
opus_int64 res;
|
opus_int64 res;
|
||||||
if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
|
if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
|
||||||
|
@ -497,7 +497,7 @@ static inline int MULT16_32_PX_(int a, opus_int64 b, int Q, char *file, int line
|
||||||
#define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15)
|
#define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15)
|
||||||
#define MAC16_32_Q15(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q15((a),(b))))
|
#define MAC16_32_Q15(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q15((a),(b))))
|
||||||
|
|
||||||
static inline int SATURATE(int a, int b)
|
static OPUS_INLINE int SATURATE(int a, int b)
|
||||||
{
|
{
|
||||||
if (a>b)
|
if (a>b)
|
||||||
a=b;
|
a=b;
|
||||||
|
@ -507,7 +507,17 @@ static inline int SATURATE(int a, int b)
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int MULT16_16_Q11_32(int a, int b)
|
static OPUS_INLINE opus_int16 SATURATE16(opus_int32 a)
|
||||||
|
{
|
||||||
|
celt_mips+=3;
|
||||||
|
if (a>32767)
|
||||||
|
return 32767;
|
||||||
|
else if (a<-32768)
|
||||||
|
return -32768;
|
||||||
|
else return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
static OPUS_INLINE int MULT16_16_Q11_32(int a, int b)
|
||||||
{
|
{
|
||||||
opus_int64 res;
|
opus_int64 res;
|
||||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||||
|
@ -529,7 +539,7 @@ static inline int MULT16_16_Q11_32(int a, int b)
|
||||||
celt_mips+=3;
|
celt_mips+=3;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
static inline short MULT16_16_Q13(int a, int b)
|
static OPUS_INLINE short MULT16_16_Q13(int a, int b)
|
||||||
{
|
{
|
||||||
opus_int64 res;
|
opus_int64 res;
|
||||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||||
|
@ -551,7 +561,7 @@ static inline short MULT16_16_Q13(int a, int b)
|
||||||
celt_mips+=3;
|
celt_mips+=3;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
static inline short MULT16_16_Q14(int a, int b)
|
static OPUS_INLINE short MULT16_16_Q14(int a, int b)
|
||||||
{
|
{
|
||||||
opus_int64 res;
|
opus_int64 res;
|
||||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||||
|
@ -575,7 +585,7 @@ static inline short MULT16_16_Q14(int a, int b)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MULT16_16_Q15(a, b) MULT16_16_Q15_(a, b, __FILE__, __LINE__)
|
#define MULT16_16_Q15(a, b) MULT16_16_Q15_(a, b, __FILE__, __LINE__)
|
||||||
static inline short MULT16_16_Q15_(int a, int b, char *file, int line)
|
static OPUS_INLINE short MULT16_16_Q15_(int a, int b, char *file, int line)
|
||||||
{
|
{
|
||||||
opus_int64 res;
|
opus_int64 res;
|
||||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||||
|
@ -598,7 +608,7 @@ static inline short MULT16_16_Q15_(int a, int b, char *file, int line)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline short MULT16_16_P13(int a, int b)
|
static OPUS_INLINE short MULT16_16_P13(int a, int b)
|
||||||
{
|
{
|
||||||
opus_int64 res;
|
opus_int64 res;
|
||||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||||
|
@ -628,7 +638,7 @@ static inline short MULT16_16_P13(int a, int b)
|
||||||
celt_mips+=4;
|
celt_mips+=4;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
static inline short MULT16_16_P14(int a, int b)
|
static OPUS_INLINE short MULT16_16_P14(int a, int b)
|
||||||
{
|
{
|
||||||
opus_int64 res;
|
opus_int64 res;
|
||||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||||
|
@ -658,7 +668,7 @@ static inline short MULT16_16_P14(int a, int b)
|
||||||
celt_mips+=4;
|
celt_mips+=4;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
static inline short MULT16_16_P15(int a, int b)
|
static OPUS_INLINE short MULT16_16_P15(int a, int b)
|
||||||
{
|
{
|
||||||
opus_int64 res;
|
opus_int64 res;
|
||||||
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
|
||||||
|
@ -691,7 +701,7 @@ static inline short MULT16_16_P15(int a, int b)
|
||||||
|
|
||||||
#define DIV32_16(a, b) DIV32_16_(a, b, __FILE__, __LINE__)
|
#define DIV32_16(a, b) DIV32_16_(a, b, __FILE__, __LINE__)
|
||||||
|
|
||||||
static inline int DIV32_16_(opus_int64 a, opus_int64 b, char *file, int line)
|
static OPUS_INLINE int DIV32_16_(opus_int64 a, opus_int64 b, char *file, int line)
|
||||||
{
|
{
|
||||||
opus_int64 res;
|
opus_int64 res;
|
||||||
if (b==0)
|
if (b==0)
|
||||||
|
@ -726,7 +736,7 @@ static inline int DIV32_16_(opus_int64 a, opus_int64 b, char *file, int line)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DIV32(a, b) DIV32_(a, b, __FILE__, __LINE__)
|
#define DIV32(a, b) DIV32_(a, b, __FILE__, __LINE__)
|
||||||
static inline int DIV32_(opus_int64 a, opus_int64 b, char *file, int line)
|
static OPUS_INLINE int DIV32_(opus_int64 a, opus_int64 b, char *file, int line)
|
||||||
{
|
{
|
||||||
opus_int64 res;
|
opus_int64 res;
|
||||||
if (b==0)
|
if (b==0)
|
|
@ -40,7 +40,7 @@
|
||||||
#define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR((b),16)), SHR(MULT16_16SU((a),((b)&0x0000ffff)),16))
|
#define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR((b),16)), SHR(MULT16_16SU((a),((b)&0x0000ffff)),16))
|
||||||
|
|
||||||
/** 16x32 multiplication, followed by a 16-bit shift right (round-to-nearest). Results fits in 32 bits */
|
/** 16x32 multiplication, followed by a 16-bit shift right (round-to-nearest). Results fits in 32 bits */
|
||||||
#define MULT16_32_P16(a,b) ADD32(MULT16_16((a),SHR((b),16)), PSHR(MULT16_16((a),((b)&0x0000ffff)),16))
|
#define MULT16_32_P16(a,b) ADD32(MULT16_16((a),SHR((b),16)), PSHR(MULT16_16SU((a),((b)&0x0000ffff)),16))
|
||||||
|
|
||||||
/** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */
|
/** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */
|
||||||
#define MULT16_32_Q15(a,b) ADD32(SHL(MULT16_16((a),SHR((b),16)),1), SHR(MULT16_16SU((a),((b)&0x0000ffff)),15))
|
#define MULT16_32_Q15(a,b) ADD32(SHL(MULT16_16((a),SHR((b),16)),1), SHR(MULT16_16SU((a),((b)&0x0000ffff)),15))
|
||||||
|
@ -84,6 +84,8 @@
|
||||||
#define PSHR(a,shift) (SHR((a)+((EXTEND32(1)<<((shift))>>1)),shift))
|
#define PSHR(a,shift) (SHR((a)+((EXTEND32(1)<<((shift))>>1)),shift))
|
||||||
#define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
|
#define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
|
||||||
|
|
||||||
|
#define SATURATE16(x) (EXTRACT16((x)>32767 ? 32767 : (x)<-32768 ? -32768 : (x)))
|
||||||
|
|
||||||
/** Shift by a and round-to-neareast 32-bit value. Result is a 16-bit value */
|
/** Shift by a and round-to-neareast 32-bit value. Result is a 16-bit value */
|
||||||
#define ROUND16(x,a) (EXTRACT16(PSHR32((x),(a))))
|
#define ROUND16(x,a) (EXTRACT16(PSHR32((x),(a))))
|
||||||
/** Divide by two */
|
/** Divide by two */
|
||||||
|
@ -108,10 +110,13 @@
|
||||||
|
|
||||||
/** 16x16 multiply-add where the result fits in 32 bits */
|
/** 16x16 multiply-add where the result fits in 32 bits */
|
||||||
#define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b))))
|
#define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b))))
|
||||||
/** 16x32 multiply-add, followed by a 15-bit shift right. Results fits in 32 bits */
|
/** 16x32 multiply, followed by a 15-bit shift right and 32-bit add.
|
||||||
|
b must fit in 31 bits.
|
||||||
|
Result fits in 32 bits. */
|
||||||
#define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)))
|
#define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)))
|
||||||
|
|
||||||
#define MULT16_16_Q11_32(a,b) (SHR(MULT16_16((a),(b)),11))
|
#define MULT16_16_Q11_32(a,b) (SHR(MULT16_16((a),(b)),11))
|
||||||
|
#define MULT16_16_Q11(a,b) (SHR(MULT16_16((a),(b)),11))
|
||||||
#define MULT16_16_Q13(a,b) (SHR(MULT16_16((a),(b)),13))
|
#define MULT16_16_Q13(a,b) (SHR(MULT16_16((a),(b)),13))
|
||||||
#define MULT16_16_Q14(a,b) (SHR(MULT16_16((a),(b)),14))
|
#define MULT16_16_Q14(a,b) (SHR(MULT16_16((a),(b)),14))
|
||||||
#define MULT16_16_Q15(a,b) (SHR(MULT16_16((a),(b)),15))
|
#define MULT16_16_Q15(a,b) (SHR(MULT16_16((a),(b)),15))
|
|
@ -101,7 +101,7 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
/* Win32 doesn't seem to have these functions.
|
/* Win32 doesn't seem to have these functions.
|
||||||
** Therefore implement inline versions of these functions here.
|
** Therefore implement OPUS_INLINE versions of these functions here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
__inline long int
|
__inline long int
|
||||||
|
@ -128,7 +128,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef DISABLE_FLOAT_API
|
#ifndef DISABLE_FLOAT_API
|
||||||
static inline opus_int16 FLOAT2INT16(float x)
|
static OPUS_INLINE opus_int16 FLOAT2INT16(float x)
|
||||||
{
|
{
|
||||||
x = x*CELT_SIG_SCALE;
|
x = x*CELT_SIG_SCALE;
|
||||||
x = MAX32(x, -32768);
|
x = MAX32(x, -32768);
|
|
@ -40,7 +40,6 @@
|
||||||
#include "os_support.h"
|
#include "os_support.h"
|
||||||
#include "mathops.h"
|
#include "mathops.h"
|
||||||
#include "stack_alloc.h"
|
#include "stack_alloc.h"
|
||||||
#include "os_support.h"
|
|
||||||
|
|
||||||
/* The guts header contains all the multiplication and addition macros that are defined for
|
/* The guts header contains all the multiplication and addition macros that are defined for
|
||||||
complex numbers. It also delares the kf_ internal functions.
|
complex numbers. It also delares the kf_ internal functions.
|
||||||
|
@ -142,8 +141,6 @@ static void kf_bfly4(
|
||||||
C_ADDTO(*Fout, scratch[1]);
|
C_ADDTO(*Fout, scratch[1]);
|
||||||
C_ADD( scratch[3] , scratch[0] , scratch[2] );
|
C_ADD( scratch[3] , scratch[0] , scratch[2] );
|
||||||
C_SUB( scratch[4] , scratch[0] , scratch[2] );
|
C_SUB( scratch[4] , scratch[0] , scratch[2] );
|
||||||
Fout[m2].r = PSHR32(Fout[m2].r, 2);
|
|
||||||
Fout[m2].i = PSHR32(Fout[m2].i, 2);
|
|
||||||
C_SUB( Fout[m2], *Fout, scratch[3] );
|
C_SUB( Fout[m2], *Fout, scratch[3] );
|
||||||
tw1 += fstride;
|
tw1 += fstride;
|
||||||
tw2 += fstride*2;
|
tw2 += fstride*2;
|
|
@ -123,6 +123,8 @@ opus_val32 celt_sqrt(opus_val32 x)
|
||||||
static const opus_val16 C[5] = {23175, 11561, -3011, 1699, -664};
|
static const opus_val16 C[5] = {23175, 11561, -3011, 1699, -664};
|
||||||
if (x==0)
|
if (x==0)
|
||||||
return 0;
|
return 0;
|
||||||
|
else if (x>=1073741824)
|
||||||
|
return 32767;
|
||||||
k = (celt_ilog2(x)>>1)-7;
|
k = (celt_ilog2(x)>>1)-7;
|
||||||
x = VSHR32(x, 2*k);
|
x = VSHR32(x, 2*k);
|
||||||
n = x-32768;
|
n = x-32768;
|
||||||
|
@ -137,7 +139,7 @@ opus_val32 celt_sqrt(opus_val32 x)
|
||||||
#define L3 8277
|
#define L3 8277
|
||||||
#define L4 -626
|
#define L4 -626
|
||||||
|
|
||||||
static inline opus_val16 _celt_cos_pi_2(opus_val16 x)
|
static OPUS_INLINE opus_val16 _celt_cos_pi_2(opus_val16 x)
|
||||||
{
|
{
|
||||||
opus_val16 x2;
|
opus_val16 x2;
|
||||||
|
|
|
@ -43,6 +43,41 @@
|
||||||
|
|
||||||
unsigned isqrt32(opus_uint32 _val);
|
unsigned isqrt32(opus_uint32 _val);
|
||||||
|
|
||||||
|
#ifndef OVERRIDE_CELT_MAXABS16
|
||||||
|
static OPUS_INLINE opus_val32 celt_maxabs16(const opus_val16 *x, int len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
opus_val16 maxval = 0;
|
||||||
|
opus_val16 minval = 0;
|
||||||
|
for (i=0;i<len;i++)
|
||||||
|
{
|
||||||
|
maxval = MAX16(maxval, x[i]);
|
||||||
|
minval = MIN16(minval, x[i]);
|
||||||
|
}
|
||||||
|
return MAX32(EXTEND32(maxval),-EXTEND32(minval));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef OVERRIDE_CELT_MAXABS32
|
||||||
|
#ifdef FIXED_POINT
|
||||||
|
static OPUS_INLINE opus_val32 celt_maxabs32(const opus_val32 *x, int len)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
opus_val32 maxval = 0;
|
||||||
|
opus_val32 minval = 0;
|
||||||
|
for (i=0;i<len;i++)
|
||||||
|
{
|
||||||
|
maxval = MAX32(maxval, x[i]);
|
||||||
|
minval = MIN32(minval, x[i]);
|
||||||
|
}
|
||||||
|
return MAX32(maxval, -minval);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define celt_maxabs32(x,len) celt_maxabs16(x,len)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifndef FIXED_POINT
|
#ifndef FIXED_POINT
|
||||||
|
|
||||||
#define PI 3.141592653f
|
#define PI 3.141592653f
|
||||||
|
@ -60,7 +95,7 @@ unsigned isqrt32(opus_uint32 _val);
|
||||||
denorm, +/- inf and NaN are *not* handled */
|
denorm, +/- inf and NaN are *not* handled */
|
||||||
|
|
||||||
/** Base-2 log approximation (log2(x)). */
|
/** Base-2 log approximation (log2(x)). */
|
||||||
static inline float celt_log2(float x)
|
static OPUS_INLINE float celt_log2(float x)
|
||||||
{
|
{
|
||||||
int integer;
|
int integer;
|
||||||
float frac;
|
float frac;
|
||||||
|
@ -78,7 +113,7 @@ static inline float celt_log2(float x)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Base-2 exponential approximation (2^x). */
|
/** Base-2 exponential approximation (2^x). */
|
||||||
static inline float celt_exp2(float x)
|
static OPUS_INLINE float celt_exp2(float x)
|
||||||
{
|
{
|
||||||
int integer;
|
int integer;
|
||||||
float frac;
|
float frac;
|
||||||
|
@ -110,37 +145,16 @@ static inline float celt_exp2(float x)
|
||||||
|
|
||||||
#ifndef OVERRIDE_CELT_ILOG2
|
#ifndef OVERRIDE_CELT_ILOG2
|
||||||
/** Integer log in base2. Undefined for zero and negative numbers */
|
/** Integer log in base2. Undefined for zero and negative numbers */
|
||||||
static inline opus_int16 celt_ilog2(opus_int32 x)
|
static OPUS_INLINE opus_int16 celt_ilog2(opus_int32 x)
|
||||||
{
|
{
|
||||||
celt_assert2(x>0, "celt_ilog2() only defined for strictly positive numbers");
|
celt_assert2(x>0, "celt_ilog2() only defined for strictly positive numbers");
|
||||||
return EC_ILOG(x)-1;
|
return EC_ILOG(x)-1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef OVERRIDE_CELT_MAXABS16
|
|
||||||
static inline opus_val16 celt_maxabs16(opus_val16 *x, int len)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
opus_val16 maxval = 0;
|
|
||||||
for (i=0;i<len;i++)
|
|
||||||
maxval = MAX16(maxval, ABS16(x[i]));
|
|
||||||
return maxval;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef OVERRIDE_CELT_MAXABS32
|
|
||||||
static inline opus_val32 celt_maxabs32(opus_val32 *x, int len)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
opus_val32 maxval = 0;
|
|
||||||
for (i=0;i<len;i++)
|
|
||||||
maxval = MAX32(maxval, ABS32(x[i]));
|
|
||||||
return maxval;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Integer log in base2. Defined for zero, but not for negative numbers */
|
/** Integer log in base2. Defined for zero, but not for negative numbers */
|
||||||
static inline opus_int16 celt_zlog2(opus_val32 x)
|
static OPUS_INLINE opus_int16 celt_zlog2(opus_val32 x)
|
||||||
{
|
{
|
||||||
return x <= 0 ? 0 : celt_ilog2(x);
|
return x <= 0 ? 0 : celt_ilog2(x);
|
||||||
}
|
}
|
||||||
|
@ -151,7 +165,8 @@ opus_val32 celt_sqrt(opus_val32 x);
|
||||||
|
|
||||||
opus_val16 celt_cos_norm(opus_val32 x);
|
opus_val16 celt_cos_norm(opus_val32 x);
|
||||||
|
|
||||||
static inline opus_val16 celt_log2(opus_val32 x)
|
/** Base-2 logarithm approximation (log2(x)). (Q14 input, Q10 output) */
|
||||||
|
static OPUS_INLINE opus_val16 celt_log2(opus_val32 x)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
opus_val16 n, frac;
|
opus_val16 n, frac;
|
||||||
|
@ -176,8 +191,15 @@ static inline opus_val16 celt_log2(opus_val32 x)
|
||||||
#define D1 22804
|
#define D1 22804
|
||||||
#define D2 14819
|
#define D2 14819
|
||||||
#define D3 10204
|
#define D3 10204
|
||||||
|
|
||||||
|
static OPUS_INLINE opus_val32 celt_exp2_frac(opus_val16 x)
|
||||||
|
{
|
||||||
|
opus_val16 frac;
|
||||||
|
frac = SHL16(x, 4);
|
||||||
|
return ADD16(D0, MULT16_16_Q15(frac, ADD16(D1, MULT16_16_Q15(frac, ADD16(D2 , MULT16_16_Q15(D3,frac))))));
|
||||||
|
}
|
||||||
/** Base-2 exponential approximation (2^x). (Q10 input, Q16 output) */
|
/** Base-2 exponential approximation (2^x). (Q10 input, Q16 output) */
|
||||||
static inline opus_val32 celt_exp2(opus_val16 x)
|
static OPUS_INLINE opus_val32 celt_exp2(opus_val16 x)
|
||||||
{
|
{
|
||||||
int integer;
|
int integer;
|
||||||
opus_val16 frac;
|
opus_val16 frac;
|
||||||
|
@ -186,8 +208,7 @@ static inline opus_val32 celt_exp2(opus_val16 x)
|
||||||
return 0x7f000000;
|
return 0x7f000000;
|
||||||
else if (integer < -15)
|
else if (integer < -15)
|
||||||
return 0;
|
return 0;
|
||||||
frac = SHL16(x-SHL16(integer,10),4);
|
frac = celt_exp2_frac(x-SHL16(integer,10));
|
||||||
frac = ADD16(D0, MULT16_16_Q15(frac, ADD16(D1, MULT16_16_Q15(frac, ADD16(D2 , MULT16_16_Q15(D3,frac))))));
|
|
||||||
return VSHR32(EXTEND32(frac), -integer-2);
|
return VSHR32(EXTEND32(frac), -integer-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +225,7 @@ opus_val32 frac_div32(opus_val32 a, opus_val32 b);
|
||||||
|
|
||||||
/* Atan approximation using a 4th order polynomial. Input is in Q15 format
|
/* Atan approximation using a 4th order polynomial. Input is in Q15 format
|
||||||
and normalized by pi/4. Output is in Q15 format */
|
and normalized by pi/4. Output is in Q15 format */
|
||||||
static inline opus_val16 celt_atan01(opus_val16 x)
|
static OPUS_INLINE opus_val16 celt_atan01(opus_val16 x)
|
||||||
{
|
{
|
||||||
return MULT16_16_P15(x, ADD32(M1, MULT16_16_P15(x, ADD32(M2, MULT16_16_P15(x, ADD32(M3, MULT16_16_P15(M4, x)))))));
|
return MULT16_16_P15(x, ADD32(M1, MULT16_16_P15(x, ADD32(M2, MULT16_16_P15(x, ADD32(M3, MULT16_16_P15(M4, x)))))));
|
||||||
}
|
}
|
||||||
|
@ -215,7 +236,7 @@ static inline opus_val16 celt_atan01(opus_val16 x)
|
||||||
#undef M4
|
#undef M4
|
||||||
|
|
||||||
/* atan2() approximation valid for positive input values */
|
/* atan2() approximation valid for positive input values */
|
||||||
static inline opus_val16 celt_atan2p(opus_val16 y, opus_val16 x)
|
static OPUS_INLINE opus_val16 celt_atan2p(opus_val16 y, opus_val16 x)
|
||||||
{
|
{
|
||||||
if (y < x)
|
if (y < x)
|
||||||
{
|
{
|
|
@ -109,12 +109,14 @@ void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar
|
||||||
int N, N2, N4;
|
int N, N2, N4;
|
||||||
kiss_twiddle_scalar sine;
|
kiss_twiddle_scalar sine;
|
||||||
VARDECL(kiss_fft_scalar, f);
|
VARDECL(kiss_fft_scalar, f);
|
||||||
|
VARDECL(kiss_fft_scalar, f2);
|
||||||
SAVE_STACK;
|
SAVE_STACK;
|
||||||
N = l->n;
|
N = l->n;
|
||||||
N >>= shift;
|
N >>= shift;
|
||||||
N2 = N>>1;
|
N2 = N>>1;
|
||||||
N4 = N>>2;
|
N4 = N>>2;
|
||||||
ALLOC(f, N2, kiss_fft_scalar);
|
ALLOC(f, N2, kiss_fft_scalar);
|
||||||
|
ALLOC(f2, N2, kiss_fft_scalar);
|
||||||
/* sin(x) ~= x here */
|
/* sin(x) ~= x here */
|
||||||
#ifdef FIXED_POINT
|
#ifdef FIXED_POINT
|
||||||
sine = TRIG_UPSCALE*(QCONST16(0.7853981f, 15)+N2)/N;
|
sine = TRIG_UPSCALE*(QCONST16(0.7853981f, 15)+N2)/N;
|
||||||
|
@ -131,7 +133,7 @@ void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar
|
||||||
kiss_fft_scalar * OPUS_RESTRICT yp = f;
|
kiss_fft_scalar * OPUS_RESTRICT yp = f;
|
||||||
const opus_val16 * OPUS_RESTRICT wp1 = window+(overlap>>1);
|
const opus_val16 * OPUS_RESTRICT wp1 = window+(overlap>>1);
|
||||||
const opus_val16 * OPUS_RESTRICT wp2 = window+(overlap>>1)-1;
|
const opus_val16 * OPUS_RESTRICT wp2 = window+(overlap>>1)-1;
|
||||||
for(i=0;i<(overlap>>2);i++)
|
for(i=0;i<((overlap+3)>>2);i++)
|
||||||
{
|
{
|
||||||
/* Real part arranged as -d-cR, Imag part arranged as -b+aR*/
|
/* Real part arranged as -d-cR, Imag part arranged as -b+aR*/
|
||||||
*yp++ = MULT16_32_Q15(*wp2, xp1[N2]) + MULT16_32_Q15(*wp1,*xp2);
|
*yp++ = MULT16_32_Q15(*wp2, xp1[N2]) + MULT16_32_Q15(*wp1,*xp2);
|
||||||
|
@ -143,7 +145,7 @@ void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar
|
||||||
}
|
}
|
||||||
wp1 = window;
|
wp1 = window;
|
||||||
wp2 = window+overlap-1;
|
wp2 = window+overlap-1;
|
||||||
for(;i<N4-(overlap>>2);i++)
|
for(;i<N4-((overlap+3)>>2);i++)
|
||||||
{
|
{
|
||||||
/* Real part arranged as a-bR, Imag part arranged as -c-dR */
|
/* Real part arranged as a-bR, Imag part arranged as -c-dR */
|
||||||
*yp++ = *xp2;
|
*yp++ = *xp2;
|
||||||
|
@ -180,12 +182,12 @@ void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar
|
||||||
}
|
}
|
||||||
|
|
||||||
/* N/4 complex FFT, down-scales by 4/N */
|
/* N/4 complex FFT, down-scales by 4/N */
|
||||||
opus_fft(l->kfft[shift], (kiss_fft_cpx *)f, (kiss_fft_cpx *)in);
|
opus_fft(l->kfft[shift], (kiss_fft_cpx *)f, (kiss_fft_cpx *)f2);
|
||||||
|
|
||||||
/* Post-rotate */
|
/* Post-rotate */
|
||||||
{
|
{
|
||||||
/* Temp pointers to make it really clear to the compiler what we're doing */
|
/* Temp pointers to make it really clear to the compiler what we're doing */
|
||||||
const kiss_fft_scalar * OPUS_RESTRICT fp = in;
|
const kiss_fft_scalar * OPUS_RESTRICT fp = f2;
|
||||||
kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
|
kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
|
||||||
kiss_fft_scalar * OPUS_RESTRICT yp2 = out+stride*(N2-1);
|
kiss_fft_scalar * OPUS_RESTRICT yp2 = out+stride*(N2-1);
|
||||||
const kiss_twiddle_scalar *t = &l->trig[0];
|
const kiss_twiddle_scalar *t = &l->trig[0];
|
||||||
|
@ -212,14 +214,12 @@ void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scala
|
||||||
int i;
|
int i;
|
||||||
int N, N2, N4;
|
int N, N2, N4;
|
||||||
kiss_twiddle_scalar sine;
|
kiss_twiddle_scalar sine;
|
||||||
VARDECL(kiss_fft_scalar, f);
|
|
||||||
VARDECL(kiss_fft_scalar, f2);
|
VARDECL(kiss_fft_scalar, f2);
|
||||||
SAVE_STACK;
|
SAVE_STACK;
|
||||||
N = l->n;
|
N = l->n;
|
||||||
N >>= shift;
|
N >>= shift;
|
||||||
N2 = N>>1;
|
N2 = N>>1;
|
||||||
N4 = N>>2;
|
N4 = N>>2;
|
||||||
ALLOC(f, N2, kiss_fft_scalar);
|
|
||||||
ALLOC(f2, N2, kiss_fft_scalar);
|
ALLOC(f2, N2, kiss_fft_scalar);
|
||||||
/* sin(x) ~= x here */
|
/* sin(x) ~= x here */
|
||||||
#ifdef FIXED_POINT
|
#ifdef FIXED_POINT
|
||||||
|
@ -249,81 +249,60 @@ void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scala
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Inverse N/4 complex FFT. This one should *not* downscale even in fixed-point */
|
/* Inverse N/4 complex FFT. This one should *not* downscale even in fixed-point */
|
||||||
opus_ifft(l->kfft[shift], (kiss_fft_cpx *)f2, (kiss_fft_cpx *)f);
|
opus_ifft(l->kfft[shift], (kiss_fft_cpx *)f2, (kiss_fft_cpx *)(out+(overlap>>1)));
|
||||||
|
|
||||||
/* Post-rotate */
|
/* Post-rotate and de-shuffle from both ends of the buffer at once to make
|
||||||
|
it in-place. */
|
||||||
{
|
{
|
||||||
kiss_fft_scalar * OPUS_RESTRICT fp = f;
|
kiss_fft_scalar * OPUS_RESTRICT yp0 = out+(overlap>>1);
|
||||||
|
kiss_fft_scalar * OPUS_RESTRICT yp1 = out+(overlap>>1)+N2-2;
|
||||||
const kiss_twiddle_scalar *t = &l->trig[0];
|
const kiss_twiddle_scalar *t = &l->trig[0];
|
||||||
|
/* Loop to (N4+1)>>1 to handle odd N4. When N4 is odd, the
|
||||||
for(i=0;i<N4;i++)
|
middle pair will be computed twice. */
|
||||||
|
for(i=0;i<(N4+1)>>1;i++)
|
||||||
{
|
{
|
||||||
kiss_fft_scalar re, im, yr, yi;
|
kiss_fft_scalar re, im, yr, yi;
|
||||||
re = fp[0];
|
kiss_twiddle_scalar t0, t1;
|
||||||
im = fp[1];
|
re = yp0[0];
|
||||||
|
im = yp0[1];
|
||||||
|
t0 = t[i<<shift];
|
||||||
|
t1 = t[(N4-i)<<shift];
|
||||||
/* We'd scale up by 2 here, but instead it's done when mixing the windows */
|
/* We'd scale up by 2 here, but instead it's done when mixing the windows */
|
||||||
yr = S_MUL(re,t[i<<shift]) - S_MUL(im,t[(N4-i)<<shift]);
|
yr = S_MUL(re,t0) - S_MUL(im,t1);
|
||||||
yi = S_MUL(im,t[i<<shift]) + S_MUL(re,t[(N4-i)<<shift]);
|
yi = S_MUL(im,t0) + S_MUL(re,t1);
|
||||||
|
re = yp1[0];
|
||||||
|
im = yp1[1];
|
||||||
/* works because the cos is nearly one */
|
/* works because the cos is nearly one */
|
||||||
*fp++ = yr - S_MUL(yi,sine);
|
yp0[0] = -(yr - S_MUL(yi,sine));
|
||||||
*fp++ = yi + S_MUL(yr,sine);
|
yp1[1] = yi + S_MUL(yr,sine);
|
||||||
|
|
||||||
|
t0 = t[(N4-i-1)<<shift];
|
||||||
|
t1 = t[(i+1)<<shift];
|
||||||
|
/* We'd scale up by 2 here, but instead it's done when mixing the windows */
|
||||||
|
yr = S_MUL(re,t0) - S_MUL(im,t1);
|
||||||
|
yi = S_MUL(im,t0) + S_MUL(re,t1);
|
||||||
|
/* works because the cos is nearly one */
|
||||||
|
yp1[0] = -(yr - S_MUL(yi,sine));
|
||||||
|
yp0[1] = yi + S_MUL(yr,sine);
|
||||||
|
yp0 += 2;
|
||||||
|
yp1 -= 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* De-shuffle the components for the middle of the window only */
|
|
||||||
{
|
|
||||||
const kiss_fft_scalar * OPUS_RESTRICT fp1 = f;
|
|
||||||
const kiss_fft_scalar * OPUS_RESTRICT fp2 = f+N2-1;
|
|
||||||
kiss_fft_scalar * OPUS_RESTRICT yp = f2;
|
|
||||||
for(i = 0; i < N4; i++)
|
|
||||||
{
|
|
||||||
*yp++ =-*fp1;
|
|
||||||
*yp++ = *fp2;
|
|
||||||
fp1 += 2;
|
|
||||||
fp2 -= 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
out -= (N2-overlap)>>1;
|
|
||||||
/* Mirror on both sides for TDAC */
|
/* Mirror on both sides for TDAC */
|
||||||
{
|
{
|
||||||
kiss_fft_scalar * OPUS_RESTRICT fp1 = f2+N4-1;
|
kiss_fft_scalar * OPUS_RESTRICT xp1 = out+overlap-1;
|
||||||
kiss_fft_scalar * OPUS_RESTRICT xp1 = out+N2-1;
|
kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
|
||||||
kiss_fft_scalar * OPUS_RESTRICT yp1 = out+N4-overlap/2;
|
|
||||||
const opus_val16 * OPUS_RESTRICT wp1 = window;
|
const opus_val16 * OPUS_RESTRICT wp1 = window;
|
||||||
const opus_val16 * OPUS_RESTRICT wp2 = window+overlap-1;
|
const opus_val16 * OPUS_RESTRICT wp2 = window+overlap-1;
|
||||||
for(i = 0; i< N4-overlap/2; i++)
|
|
||||||
|
for(i = 0; i < overlap/2; i++)
|
||||||
{
|
{
|
||||||
*xp1 = *fp1;
|
kiss_fft_scalar x1, x2;
|
||||||
xp1--;
|
x1 = *xp1;
|
||||||
fp1--;
|
x2 = *yp1;
|
||||||
}
|
*yp1++ = MULT16_32_Q15(*wp2, x2) - MULT16_32_Q15(*wp1, x1);
|
||||||
for(; i < N4; i++)
|
*xp1-- = MULT16_32_Q15(*wp1, x2) + MULT16_32_Q15(*wp2, x1);
|
||||||
{
|
|
||||||
kiss_fft_scalar x1;
|
|
||||||
x1 = *fp1--;
|
|
||||||
*yp1++ +=-MULT16_32_Q15(*wp1, x1);
|
|
||||||
*xp1-- += MULT16_32_Q15(*wp2, x1);
|
|
||||||
wp1++;
|
|
||||||
wp2--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
kiss_fft_scalar * OPUS_RESTRICT fp2 = f2+N4;
|
|
||||||
kiss_fft_scalar * OPUS_RESTRICT xp2 = out+N2;
|
|
||||||
kiss_fft_scalar * OPUS_RESTRICT yp2 = out+N-1-(N4-overlap/2);
|
|
||||||
const opus_val16 * OPUS_RESTRICT wp1 = window;
|
|
||||||
const opus_val16 * OPUS_RESTRICT wp2 = window+overlap-1;
|
|
||||||
for(i = 0; i< N4-overlap/2; i++)
|
|
||||||
{
|
|
||||||
*xp2 = *fp2;
|
|
||||||
xp2++;
|
|
||||||
fp2++;
|
|
||||||
}
|
|
||||||
for(; i < N4; i++)
|
|
||||||
{
|
|
||||||
kiss_fft_scalar x2;
|
|
||||||
x2 = *fp2++;
|
|
||||||
*yp2-- = MULT16_32_Q15(*wp1, x2);
|
|
||||||
*xp2++ = MULT16_32_Q15(*wp2, x2);
|
|
||||||
wp1++;
|
wp1++;
|
||||||
wp2--;
|
wp2--;
|
||||||
}
|
}
|
|
@ -345,6 +345,14 @@ CELTMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error)
|
||||||
mode->eBands = compute_ebands(Fs, mode->shortMdctSize, res, &mode->nbEBands);
|
mode->eBands = compute_ebands(Fs, mode->shortMdctSize, res, &mode->nbEBands);
|
||||||
if (mode->eBands==NULL)
|
if (mode->eBands==NULL)
|
||||||
goto failure;
|
goto failure;
|
||||||
|
#if !defined(SMALL_FOOTPRINT)
|
||||||
|
/* Make sure we don't allocate a band larger than our PVQ table.
|
||||||
|
208 should be enough, but let's be paranoid. */
|
||||||
|
if ((mode->eBands[mode->nbEBands] - mode->eBands[mode->nbEBands-1])<<LM >
|
||||||
|
208) {
|
||||||
|
goto failure;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
mode->effEBands = mode->nbEBands;
|
mode->effEBands = mode->nbEBands;
|
||||||
while (mode->eBands[mode->effEBands] > mode->shortMdctSize)
|
while (mode->eBands[mode->effEBands] > mode->shortMdctSize)
|
|
@ -35,13 +35,16 @@
|
||||||
# include "custom_support.h"
|
# include "custom_support.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "opus_types.h"
|
||||||
|
#include "opus_defines.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
/** Opus wrapper for malloc(). To do your own dynamic allocation, all you need to do is replace this function and opus_free */
|
/** Opus wrapper for malloc(). To do your own dynamic allocation, all you need to do is replace this function and opus_free */
|
||||||
#ifndef OVERRIDE_OPUS_ALLOC
|
#ifndef OVERRIDE_OPUS_ALLOC
|
||||||
static inline void *opus_alloc (size_t size)
|
static OPUS_INLINE void *opus_alloc (size_t size)
|
||||||
{
|
{
|
||||||
return malloc(size);
|
return malloc(size);
|
||||||
}
|
}
|
||||||
|
@ -49,7 +52,7 @@ static inline void *opus_alloc (size_t size)
|
||||||
|
|
||||||
/** Same as celt_alloc(), except that the area is only needed inside a CELT call (might cause problem with wideband though) */
|
/** Same as celt_alloc(), except that the area is only needed inside a CELT call (might cause problem with wideband though) */
|
||||||
#ifndef OVERRIDE_OPUS_ALLOC_SCRATCH
|
#ifndef OVERRIDE_OPUS_ALLOC_SCRATCH
|
||||||
static inline void *opus_alloc_scratch (size_t size)
|
static OPUS_INLINE void *opus_alloc_scratch (size_t size)
|
||||||
{
|
{
|
||||||
/* Scratch space doesn't need to be cleared */
|
/* Scratch space doesn't need to be cleared */
|
||||||
return opus_alloc(size);
|
return opus_alloc(size);
|
||||||
|
@ -58,7 +61,7 @@ static inline void *opus_alloc_scratch (size_t size)
|
||||||
|
|
||||||
/** Opus wrapper for free(). To do your own dynamic allocation, all you need to do is replace this function and opus_alloc */
|
/** Opus wrapper for free(). To do your own dynamic allocation, all you need to do is replace this function and opus_alloc */
|
||||||
#ifndef OVERRIDE_OPUS_FREE
|
#ifndef OVERRIDE_OPUS_FREE
|
||||||
static inline void opus_free (void *ptr)
|
static OPUS_INLINE void opus_free (void *ptr)
|
||||||
{
|
{
|
||||||
free(ptr);
|
free(ptr);
|
||||||
}
|
}
|
|
@ -102,13 +102,57 @@ static void find_best_pitch(opus_val32 *xcorr, opus_val16 *y, int len,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void celt_fir5(const opus_val16 *x,
|
||||||
|
const opus_val16 *num,
|
||||||
|
opus_val16 *y,
|
||||||
|
int N,
|
||||||
|
opus_val16 *mem)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
opus_val16 num0, num1, num2, num3, num4;
|
||||||
|
opus_val32 mem0, mem1, mem2, mem3, mem4;
|
||||||
|
num0=num[0];
|
||||||
|
num1=num[1];
|
||||||
|
num2=num[2];
|
||||||
|
num3=num[3];
|
||||||
|
num4=num[4];
|
||||||
|
mem0=mem[0];
|
||||||
|
mem1=mem[1];
|
||||||
|
mem2=mem[2];
|
||||||
|
mem3=mem[3];
|
||||||
|
mem4=mem[4];
|
||||||
|
for (i=0;i<N;i++)
|
||||||
|
{
|
||||||
|
opus_val32 sum = SHL32(EXTEND32(x[i]), SIG_SHIFT);
|
||||||
|
sum = MAC16_16(sum,num0,mem0);
|
||||||
|
sum = MAC16_16(sum,num1,mem1);
|
||||||
|
sum = MAC16_16(sum,num2,mem2);
|
||||||
|
sum = MAC16_16(sum,num3,mem3);
|
||||||
|
sum = MAC16_16(sum,num4,mem4);
|
||||||
|
mem4 = mem3;
|
||||||
|
mem3 = mem2;
|
||||||
|
mem2 = mem1;
|
||||||
|
mem1 = mem0;
|
||||||
|
mem0 = x[i];
|
||||||
|
y[i] = ROUND16(sum, SIG_SHIFT);
|
||||||
|
}
|
||||||
|
mem[0]=mem0;
|
||||||
|
mem[1]=mem1;
|
||||||
|
mem[2]=mem2;
|
||||||
|
mem[3]=mem3;
|
||||||
|
mem[4]=mem4;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x_lp,
|
void pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x_lp,
|
||||||
int len, int C)
|
int len, int C, int arch)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
opus_val32 ac[5];
|
opus_val32 ac[5];
|
||||||
opus_val16 tmp=Q15ONE;
|
opus_val16 tmp=Q15ONE;
|
||||||
opus_val16 lpc[4], mem[4]={0,0,0,0};
|
opus_val16 lpc[4], mem[5]={0,0,0,0,0};
|
||||||
|
opus_val16 lpc2[5];
|
||||||
|
opus_val16 c1 = QCONST16(.8f,15);
|
||||||
#ifdef FIXED_POINT
|
#ifdef FIXED_POINT
|
||||||
int shift;
|
int shift;
|
||||||
opus_val32 maxabs = celt_maxabs32(x[0], len);
|
opus_val32 maxabs = celt_maxabs32(x[0], len);
|
||||||
|
@ -136,7 +180,7 @@ void pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x
|
||||||
}
|
}
|
||||||
|
|
||||||
_celt_autocorr(x_lp, ac, NULL, 0,
|
_celt_autocorr(x_lp, ac, NULL, 0,
|
||||||
4, len>>1);
|
4, len>>1, arch);
|
||||||
|
|
||||||
/* Noise floor -40 dB */
|
/* Noise floor -40 dB */
|
||||||
#ifdef FIXED_POINT
|
#ifdef FIXED_POINT
|
||||||
|
@ -161,16 +205,96 @@ void pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x
|
||||||
tmp = MULT16_16_Q15(QCONST16(.9f,15), tmp);
|
tmp = MULT16_16_Q15(QCONST16(.9f,15), tmp);
|
||||||
lpc[i] = MULT16_16_Q15(lpc[i], tmp);
|
lpc[i] = MULT16_16_Q15(lpc[i], tmp);
|
||||||
}
|
}
|
||||||
celt_fir(x_lp, lpc, x_lp, len>>1, 4, mem);
|
/* Add a zero */
|
||||||
|
lpc2[0] = lpc[0] + QCONST16(.8f,SIG_SHIFT);
|
||||||
mem[0]=0;
|
lpc2[1] = lpc[1] + MULT16_16_Q15(c1,lpc[0]);
|
||||||
lpc[0]=QCONST16(.8f,12);
|
lpc2[2] = lpc[2] + MULT16_16_Q15(c1,lpc[1]);
|
||||||
celt_fir(x_lp, lpc, x_lp, len>>1, 1, mem);
|
lpc2[3] = lpc[3] + MULT16_16_Q15(c1,lpc[2]);
|
||||||
|
lpc2[4] = MULT16_16_Q15(c1,lpc[3]);
|
||||||
|
celt_fir5(x_lp, lpc2, x_lp, len>>1, mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 /* This is a simple version of the pitch correlation that should work
|
||||||
|
well on DSPs like Blackfin and TI C5x/C6x */
|
||||||
|
|
||||||
|
#ifdef FIXED_POINT
|
||||||
|
opus_val32
|
||||||
|
#else
|
||||||
|
void
|
||||||
|
#endif
|
||||||
|
celt_pitch_xcorr(opus_val16 *x, opus_val16 *y, opus_val32 *xcorr, int len, int max_pitch)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
#ifdef FIXED_POINT
|
||||||
|
opus_val32 maxcorr=1;
|
||||||
|
#endif
|
||||||
|
for (i=0;i<max_pitch;i++)
|
||||||
|
{
|
||||||
|
opus_val32 sum = 0;
|
||||||
|
for (j=0;j<len;j++)
|
||||||
|
sum = MAC16_16(sum, x[j],y[i+j]);
|
||||||
|
xcorr[i] = sum;
|
||||||
|
#ifdef FIXED_POINT
|
||||||
|
maxcorr = MAX32(maxcorr, sum);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#ifdef FIXED_POINT
|
||||||
|
return maxcorr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#else /* Unrolled version of the pitch correlation -- runs faster on x86 and ARM */
|
||||||
|
|
||||||
|
#ifdef FIXED_POINT
|
||||||
|
opus_val32
|
||||||
|
#else
|
||||||
|
void
|
||||||
|
#endif
|
||||||
|
celt_pitch_xcorr_c(const opus_val16 *_x, const opus_val16 *_y, opus_val32 *xcorr, int len, int max_pitch)
|
||||||
|
{
|
||||||
|
int i,j;
|
||||||
|
/*The EDSP version requires that max_pitch is at least 1, and that _x is
|
||||||
|
32-bit aligned.
|
||||||
|
Since it's hard to put asserts in assembly, put them here.*/
|
||||||
|
celt_assert(max_pitch>0);
|
||||||
|
celt_assert((((unsigned char *)_x-(unsigned char *)NULL)&3)==0);
|
||||||
|
#ifdef FIXED_POINT
|
||||||
|
opus_val32 maxcorr=1;
|
||||||
|
#endif
|
||||||
|
for (i=0;i<max_pitch-3;i+=4)
|
||||||
|
{
|
||||||
|
opus_val32 sum[4]={0,0,0,0};
|
||||||
|
xcorr_kernel(_x, _y+i, sum, len);
|
||||||
|
xcorr[i]=sum[0];
|
||||||
|
xcorr[i+1]=sum[1];
|
||||||
|
xcorr[i+2]=sum[2];
|
||||||
|
xcorr[i+3]=sum[3];
|
||||||
|
#ifdef FIXED_POINT
|
||||||
|
sum[0] = MAX32(sum[0], sum[1]);
|
||||||
|
sum[2] = MAX32(sum[2], sum[3]);
|
||||||
|
sum[0] = MAX32(sum[0], sum[2]);
|
||||||
|
maxcorr = MAX32(maxcorr, sum[0]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/* In case max_pitch isn't a multiple of 4, do non-unrolled version. */
|
||||||
|
for (;i<max_pitch;i++)
|
||||||
|
{
|
||||||
|
opus_val32 sum = 0;
|
||||||
|
for (j=0;j<len;j++)
|
||||||
|
sum = MAC16_16(sum, _x[j],_y[i+j]);
|
||||||
|
xcorr[i] = sum;
|
||||||
|
#ifdef FIXED_POINT
|
||||||
|
maxcorr = MAX32(maxcorr, sum);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#ifdef FIXED_POINT
|
||||||
|
return maxcorr;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
void pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTRICT y,
|
void pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTRICT y,
|
||||||
int len, int max_pitch, int *pitch)
|
int len, int max_pitch, int *pitch, int arch)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
int lag;
|
int lag;
|
||||||
|
@ -179,8 +303,8 @@ void pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTR
|
||||||
VARDECL(opus_val16, y_lp4);
|
VARDECL(opus_val16, y_lp4);
|
||||||
VARDECL(opus_val32, xcorr);
|
VARDECL(opus_val32, xcorr);
|
||||||
#ifdef FIXED_POINT
|
#ifdef FIXED_POINT
|
||||||
opus_val32 maxcorr=1;
|
opus_val32 maxcorr;
|
||||||
opus_val16 xmax, ymax;
|
opus_val32 xmax, ymax;
|
||||||
int shift=0;
|
int shift=0;
|
||||||
#endif
|
#endif
|
||||||
int offset;
|
int offset;
|
||||||
|
@ -204,7 +328,7 @@ void pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTR
|
||||||
#ifdef FIXED_POINT
|
#ifdef FIXED_POINT
|
||||||
xmax = celt_maxabs16(x_lp4, len>>2);
|
xmax = celt_maxabs16(x_lp4, len>>2);
|
||||||
ymax = celt_maxabs16(y_lp4, lag>>2);
|
ymax = celt_maxabs16(y_lp4, lag>>2);
|
||||||
shift = celt_ilog2(MAX16(1, MAX16(xmax, ymax)))-11;
|
shift = celt_ilog2(MAX32(1, MAX32(xmax, ymax)))-11;
|
||||||
if (shift>0)
|
if (shift>0)
|
||||||
{
|
{
|
||||||
for (j=0;j<len>>2;j++)
|
for (j=0;j<len>>2;j++)
|
||||||
|
@ -220,16 +344,11 @@ void pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTR
|
||||||
|
|
||||||
/* Coarse search with 4x decimation */
|
/* Coarse search with 4x decimation */
|
||||||
|
|
||||||
for (i=0;i<max_pitch>>2;i++)
|
|
||||||
{
|
|
||||||
opus_val32 sum = 0;
|
|
||||||
for (j=0;j<len>>2;j++)
|
|
||||||
sum = MAC16_16(sum, x_lp4[j],y_lp4[i+j]);
|
|
||||||
xcorr[i] = MAX32(-1, sum);
|
|
||||||
#ifdef FIXED_POINT
|
#ifdef FIXED_POINT
|
||||||
maxcorr = MAX32(maxcorr, sum);
|
maxcorr =
|
||||||
#endif
|
#endif
|
||||||
}
|
celt_pitch_xcorr(x_lp4, y_lp4, xcorr, len>>2, max_pitch>>2, arch);
|
||||||
|
|
||||||
find_best_pitch(xcorr, y_lp4, len>>2, max_pitch>>2, best_pitch
|
find_best_pitch(xcorr, y_lp4, len>>2, max_pitch>>2, best_pitch
|
||||||
#ifdef FIXED_POINT
|
#ifdef FIXED_POINT
|
||||||
, 0, maxcorr
|
, 0, maxcorr
|
||||||
|
@ -287,11 +406,13 @@ opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
|
||||||
int k, i, T, T0;
|
int k, i, T, T0;
|
||||||
opus_val16 g, g0;
|
opus_val16 g, g0;
|
||||||
opus_val16 pg;
|
opus_val16 pg;
|
||||||
opus_val32 xy,xx,yy;
|
opus_val32 xy,xx,yy,xy2;
|
||||||
opus_val32 xcorr[3];
|
opus_val32 xcorr[3];
|
||||||
opus_val32 best_xy, best_yy;
|
opus_val32 best_xy, best_yy;
|
||||||
int offset;
|
int offset;
|
||||||
int minperiod0;
|
int minperiod0;
|
||||||
|
VARDECL(opus_val32, yy_lookup);
|
||||||
|
SAVE_STACK;
|
||||||
|
|
||||||
minperiod0 = minperiod;
|
minperiod0 = minperiod;
|
||||||
maxperiod /= 2;
|
maxperiod /= 2;
|
||||||
|
@ -304,13 +425,16 @@ opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
|
||||||
*T0_=maxperiod-1;
|
*T0_=maxperiod-1;
|
||||||
|
|
||||||
T = T0 = *T0_;
|
T = T0 = *T0_;
|
||||||
xx=xy=yy=0;
|
ALLOC(yy_lookup, maxperiod+1, opus_val32);
|
||||||
for (i=0;i<N;i++)
|
dual_inner_prod(x, x, x-T0, N, &xx, &xy);
|
||||||
|
yy_lookup[0] = xx;
|
||||||
|
yy=xx;
|
||||||
|
for (i=1;i<=maxperiod;i++)
|
||||||
{
|
{
|
||||||
xy = MAC16_16(xy, x[i], x[i-T0]);
|
yy = yy+MULT16_16(x[-i],x[-i])-MULT16_16(x[N-i],x[N-i]);
|
||||||
xx = MAC16_16(xx, x[i], x[i]);
|
yy_lookup[i] = MAX32(0, yy);
|
||||||
yy = MAC16_16(yy, x[i-T0],x[i-T0]);
|
|
||||||
}
|
}
|
||||||
|
yy = yy_lookup[T0];
|
||||||
best_xy = xy;
|
best_xy = xy;
|
||||||
best_yy = yy;
|
best_yy = yy;
|
||||||
#ifdef FIXED_POINT
|
#ifdef FIXED_POINT
|
||||||
|
@ -331,6 +455,7 @@ opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
|
||||||
int T1, T1b;
|
int T1, T1b;
|
||||||
opus_val16 g1;
|
opus_val16 g1;
|
||||||
opus_val16 cont=0;
|
opus_val16 cont=0;
|
||||||
|
opus_val16 thresh;
|
||||||
T1 = (2*T0+k)/(2*k);
|
T1 = (2*T0+k)/(2*k);
|
||||||
if (T1 < minperiod)
|
if (T1 < minperiod)
|
||||||
break;
|
break;
|
||||||
|
@ -345,15 +470,9 @@ opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
|
||||||
{
|
{
|
||||||
T1b = (2*second_check[k]*T0+k)/(2*k);
|
T1b = (2*second_check[k]*T0+k)/(2*k);
|
||||||
}
|
}
|
||||||
xy=yy=0;
|
dual_inner_prod(x, &x[-T1], &x[-T1b], N, &xy, &xy2);
|
||||||
for (i=0;i<N;i++)
|
xy += xy2;
|
||||||
{
|
yy = yy_lookup[T1] + yy_lookup[T1b];
|
||||||
xy = MAC16_16(xy, x[i], x[i-T1]);
|
|
||||||
yy = MAC16_16(yy, x[i-T1], x[i-T1]);
|
|
||||||
|
|
||||||
xy = MAC16_16(xy, x[i], x[i-T1b]);
|
|
||||||
yy = MAC16_16(yy, x[i-T1b], x[i-T1b]);
|
|
||||||
}
|
|
||||||
#ifdef FIXED_POINT
|
#ifdef FIXED_POINT
|
||||||
{
|
{
|
||||||
opus_val32 x2y2;
|
opus_val32 x2y2;
|
||||||
|
@ -372,7 +491,14 @@ opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
|
||||||
cont = HALF32(prev_gain);
|
cont = HALF32(prev_gain);
|
||||||
else
|
else
|
||||||
cont = 0;
|
cont = 0;
|
||||||
if (g1 > QCONST16(.3f,15) + MULT16_16_Q15(QCONST16(.4f,15),g0)-cont)
|
thresh = MAX16(QCONST16(.3f,15), MULT16_16_Q15(QCONST16(.7f,15),g0)-cont);
|
||||||
|
/* Bias against very high pitch (very short period) to avoid false-positives
|
||||||
|
due to short-term correlation */
|
||||||
|
if (T1<3*minperiod)
|
||||||
|
thresh = MAX16(QCONST16(.4f,15), MULT16_16_Q15(QCONST16(.85f,15),g0)-cont);
|
||||||
|
else if (T1<2*minperiod)
|
||||||
|
thresh = MAX16(QCONST16(.5f,15), MULT16_16_Q15(QCONST16(.9f,15),g0)-cont);
|
||||||
|
if (g1 > thresh)
|
||||||
{
|
{
|
||||||
best_xy = xy;
|
best_xy = xy;
|
||||||
best_yy = yy;
|
best_yy = yy;
|
||||||
|
@ -406,5 +532,6 @@ opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
|
||||||
|
|
||||||
if (*T0_<minperiod0)
|
if (*T0_<minperiod0)
|
||||||
*T0_=minperiod0;
|
*T0_=minperiod0;
|
||||||
|
RESTORE_STACK;
|
||||||
return pg;
|
return pg;
|
||||||
}
|
}
|
173
code/opus-1.1/celt/pitch.h
Normal file
173
code/opus-1.1/celt/pitch.h
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
/* Copyright (c) 2007-2008 CSIRO
|
||||||
|
Copyright (c) 2007-2009 Xiph.Org Foundation
|
||||||
|
Written by Jean-Marc Valin */
|
||||||
|
/**
|
||||||
|
@file pitch.h
|
||||||
|
@brief Pitch analysis
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
- Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||||
|
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PITCH_H
|
||||||
|
#define PITCH_H
|
||||||
|
|
||||||
|
#include "modes.h"
|
||||||
|
#include "cpu_support.h"
|
||||||
|
|
||||||
|
#if defined(__SSE__) && !defined(FIXED_POINT)
|
||||||
|
#include "x86/pitch_sse.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(OPUS_ARM_ASM) && defined(FIXED_POINT)
|
||||||
|
# include "arm/pitch_arm.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x_lp,
|
||||||
|
int len, int C, int arch);
|
||||||
|
|
||||||
|
void pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTRICT y,
|
||||||
|
int len, int max_pitch, int *pitch, int arch);
|
||||||
|
|
||||||
|
opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
|
||||||
|
int N, int *T0, int prev_period, opus_val16 prev_gain);
|
||||||
|
|
||||||
|
/* OPT: This is the kernel you really want to optimize. It gets used a lot
|
||||||
|
by the prefilter and by the PLC. */
|
||||||
|
#ifndef OVERRIDE_XCORR_KERNEL
|
||||||
|
static OPUS_INLINE void xcorr_kernel(const opus_val16 * x, const opus_val16 * y, opus_val32 sum[4], int len)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
opus_val16 y_0, y_1, y_2, y_3;
|
||||||
|
celt_assert(len>=3);
|
||||||
|
y_3=0; /* gcc doesn't realize that y_3 can't be used uninitialized */
|
||||||
|
y_0=*y++;
|
||||||
|
y_1=*y++;
|
||||||
|
y_2=*y++;
|
||||||
|
for (j=0;j<len-3;j+=4)
|
||||||
|
{
|
||||||
|
opus_val16 tmp;
|
||||||
|
tmp = *x++;
|
||||||
|
y_3=*y++;
|
||||||
|
sum[0] = MAC16_16(sum[0],tmp,y_0);
|
||||||
|
sum[1] = MAC16_16(sum[1],tmp,y_1);
|
||||||
|
sum[2] = MAC16_16(sum[2],tmp,y_2);
|
||||||
|
sum[3] = MAC16_16(sum[3],tmp,y_3);
|
||||||
|
tmp=*x++;
|
||||||
|
y_0=*y++;
|
||||||
|
sum[0] = MAC16_16(sum[0],tmp,y_1);
|
||||||
|
sum[1] = MAC16_16(sum[1],tmp,y_2);
|
||||||
|
sum[2] = MAC16_16(sum[2],tmp,y_3);
|
||||||
|
sum[3] = MAC16_16(sum[3],tmp,y_0);
|
||||||
|
tmp=*x++;
|
||||||
|
y_1=*y++;
|
||||||
|
sum[0] = MAC16_16(sum[0],tmp,y_2);
|
||||||
|
sum[1] = MAC16_16(sum[1],tmp,y_3);
|
||||||
|
sum[2] = MAC16_16(sum[2],tmp,y_0);
|
||||||
|
sum[3] = MAC16_16(sum[3],tmp,y_1);
|
||||||
|
tmp=*x++;
|
||||||
|
y_2=*y++;
|
||||||
|
sum[0] = MAC16_16(sum[0],tmp,y_3);
|
||||||
|
sum[1] = MAC16_16(sum[1],tmp,y_0);
|
||||||
|
sum[2] = MAC16_16(sum[2],tmp,y_1);
|
||||||
|
sum[3] = MAC16_16(sum[3],tmp,y_2);
|
||||||
|
}
|
||||||
|
if (j++<len)
|
||||||
|
{
|
||||||
|
opus_val16 tmp = *x++;
|
||||||
|
y_3=*y++;
|
||||||
|
sum[0] = MAC16_16(sum[0],tmp,y_0);
|
||||||
|
sum[1] = MAC16_16(sum[1],tmp,y_1);
|
||||||
|
sum[2] = MAC16_16(sum[2],tmp,y_2);
|
||||||
|
sum[3] = MAC16_16(sum[3],tmp,y_3);
|
||||||
|
}
|
||||||
|
if (j++<len)
|
||||||
|
{
|
||||||
|
opus_val16 tmp=*x++;
|
||||||
|
y_0=*y++;
|
||||||
|
sum[0] = MAC16_16(sum[0],tmp,y_1);
|
||||||
|
sum[1] = MAC16_16(sum[1],tmp,y_2);
|
||||||
|
sum[2] = MAC16_16(sum[2],tmp,y_3);
|
||||||
|
sum[3] = MAC16_16(sum[3],tmp,y_0);
|
||||||
|
}
|
||||||
|
if (j<len)
|
||||||
|
{
|
||||||
|
opus_val16 tmp=*x++;
|
||||||
|
y_1=*y++;
|
||||||
|
sum[0] = MAC16_16(sum[0],tmp,y_2);
|
||||||
|
sum[1] = MAC16_16(sum[1],tmp,y_3);
|
||||||
|
sum[2] = MAC16_16(sum[2],tmp,y_0);
|
||||||
|
sum[3] = MAC16_16(sum[3],tmp,y_1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* OVERRIDE_XCORR_KERNEL */
|
||||||
|
|
||||||
|
#ifndef OVERRIDE_DUAL_INNER_PROD
|
||||||
|
static OPUS_INLINE void dual_inner_prod(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,
|
||||||
|
int N, opus_val32 *xy1, opus_val32 *xy2)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
opus_val32 xy01=0;
|
||||||
|
opus_val32 xy02=0;
|
||||||
|
for (i=0;i<N;i++)
|
||||||
|
{
|
||||||
|
xy01 = MAC16_16(xy01, x[i], y01[i]);
|
||||||
|
xy02 = MAC16_16(xy02, x[i], y02[i]);
|
||||||
|
}
|
||||||
|
*xy1 = xy01;
|
||||||
|
*xy2 = xy02;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef FIXED_POINT
|
||||||
|
opus_val32
|
||||||
|
#else
|
||||||
|
void
|
||||||
|
#endif
|
||||||
|
celt_pitch_xcorr_c(const opus_val16 *_x, const opus_val16 *_y,
|
||||||
|
opus_val32 *xcorr, int len, int max_pitch);
|
||||||
|
|
||||||
|
#if !defined(OVERRIDE_PITCH_XCORR)
|
||||||
|
/*Is run-time CPU detection enabled on this platform?*/
|
||||||
|
# if defined(OPUS_HAVE_RTCD)
|
||||||
|
extern
|
||||||
|
# if defined(FIXED_POINT)
|
||||||
|
opus_val32
|
||||||
|
# else
|
||||||
|
void
|
||||||
|
# endif
|
||||||
|
(*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
|
||||||
|
const opus_val16 *, opus_val32 *, int, int);
|
||||||
|
|
||||||
|
# define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
|
||||||
|
((*CELT_PITCH_XCORR_IMPL[(arch)&OPUS_ARCHMASK])(_x, _y, \
|
||||||
|
xcorr, len, max_pitch))
|
||||||
|
# else
|
||||||
|
# define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
|
||||||
|
((void)(arch),celt_pitch_xcorr_c(_x, _y, xcorr, len, max_pitch))
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -40,8 +40,8 @@
|
||||||
#include "rate.h"
|
#include "rate.h"
|
||||||
|
|
||||||
#ifdef FIXED_POINT
|
#ifdef FIXED_POINT
|
||||||
/* Mean energy in each band quantized in Q6 */
|
/* Mean energy in each band quantized in Q4 */
|
||||||
static const signed char eMeans[25] = {
|
const signed char eMeans[25] = {
|
||||||
103,100, 92, 85, 81,
|
103,100, 92, 85, 81,
|
||||||
77, 72, 70, 78, 75,
|
77, 72, 70, 78, 75,
|
||||||
73, 71, 78, 74, 69,
|
73, 71, 78, 74, 69,
|
||||||
|
@ -49,8 +49,8 @@ static const signed char eMeans[25] = {
|
||||||
60, 60, 60, 60, 60
|
60, 60, 60, 60, 60
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
/* Mean energy in each band quantized in Q6 and converted back to float */
|
/* Mean energy in each band quantized in Q4 and converted back to float */
|
||||||
static const opus_val16 eMeans[25] = {
|
const opus_val16 eMeans[25] = {
|
||||||
6.437500f, 6.250000f, 5.750000f, 5.312500f, 5.062500f,
|
6.437500f, 6.250000f, 5.750000f, 5.312500f, 5.062500f,
|
||||||
4.812500f, 4.500000f, 4.375000f, 4.875000f, 4.687500f,
|
4.812500f, 4.500000f, 4.375000f, 4.875000f, 4.687500f,
|
||||||
4.562500f, 4.437500f, 4.875000f, 4.625000f, 4.312500f,
|
4.562500f, 4.437500f, 4.875000f, 4.625000f, 4.312500f,
|
||||||
|
@ -157,7 +157,7 @@ static int quant_coarse_energy_impl(const CELTMode *m, int start, int end,
|
||||||
const opus_val16 *eBands, opus_val16 *oldEBands,
|
const opus_val16 *eBands, opus_val16 *oldEBands,
|
||||||
opus_int32 budget, opus_int32 tell,
|
opus_int32 budget, opus_int32 tell,
|
||||||
const unsigned char *prob_model, opus_val16 *error, ec_enc *enc,
|
const unsigned char *prob_model, opus_val16 *error, ec_enc *enc,
|
||||||
int C, int LM, int intra, opus_val16 max_decay)
|
int C, int LM, int intra, opus_val16 max_decay, int lfe)
|
||||||
{
|
{
|
||||||
int i, c;
|
int i, c;
|
||||||
int badness = 0;
|
int badness = 0;
|
||||||
|
@ -222,6 +222,8 @@ static int quant_coarse_energy_impl(const CELTMode *m, int start, int end,
|
||||||
if (bits_left < 16)
|
if (bits_left < 16)
|
||||||
qi = IMAX(-1, qi);
|
qi = IMAX(-1, qi);
|
||||||
}
|
}
|
||||||
|
if (lfe && i>=2)
|
||||||
|
qi = IMIN(qi, 0);
|
||||||
if (budget-tell >= 15)
|
if (budget-tell >= 15)
|
||||||
{
|
{
|
||||||
int pi;
|
int pi;
|
||||||
|
@ -253,13 +255,13 @@ static int quant_coarse_energy_impl(const CELTMode *m, int start, int end,
|
||||||
prev[c] = prev[c] + SHL32(q,7) - MULT16_16(beta,PSHR32(q,8));
|
prev[c] = prev[c] + SHL32(q,7) - MULT16_16(beta,PSHR32(q,8));
|
||||||
} while (++c < C);
|
} while (++c < C);
|
||||||
}
|
}
|
||||||
return badness;
|
return lfe ? 0 : badness;
|
||||||
}
|
}
|
||||||
|
|
||||||
void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
|
void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
|
||||||
const opus_val16 *eBands, opus_val16 *oldEBands, opus_uint32 budget,
|
const opus_val16 *eBands, opus_val16 *oldEBands, opus_uint32 budget,
|
||||||
opus_val16 *error, ec_enc *enc, int C, int LM, int nbAvailableBytes,
|
opus_val16 *error, ec_enc *enc, int C, int LM, int nbAvailableBytes,
|
||||||
int force_intra, opus_val32 *delayedIntra, int two_pass, int loss_rate)
|
int force_intra, opus_val32 *delayedIntra, int two_pass, int loss_rate, int lfe)
|
||||||
{
|
{
|
||||||
int intra;
|
int intra;
|
||||||
opus_val16 max_decay;
|
opus_val16 max_decay;
|
||||||
|
@ -280,9 +282,6 @@ void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
|
||||||
if (tell+3 > budget)
|
if (tell+3 > budget)
|
||||||
two_pass = intra = 0;
|
two_pass = intra = 0;
|
||||||
|
|
||||||
/* Encode the global flags using a simple probability model
|
|
||||||
(first symbols in the stream) */
|
|
||||||
|
|
||||||
max_decay = QCONST16(16.f,DB_SHIFT);
|
max_decay = QCONST16(16.f,DB_SHIFT);
|
||||||
if (end-start>10)
|
if (end-start>10)
|
||||||
{
|
{
|
||||||
|
@ -292,6 +291,8 @@ void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
|
||||||
max_decay = MIN32(max_decay, .125f*nbAvailableBytes);
|
max_decay = MIN32(max_decay, .125f*nbAvailableBytes);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
if (lfe)
|
||||||
|
max_decay=3;
|
||||||
enc_start_state = *enc;
|
enc_start_state = *enc;
|
||||||
|
|
||||||
ALLOC(oldEBands_intra, C*m->nbEBands, opus_val16);
|
ALLOC(oldEBands_intra, C*m->nbEBands, opus_val16);
|
||||||
|
@ -301,7 +302,7 @@ void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
|
||||||
if (two_pass || intra)
|
if (two_pass || intra)
|
||||||
{
|
{
|
||||||
badness1 = quant_coarse_energy_impl(m, start, end, eBands, oldEBands_intra, budget,
|
badness1 = quant_coarse_energy_impl(m, start, end, eBands, oldEBands_intra, budget,
|
||||||
tell, e_prob_model[LM][1], error_intra, enc, C, LM, 1, max_decay);
|
tell, e_prob_model[LM][1], error_intra, enc, C, LM, 1, max_decay, lfe);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!intra)
|
if (!intra)
|
||||||
|
@ -311,6 +312,7 @@ void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
|
||||||
opus_int32 tell_intra;
|
opus_int32 tell_intra;
|
||||||
opus_uint32 nstart_bytes;
|
opus_uint32 nstart_bytes;
|
||||||
opus_uint32 nintra_bytes;
|
opus_uint32 nintra_bytes;
|
||||||
|
opus_uint32 save_bytes;
|
||||||
int badness2;
|
int badness2;
|
||||||
VARDECL(unsigned char, intra_bits);
|
VARDECL(unsigned char, intra_bits);
|
||||||
|
|
||||||
|
@ -321,14 +323,17 @@ void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
|
||||||
nstart_bytes = ec_range_bytes(&enc_start_state);
|
nstart_bytes = ec_range_bytes(&enc_start_state);
|
||||||
nintra_bytes = ec_range_bytes(&enc_intra_state);
|
nintra_bytes = ec_range_bytes(&enc_intra_state);
|
||||||
intra_buf = ec_get_buffer(&enc_intra_state) + nstart_bytes;
|
intra_buf = ec_get_buffer(&enc_intra_state) + nstart_bytes;
|
||||||
ALLOC(intra_bits, nintra_bytes-nstart_bytes, unsigned char);
|
save_bytes = nintra_bytes-nstart_bytes;
|
||||||
|
if (save_bytes == 0)
|
||||||
|
save_bytes = ALLOC_NONE;
|
||||||
|
ALLOC(intra_bits, save_bytes, unsigned char);
|
||||||
/* Copy bits from intra bit-stream */
|
/* Copy bits from intra bit-stream */
|
||||||
OPUS_COPY(intra_bits, intra_buf, nintra_bytes - nstart_bytes);
|
OPUS_COPY(intra_bits, intra_buf, nintra_bytes - nstart_bytes);
|
||||||
|
|
||||||
*enc = enc_start_state;
|
*enc = enc_start_state;
|
||||||
|
|
||||||
badness2 = quant_coarse_energy_impl(m, start, end, eBands, oldEBands, budget,
|
badness2 = quant_coarse_energy_impl(m, start, end, eBands, oldEBands, budget,
|
||||||
tell, e_prob_model[LM][intra], error, enc, C, LM, 0, max_decay);
|
tell, e_prob_model[LM][intra], error, enc, C, LM, 0, max_decay, lfe);
|
||||||
|
|
||||||
if (two_pass && (badness1 < badness2 || (badness1 == badness2 && ((opus_int32)ec_tell_frac(enc))+intra_bias > tell_intra)))
|
if (two_pass && (badness1 < badness2 || (badness1 == badness2 && ((opus_int32)ec_tell_frac(enc))+intra_bias > tell_intra)))
|
||||||
{
|
{
|
||||||
|
@ -535,25 +540,6 @@ void unquant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void log2Amp(const CELTMode *m, int start, int end,
|
|
||||||
celt_ener *eBands, const opus_val16 *oldEBands, int C)
|
|
||||||
{
|
|
||||||
int c, i;
|
|
||||||
c=0;
|
|
||||||
do {
|
|
||||||
for (i=0;i<start;i++)
|
|
||||||
eBands[i+c*m->nbEBands] = 0;
|
|
||||||
for (;i<end;i++)
|
|
||||||
{
|
|
||||||
opus_val16 lg = ADD16(oldEBands[i+c*m->nbEBands],
|
|
||||||
SHL16((opus_val16)eMeans[i],6));
|
|
||||||
eBands[i+c*m->nbEBands] = PSHR32(celt_exp2(lg),4);
|
|
||||||
}
|
|
||||||
for (;i<m->nbEBands;i++)
|
|
||||||
eBands[i+c*m->nbEBands] = 0;
|
|
||||||
} while (++c < C);
|
|
||||||
}
|
|
||||||
|
|
||||||
void amp2Log2(const CELTMode *m, int effEnd, int end,
|
void amp2Log2(const CELTMode *m, int effEnd, int end,
|
||||||
celt_ener *bandE, opus_val16 *bandLogE, int C)
|
celt_ener *bandE, opus_val16 *bandLogE, int C)
|
||||||
{
|
{
|
|
@ -35,6 +35,12 @@
|
||||||
#include "entdec.h"
|
#include "entdec.h"
|
||||||
#include "mathops.h"
|
#include "mathops.h"
|
||||||
|
|
||||||
|
#ifdef FIXED_POINT
|
||||||
|
extern const signed char eMeans[25];
|
||||||
|
#else
|
||||||
|
extern const opus_val16 eMeans[25];
|
||||||
|
#endif
|
||||||
|
|
||||||
void amp2Log2(const CELTMode *m, int effEnd, int end,
|
void amp2Log2(const CELTMode *m, int effEnd, int end,
|
||||||
celt_ener *bandE, opus_val16 *bandLogE, int C);
|
celt_ener *bandE, opus_val16 *bandLogE, int C);
|
||||||
|
|
||||||
|
@ -45,7 +51,7 @@ void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
|
||||||
const opus_val16 *eBands, opus_val16 *oldEBands, opus_uint32 budget,
|
const opus_val16 *eBands, opus_val16 *oldEBands, opus_uint32 budget,
|
||||||
opus_val16 *error, ec_enc *enc, int C, int LM,
|
opus_val16 *error, ec_enc *enc, int C, int LM,
|
||||||
int nbAvailableBytes, int force_intra, opus_val32 *delayedIntra,
|
int nbAvailableBytes, int force_intra, opus_val32 *delayedIntra,
|
||||||
int two_pass, int loss_rate);
|
int two_pass, int loss_rate, int lfe);
|
||||||
|
|
||||||
void quant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, ec_enc *enc, int C);
|
void quant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, ec_enc *enc, int C);
|
||||||
|
|
|
@ -245,10 +245,10 @@ void compute_pulse_cache(CELTMode *m, int LM)
|
||||||
|
|
||||||
#define ALLOC_STEPS 6
|
#define ALLOC_STEPS 6
|
||||||
|
|
||||||
static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int skip_start,
|
static OPUS_INLINE int interp_bits2pulses(const CELTMode *m, int start, int end, int skip_start,
|
||||||
const int *bits1, const int *bits2, const int *thresh, const int *cap, opus_int32 total, opus_int32 *_balance,
|
const int *bits1, const int *bits2, const int *thresh, const int *cap, opus_int32 total, opus_int32 *_balance,
|
||||||
int skip_rsv, int *intensity, int intensity_rsv, int *dual_stereo, int dual_stereo_rsv, int *bits,
|
int skip_rsv, int *intensity, int intensity_rsv, int *dual_stereo, int dual_stereo_rsv, int *bits,
|
||||||
int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev)
|
int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev, int signalBandwidth)
|
||||||
{
|
{
|
||||||
opus_int32 psum;
|
opus_int32 psum;
|
||||||
int lo, hi;
|
int lo, hi;
|
||||||
|
@ -353,7 +353,7 @@ static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int
|
||||||
#ifdef FUZZING
|
#ifdef FUZZING
|
||||||
if ((rand()&0x1) == 0)
|
if ((rand()&0x1) == 0)
|
||||||
#else
|
#else
|
||||||
if (codedBands<=start+2 || band_bits > ((j<prev?7:9)*band_width<<LM<<BITRES)>>4)
|
if (codedBands<=start+2 || (band_bits > ((j<prev?7:9)*band_width<<LM<<BITRES)>>4 && j<=signalBandwidth))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
ec_enc_bit_logp(ec, 1, 1);
|
ec_enc_bit_logp(ec, 1, 1);
|
||||||
|
@ -524,7 +524,7 @@ static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int
|
||||||
}
|
}
|
||||||
|
|
||||||
int compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stereo,
|
int compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stereo,
|
||||||
opus_int32 total, opus_int32 *balance, int *pulses, int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev)
|
opus_int32 total, opus_int32 *balance, int *pulses, int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev, int signalBandwidth)
|
||||||
{
|
{
|
||||||
int lo, hi, len, j;
|
int lo, hi, len, j;
|
||||||
int codedBands;
|
int codedBands;
|
||||||
|
@ -631,7 +631,7 @@ int compute_allocation(const CELTMode *m, int start, int end, const int *offsets
|
||||||
}
|
}
|
||||||
codedBands = interp_bits2pulses(m, start, end, skip_start, bits1, bits2, thresh, cap,
|
codedBands = interp_bits2pulses(m, start, end, skip_start, bits1, bits2, thresh, cap,
|
||||||
total, balance, skip_rsv, intensity, intensity_rsv, dual_stereo, dual_stereo_rsv,
|
total, balance, skip_rsv, intensity, intensity_rsv, dual_stereo, dual_stereo_rsv,
|
||||||
pulses, ebits, fine_priority, C, LM, ec, encode, prev);
|
pulses, ebits, fine_priority, C, LM, ec, encode, prev, signalBandwidth);
|
||||||
RESTORE_STACK;
|
RESTORE_STACK;
|
||||||
return codedBands;
|
return codedBands;
|
||||||
}
|
}
|
|
@ -45,12 +45,12 @@
|
||||||
|
|
||||||
void compute_pulse_cache(CELTMode *m, int LM);
|
void compute_pulse_cache(CELTMode *m, int LM);
|
||||||
|
|
||||||
static inline int get_pulses(int i)
|
static OPUS_INLINE int get_pulses(int i)
|
||||||
{
|
{
|
||||||
return i<8 ? i : (8 + (i&7)) << ((i>>3)-1);
|
return i<8 ? i : (8 + (i&7)) << ((i>>3)-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int bits2pulses(const CELTMode *m, int band, int LM, int bits)
|
static OPUS_INLINE int bits2pulses(const CELTMode *m, int band, int LM, int bits)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int lo, hi;
|
int lo, hi;
|
||||||
|
@ -77,7 +77,7 @@ static inline int bits2pulses(const CELTMode *m, int band, int LM, int bits)
|
||||||
return hi;
|
return hi;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int pulses2bits(const CELTMode *m, int band, int LM, int pulses)
|
static OPUS_INLINE int pulses2bits(const CELTMode *m, int band, int LM, int pulses)
|
||||||
{
|
{
|
||||||
const unsigned char *cache;
|
const unsigned char *cache;
|
||||||
|
|
||||||
|
@ -96,6 +96,6 @@ static inline int pulses2bits(const CELTMode *m, int band, int LM, int pulses)
|
||||||
@return Total number of bits allocated
|
@return Total number of bits allocated
|
||||||
*/
|
*/
|
||||||
int compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stero,
|
int compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stero,
|
||||||
opus_int32 total, opus_int32 *balance, int *pulses, int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev);
|
opus_int32 total, opus_int32 *balance, int *pulses, int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev, int signalBandwidth);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -32,6 +32,9 @@
|
||||||
#ifndef STACK_ALLOC_H
|
#ifndef STACK_ALLOC_H
|
||||||
#define STACK_ALLOC_H
|
#define STACK_ALLOC_H
|
||||||
|
|
||||||
|
#include "opus_types.h"
|
||||||
|
#include "opus_defines.h"
|
||||||
|
|
||||||
#if (!defined (VAR_ARRAYS) && !defined (USE_ALLOCA) && !defined (NONTHREADSAFE_PSEUDOSTACK))
|
#if (!defined (VAR_ARRAYS) && !defined (USE_ALLOCA) && !defined (NONTHREADSAFE_PSEUDOSTACK))
|
||||||
#error "Opus requires one of VAR_ARRAYS, USE_ALLOCA, or NONTHREADSAFE_PSEUDOSTACK be defined to select the temporary allocation mode."
|
#error "Opus requires one of VAR_ARRAYS, USE_ALLOCA, or NONTHREADSAFE_PSEUDOSTACK be defined to select the temporary allocation mode."
|
||||||
#endif
|
#endif
|
||||||
|
@ -92,6 +95,8 @@
|
||||||
#define SAVE_STACK
|
#define SAVE_STACK
|
||||||
#define RESTORE_STACK
|
#define RESTORE_STACK
|
||||||
#define ALLOC_STACK
|
#define ALLOC_STACK
|
||||||
|
/* C99 does not allow VLAs of size zero */
|
||||||
|
#define ALLOC_NONE 1
|
||||||
|
|
||||||
#elif defined(USE_ALLOCA)
|
#elif defined(USE_ALLOCA)
|
||||||
|
|
||||||
|
@ -106,6 +111,7 @@
|
||||||
#define SAVE_STACK
|
#define SAVE_STACK
|
||||||
#define RESTORE_STACK
|
#define RESTORE_STACK
|
||||||
#define ALLOC_STACK
|
#define ALLOC_STACK
|
||||||
|
#define ALLOC_NONE 0
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
@ -143,7 +149,30 @@ extern char *global_stack_top;
|
||||||
#define VARDECL(type, var) type *var
|
#define VARDECL(type, var) type *var
|
||||||
#define ALLOC(var, size, type) var = PUSH(global_stack, size, type)
|
#define ALLOC(var, size, type) var = PUSH(global_stack, size, type)
|
||||||
#define SAVE_STACK char *_saved_stack = global_stack;
|
#define SAVE_STACK char *_saved_stack = global_stack;
|
||||||
|
#define ALLOC_NONE 0
|
||||||
|
|
||||||
#endif /* VAR_ARRAYS */
|
#endif /* VAR_ARRAYS */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef ENABLE_VALGRIND
|
||||||
|
|
||||||
|
#include <valgrind/memcheck.h>
|
||||||
|
#define OPUS_CHECK_ARRAY(ptr, len) VALGRIND_CHECK_MEM_IS_DEFINED(ptr, len*sizeof(*ptr))
|
||||||
|
#define OPUS_CHECK_VALUE(value) VALGRIND_CHECK_VALUE_IS_DEFINED(value)
|
||||||
|
#define OPUS_CHECK_ARRAY_COND(ptr, len) VALGRIND_CHECK_MEM_IS_DEFINED(ptr, len*sizeof(*ptr))
|
||||||
|
#define OPUS_CHECK_VALUE_COND(value) VALGRIND_CHECK_VALUE_IS_DEFINED(value)
|
||||||
|
#define OPUS_PRINT_INT(value) do {fprintf(stderr, #value " = %d at %s:%d\n", value, __FILE__, __LINE__);}while(0)
|
||||||
|
#define OPUS_FPRINTF fprintf
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static OPUS_INLINE int _opus_false(void) {return 0;}
|
||||||
|
#define OPUS_CHECK_ARRAY(ptr, len) _opus_false()
|
||||||
|
#define OPUS_CHECK_VALUE(value) _opus_false()
|
||||||
|
#define OPUS_PRINT_INT(value) do{}while(0)
|
||||||
|
#define OPUS_FPRINTF (void)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif /* STACK_ALLOC_H */
|
#endif /* STACK_ALLOC_H */
|
|
@ -40,11 +40,9 @@
|
||||||
/** Algebraic pulse-vector quantiser. The signal x is replaced by the sum of
|
/** Algebraic pulse-vector quantiser. The signal x is replaced by the sum of
|
||||||
* the pitch and a combination of pulses such that its norm is still equal
|
* the pitch and a combination of pulses such that its norm is still equal
|
||||||
* to 1. This is the function that will typically require the most CPU.
|
* to 1. This is the function that will typically require the most CPU.
|
||||||
* @param x Residual signal to quantise/encode (returns quantised version)
|
* @param X Residual signal to quantise/encode (returns quantised version)
|
||||||
* @param W Perceptual weight to use when optimising (currently unused)
|
|
||||||
* @param N Number of samples to encode
|
* @param N Number of samples to encode
|
||||||
* @param K Number of pulses to use
|
* @param K Number of pulses to use
|
||||||
* @param p Pitch vector (it is assumed that p+x is a unit vector)
|
|
||||||
* @param enc Entropy encoder state
|
* @param enc Entropy encoder state
|
||||||
* @ret A mask indicating which blocks in the band received pulses
|
* @ret A mask indicating which blocks in the band received pulses
|
||||||
*/
|
*/
|
||||||
|
@ -56,10 +54,9 @@ unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B,
|
||||||
);
|
);
|
||||||
|
|
||||||
/** Algebraic pulse decoder
|
/** Algebraic pulse decoder
|
||||||
* @param x Decoded normalised spectrum (returned)
|
* @param X Decoded normalised spectrum (returned)
|
||||||
* @param N Number of samples to decode
|
* @param N Number of samples to decode
|
||||||
* @param K Number of pulses to use
|
* @param K Number of pulses to use
|
||||||
* @param p Pitch vector (automatically added to x)
|
|
||||||
* @param dec Entropy decoder state
|
* @param dec Entropy decoder state
|
||||||
* @ret A mask indicating which blocks in the band received pulses
|
* @ret A mask indicating which blocks in the band received pulses
|
||||||
*/
|
*/
|
156
code/opus-1.1/celt/x86/pitch_sse.h
Normal file
156
code/opus-1.1/celt/x86/pitch_sse.h
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
/* Copyright (c) 2013 Jean-Marc Valin and John Ridges */
|
||||||
|
/**
|
||||||
|
@file pitch_sse.h
|
||||||
|
@brief Pitch analysis
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
- Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||||
|
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PITCH_SSE_H
|
||||||
|
#define PITCH_SSE_H
|
||||||
|
|
||||||
|
#include <xmmintrin.h>
|
||||||
|
#include "arch.h"
|
||||||
|
|
||||||
|
#define OVERRIDE_XCORR_KERNEL
|
||||||
|
static OPUS_INLINE void xcorr_kernel(const opus_val16 *x, const opus_val16 *y, opus_val32 sum[4], int len)
|
||||||
|
{
|
||||||
|
int j;
|
||||||
|
__m128 xsum1, xsum2;
|
||||||
|
xsum1 = _mm_loadu_ps(sum);
|
||||||
|
xsum2 = _mm_setzero_ps();
|
||||||
|
|
||||||
|
for (j = 0; j < len-3; j += 4)
|
||||||
|
{
|
||||||
|
__m128 x0 = _mm_loadu_ps(x+j);
|
||||||
|
__m128 yj = _mm_loadu_ps(y+j);
|
||||||
|
__m128 y3 = _mm_loadu_ps(y+j+3);
|
||||||
|
|
||||||
|
xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(_mm_shuffle_ps(x0,x0,0x00),yj));
|
||||||
|
xsum2 = _mm_add_ps(xsum2,_mm_mul_ps(_mm_shuffle_ps(x0,x0,0x55),
|
||||||
|
_mm_shuffle_ps(yj,y3,0x49)));
|
||||||
|
xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(_mm_shuffle_ps(x0,x0,0xaa),
|
||||||
|
_mm_shuffle_ps(yj,y3,0x9e)));
|
||||||
|
xsum2 = _mm_add_ps(xsum2,_mm_mul_ps(_mm_shuffle_ps(x0,x0,0xff),y3));
|
||||||
|
}
|
||||||
|
if (j < len)
|
||||||
|
{
|
||||||
|
xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(_mm_load1_ps(x+j),_mm_loadu_ps(y+j)));
|
||||||
|
if (++j < len)
|
||||||
|
{
|
||||||
|
xsum2 = _mm_add_ps(xsum2,_mm_mul_ps(_mm_load1_ps(x+j),_mm_loadu_ps(y+j)));
|
||||||
|
if (++j < len)
|
||||||
|
{
|
||||||
|
xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(_mm_load1_ps(x+j),_mm_loadu_ps(y+j)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_mm_storeu_ps(sum,_mm_add_ps(xsum1,xsum2));
|
||||||
|
}
|
||||||
|
|
||||||
|
#define OVERRIDE_DUAL_INNER_PROD
|
||||||
|
static OPUS_INLINE void dual_inner_prod(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,
|
||||||
|
int N, opus_val32 *xy1, opus_val32 *xy2)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
__m128 xsum1, xsum2;
|
||||||
|
xsum1 = _mm_setzero_ps();
|
||||||
|
xsum2 = _mm_setzero_ps();
|
||||||
|
for (i=0;i<N-3;i+=4)
|
||||||
|
{
|
||||||
|
__m128 xi = _mm_loadu_ps(x+i);
|
||||||
|
__m128 y1i = _mm_loadu_ps(y01+i);
|
||||||
|
__m128 y2i = _mm_loadu_ps(y02+i);
|
||||||
|
xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(xi, y1i));
|
||||||
|
xsum2 = _mm_add_ps(xsum2,_mm_mul_ps(xi, y2i));
|
||||||
|
}
|
||||||
|
/* Horizontal sum */
|
||||||
|
xsum1 = _mm_add_ps(xsum1, _mm_movehl_ps(xsum1, xsum1));
|
||||||
|
xsum1 = _mm_add_ss(xsum1, _mm_shuffle_ps(xsum1, xsum1, 0x55));
|
||||||
|
_mm_store_ss(xy1, xsum1);
|
||||||
|
xsum2 = _mm_add_ps(xsum2, _mm_movehl_ps(xsum2, xsum2));
|
||||||
|
xsum2 = _mm_add_ss(xsum2, _mm_shuffle_ps(xsum2, xsum2, 0x55));
|
||||||
|
_mm_store_ss(xy2, xsum2);
|
||||||
|
for (;i<N;i++)
|
||||||
|
{
|
||||||
|
*xy1 = MAC16_16(*xy1, x[i], y01[i]);
|
||||||
|
*xy2 = MAC16_16(*xy2, x[i], y02[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define OVERRIDE_COMB_FILTER_CONST
|
||||||
|
static OPUS_INLINE void comb_filter_const(opus_val32 *y, opus_val32 *x, int T, int N,
|
||||||
|
opus_val16 g10, opus_val16 g11, opus_val16 g12)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
__m128 x0v;
|
||||||
|
__m128 g10v, g11v, g12v;
|
||||||
|
g10v = _mm_load1_ps(&g10);
|
||||||
|
g11v = _mm_load1_ps(&g11);
|
||||||
|
g12v = _mm_load1_ps(&g12);
|
||||||
|
x0v = _mm_loadu_ps(&x[-T-2]);
|
||||||
|
for (i=0;i<N-3;i+=4)
|
||||||
|
{
|
||||||
|
__m128 yi, yi2, x1v, x2v, x3v, x4v;
|
||||||
|
const opus_val32 *xp = &x[i-T-2];
|
||||||
|
yi = _mm_loadu_ps(x+i);
|
||||||
|
x4v = _mm_loadu_ps(xp+4);
|
||||||
|
#if 0
|
||||||
|
/* Slower version with all loads */
|
||||||
|
x1v = _mm_loadu_ps(xp+1);
|
||||||
|
x2v = _mm_loadu_ps(xp+2);
|
||||||
|
x3v = _mm_loadu_ps(xp+3);
|
||||||
|
#else
|
||||||
|
x2v = _mm_shuffle_ps(x0v, x4v, 0x4e);
|
||||||
|
x1v = _mm_shuffle_ps(x0v, x2v, 0x99);
|
||||||
|
x3v = _mm_shuffle_ps(x2v, x4v, 0x99);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
yi = _mm_add_ps(yi, _mm_mul_ps(g10v,x2v));
|
||||||
|
#if 0 /* Set to 1 to make it bit-exact with the non-SSE version */
|
||||||
|
yi = _mm_add_ps(yi, _mm_mul_ps(g11v,_mm_add_ps(x3v,x1v)));
|
||||||
|
yi = _mm_add_ps(yi, _mm_mul_ps(g12v,_mm_add_ps(x4v,x0v)));
|
||||||
|
#else
|
||||||
|
/* Use partial sums */
|
||||||
|
yi2 = _mm_add_ps(_mm_mul_ps(g11v,_mm_add_ps(x3v,x1v)),
|
||||||
|
_mm_mul_ps(g12v,_mm_add_ps(x4v,x0v)));
|
||||||
|
yi = _mm_add_ps(yi, yi2);
|
||||||
|
#endif
|
||||||
|
x0v=x4v;
|
||||||
|
_mm_storeu_ps(y+i, yi);
|
||||||
|
}
|
||||||
|
#ifdef CUSTOM_MODES
|
||||||
|
for (;i<N;i++)
|
||||||
|
{
|
||||||
|
y[i] = x[i]
|
||||||
|
+ MULT16_32_Q15(g10,x[i-T])
|
||||||
|
+ MULT16_32_Q15(g11,ADD32(x[i-T+1],x[i-T-1]))
|
||||||
|
+ MULT16_32_Q15(g12,ADD32(x[i-T+2],x[i-T-2]));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -520,7 +520,7 @@ OPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st);
|
||||||
* @param [in] len <tt>opus_int32</tt>: size of data
|
* @param [in] len <tt>opus_int32</tt>: size of data
|
||||||
* @param [out] out_toc <tt>char*</tt>: TOC pointer
|
* @param [out] out_toc <tt>char*</tt>: TOC pointer
|
||||||
* @param [out] frames <tt>char*[48]</tt> encapsulated frames
|
* @param [out] frames <tt>char*[48]</tt> encapsulated frames
|
||||||
* @param [out] size <tt>short[48]</tt> sizes of the encapsulated frames
|
* @param [out] size <tt>opus_int16[48]</tt> sizes of the encapsulated frames
|
||||||
* @param [out] payload_offset <tt>int*</tt>: returns the position of the payload within the packet (in bytes)
|
* @param [out] payload_offset <tt>int*</tt>: returns the position of the payload within the packet (in bytes)
|
||||||
* @returns number of frames
|
* @returns number of frames
|
||||||
*/
|
*/
|
||||||
|
@ -529,7 +529,7 @@ OPUS_EXPORT int opus_packet_parse(
|
||||||
opus_int32 len,
|
opus_int32 len,
|
||||||
unsigned char *out_toc,
|
unsigned char *out_toc,
|
||||||
const unsigned char *frames[48],
|
const unsigned char *frames[48],
|
||||||
short size[48],
|
opus_int16 size[48],
|
||||||
int *payload_offset
|
int *payload_offset
|
||||||
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
|
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
|
||||||
|
|
||||||
|
@ -566,6 +566,7 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_channels(const unsign
|
||||||
* @param [in] packet <tt>char*</tt>: Opus packet
|
* @param [in] packet <tt>char*</tt>: Opus packet
|
||||||
* @param [in] len <tt>opus_int32</tt>: Length of packet
|
* @param [in] len <tt>opus_int32</tt>: Length of packet
|
||||||
* @returns Number of frames
|
* @returns Number of frames
|
||||||
|
* @retval OPUS_BAD_ARG Insufficient data was passed to the function
|
||||||
* @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
|
* @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
|
||||||
*/
|
*/
|
||||||
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1);
|
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1);
|
||||||
|
@ -577,6 +578,7 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_frames(const unsigned
|
||||||
* This must be a multiple of 400, or
|
* This must be a multiple of 400, or
|
||||||
* inaccurate results will be returned.
|
* inaccurate results will be returned.
|
||||||
* @returns Number of samples
|
* @returns Number of samples
|
||||||
|
* @retval OPUS_BAD_ARG Insufficient data was passed to the function
|
||||||
* @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
|
* @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
|
||||||
*/
|
*/
|
||||||
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len, opus_int32 Fs) OPUS_ARG_NONNULL(1);
|
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len, opus_int32 Fs) OPUS_ARG_NONNULL(1);
|
||||||
|
@ -586,9 +588,24 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_samples(const unsigne
|
||||||
* @param [in] packet <tt>char*</tt>: Opus packet
|
* @param [in] packet <tt>char*</tt>: Opus packet
|
||||||
* @param [in] len <tt>opus_int32</tt>: Length of packet
|
* @param [in] len <tt>opus_int32</tt>: Length of packet
|
||||||
* @returns Number of samples
|
* @returns Number of samples
|
||||||
|
* @retval OPUS_BAD_ARG Insufficient data was passed to the function
|
||||||
* @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
|
* @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type
|
||||||
*/
|
*/
|
||||||
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_nb_samples(const OpusDecoder *dec, const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);
|
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_nb_samples(const OpusDecoder *dec, const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);
|
||||||
|
|
||||||
|
/** Applies soft-clipping to bring a float signal within the [-1,1] range. If
|
||||||
|
* the signal is already in that range, nothing is done. If there are values
|
||||||
|
* outside of [-1,1], then the signal is clipped as smoothly as possible to
|
||||||
|
* both fit in the range and avoid creating excessive distortion in the
|
||||||
|
* process.
|
||||||
|
* @param [in,out] pcm <tt>float*</tt>: Input PCM and modified PCM
|
||||||
|
* @param [in] frame_size <tt>int</tt> Number of samples per channel to process
|
||||||
|
* @param [in] channels <tt>int</tt>: Number of channels
|
||||||
|
* @param [in,out] softclip_mem <tt>float*</tt>: State memory for the soft clipping process (one float per channel, initialized to zero)
|
||||||
|
*/
|
||||||
|
OPUS_EXPORT void opus_pcm_soft_clip(float *pcm, int frame_size, int channels, float *softclip_mem);
|
||||||
|
|
||||||
|
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
||||||
/** @defgroup opus_repacketizer Repacketizer
|
/** @defgroup opus_repacketizer Repacketizer
|
||||||
|
@ -894,6 +911,64 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_nb_frames(OpusRepa
|
||||||
*/
|
*/
|
||||||
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1);
|
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1);
|
||||||
|
|
||||||
|
/** Pads a given Opus packet to a larger size (possibly changing the TOC sequence).
|
||||||
|
* @param[in,out] data <tt>const unsigned char*</tt>: The buffer containing the
|
||||||
|
* packet to pad.
|
||||||
|
* @param len <tt>opus_int32</tt>: The size of the packet.
|
||||||
|
* This must be at least 1.
|
||||||
|
* @param new_len <tt>opus_int32</tt>: The desired size of the packet after padding.
|
||||||
|
* This must be at least as large as len.
|
||||||
|
* @returns an error code
|
||||||
|
* @retval #OPUS_OK \a on success.
|
||||||
|
* @retval #OPUS_BAD_ARG \a len was less than 1 or new_len was less than len.
|
||||||
|
* @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet.
|
||||||
|
*/
|
||||||
|
OPUS_EXPORT int opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len);
|
||||||
|
|
||||||
|
/** Remove all padding from a given Opus packet and rewrite the TOC sequence to
|
||||||
|
* minimize space usage.
|
||||||
|
* @param[in,out] data <tt>const unsigned char*</tt>: The buffer containing the
|
||||||
|
* packet to strip.
|
||||||
|
* @param len <tt>opus_int32</tt>: The size of the packet.
|
||||||
|
* This must be at least 1.
|
||||||
|
* @returns The new size of the output packet on success, or an error code
|
||||||
|
* on failure.
|
||||||
|
* @retval #OPUS_BAD_ARG \a len was less than 1.
|
||||||
|
* @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet.
|
||||||
|
*/
|
||||||
|
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_packet_unpad(unsigned char *data, opus_int32 len);
|
||||||
|
|
||||||
|
/** Pads a given Opus multi-stream packet to a larger size (possibly changing the TOC sequence).
|
||||||
|
* @param[in,out] data <tt>const unsigned char*</tt>: The buffer containing the
|
||||||
|
* packet to pad.
|
||||||
|
* @param len <tt>opus_int32</tt>: The size of the packet.
|
||||||
|
* This must be at least 1.
|
||||||
|
* @param new_len <tt>opus_int32</tt>: The desired size of the packet after padding.
|
||||||
|
* This must be at least 1.
|
||||||
|
* @param nb_streams <tt>opus_int32</tt>: The number of streams (not channels) in the packet.
|
||||||
|
* This must be at least as large as len.
|
||||||
|
* @returns an error code
|
||||||
|
* @retval #OPUS_OK \a on success.
|
||||||
|
* @retval #OPUS_BAD_ARG \a len was less than 1.
|
||||||
|
* @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet.
|
||||||
|
*/
|
||||||
|
OPUS_EXPORT int opus_multistream_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len, int nb_streams);
|
||||||
|
|
||||||
|
/** Remove all padding from a given Opus multi-stream packet and rewrite the TOC sequence to
|
||||||
|
* minimize space usage.
|
||||||
|
* @param[in,out] data <tt>const unsigned char*</tt>: The buffer containing the
|
||||||
|
* packet to strip.
|
||||||
|
* @param len <tt>opus_int32</tt>: The size of the packet.
|
||||||
|
* This must be at least 1.
|
||||||
|
* @param nb_streams <tt>opus_int32</tt>: The number of streams (not channels) in the packet.
|
||||||
|
* This must be at least 1.
|
||||||
|
* @returns The new size of the output packet on success, or an error code
|
||||||
|
* on failure.
|
||||||
|
* @retval #OPUS_BAD_ARG \a len was less than 1 or new_len was less than len.
|
||||||
|
* @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet.
|
||||||
|
*/
|
||||||
|
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_packet_unpad(unsigned char *data, opus_int32 len, int nb_streams);
|
||||||
|
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
|
@ -42,15 +42,15 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CUSTOM_MODES
|
#ifdef CUSTOM_MODES
|
||||||
#define OPUS_CUSTOM_EXPORT OPUS_EXPORT
|
# define OPUS_CUSTOM_EXPORT OPUS_EXPORT
|
||||||
#define OPUS_CUSTOM_EXPORT_STATIC OPUS_EXPORT
|
# define OPUS_CUSTOM_EXPORT_STATIC OPUS_EXPORT
|
||||||
#else
|
#else
|
||||||
#define OPUS_CUSTOM_EXPORT
|
# define OPUS_CUSTOM_EXPORT
|
||||||
#ifdef CELT_C
|
# ifdef OPUS_BUILD
|
||||||
#define OPUS_CUSTOM_EXPORT_STATIC static inline
|
# define OPUS_CUSTOM_EXPORT_STATIC static OPUS_INLINE
|
||||||
#else
|
# else
|
||||||
#define OPUS_CUSTOM_EXPORT_STATIC
|
# define OPUS_CUSTOM_EXPORT_STATIC
|
||||||
#endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** @defgroup opus_custom Opus Custom
|
/** @defgroup opus_custom Opus Custom
|
||||||
|
@ -126,6 +126,9 @@ OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomMode *opus_custom_mode_crea
|
||||||
*/
|
*/
|
||||||
OPUS_CUSTOM_EXPORT void opus_custom_mode_destroy(OpusCustomMode *mode);
|
OPUS_CUSTOM_EXPORT void opus_custom_mode_destroy(OpusCustomMode *mode);
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(OPUS_BUILD) || defined(CELT_ENCODER_C)
|
||||||
|
|
||||||
/* Encoder */
|
/* Encoder */
|
||||||
/** Gets the size of an OpusCustomEncoder structure.
|
/** Gets the size of an OpusCustomEncoder structure.
|
||||||
* @param [in] mode <tt>OpusCustomMode *</tt>: Mode configuration
|
* @param [in] mode <tt>OpusCustomMode *</tt>: Mode configuration
|
||||||
|
@ -137,6 +140,28 @@ OPUS_CUSTOM_EXPORT_STATIC OPUS_WARN_UNUSED_RESULT int opus_custom_encoder_get_si
|
||||||
int channels
|
int channels
|
||||||
) OPUS_ARG_NONNULL(1);
|
) OPUS_ARG_NONNULL(1);
|
||||||
|
|
||||||
|
# ifdef CUSTOM_MODES
|
||||||
|
/** Initializes a previously allocated encoder state
|
||||||
|
* The memory pointed to by st must be the size returned by opus_custom_encoder_get_size.
|
||||||
|
* This is intended for applications which use their own allocator instead of malloc.
|
||||||
|
* @see opus_custom_encoder_create(),opus_custom_encoder_get_size()
|
||||||
|
* To reset a previously initialized state use the OPUS_RESET_STATE CTL.
|
||||||
|
* @param [in] st <tt>OpusCustomEncoder*</tt>: Encoder state
|
||||||
|
* @param [in] mode <tt>OpusCustomMode *</tt>: Contains all the information about the characteristics of
|
||||||
|
* the stream (must be the same characteristics as used for the
|
||||||
|
* decoder)
|
||||||
|
* @param [in] channels <tt>int</tt>: Number of channels
|
||||||
|
* @return OPUS_OK Success or @ref opus_errorcodes
|
||||||
|
*/
|
||||||
|
OPUS_CUSTOM_EXPORT int opus_custom_encoder_init(
|
||||||
|
OpusCustomEncoder *st,
|
||||||
|
const OpusCustomMode *mode,
|
||||||
|
int channels
|
||||||
|
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/** Creates a new encoder state. Each stream needs its own encoder
|
/** Creates a new encoder state. Each stream needs its own encoder
|
||||||
* state (can't be shared across simultaneous streams).
|
* state (can't be shared across simultaneous streams).
|
||||||
* @param [in] mode <tt>OpusCustomMode*</tt>: Contains all the information about the characteristics of
|
* @param [in] mode <tt>OpusCustomMode*</tt>: Contains all the information about the characteristics of
|
||||||
|
@ -152,23 +177,6 @@ OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomEncoder *opus_custom_encode
|
||||||
int *error
|
int *error
|
||||||
) OPUS_ARG_NONNULL(1);
|
) OPUS_ARG_NONNULL(1);
|
||||||
|
|
||||||
/** Initializes a previously allocated encoder state
|
|
||||||
* The memory pointed to by st must be the size returned by opus_custom_encoder_get_size.
|
|
||||||
* This is intended for applications which use their own allocator instead of malloc.
|
|
||||||
* @see opus_custom_encoder_create(),opus_custom_encoder_get_size()
|
|
||||||
* To reset a previously initialized state use the OPUS_RESET_STATE CTL.
|
|
||||||
* @param [in] st <tt>OpusCustomEncoder*</tt>: Encoder state
|
|
||||||
* @param [in] mode <tt>OpusCustomMode *</tt>: Contains all the information about the characteristics of
|
|
||||||
* the stream (must be the same characteristics as used for the
|
|
||||||
* decoder)
|
|
||||||
* @param [in] channels <tt>int</tt>: Number of channels
|
|
||||||
* @return OPUS_OK Success or @ref opus_errorcodes
|
|
||||||
*/
|
|
||||||
OPUS_CUSTOM_EXPORT_STATIC int opus_custom_encoder_init(
|
|
||||||
OpusCustomEncoder *st,
|
|
||||||
const OpusCustomMode *mode,
|
|
||||||
int channels
|
|
||||||
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);
|
|
||||||
|
|
||||||
/** Destroys a an encoder state.
|
/** Destroys a an encoder state.
|
||||||
* @param[in] st <tt>OpusCustomEncoder*</tt>: State to be freed.
|
* @param[in] st <tt>OpusCustomEncoder*</tt>: State to be freed.
|
||||||
|
@ -229,6 +237,8 @@ OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode(
|
||||||
*/
|
*/
|
||||||
OPUS_CUSTOM_EXPORT int opus_custom_encoder_ctl(OpusCustomEncoder * OPUS_RESTRICT st, int request, ...) OPUS_ARG_NONNULL(1);
|
OPUS_CUSTOM_EXPORT int opus_custom_encoder_ctl(OpusCustomEncoder * OPUS_RESTRICT st, int request, ...) OPUS_ARG_NONNULL(1);
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(OPUS_BUILD) || defined(CELT_DECODER_C)
|
||||||
/* Decoder */
|
/* Decoder */
|
||||||
|
|
||||||
/** Gets the size of an OpusCustomDecoder structure.
|
/** Gets the size of an OpusCustomDecoder structure.
|
||||||
|
@ -241,20 +251,6 @@ OPUS_CUSTOM_EXPORT_STATIC OPUS_WARN_UNUSED_RESULT int opus_custom_decoder_get_si
|
||||||
int channels
|
int channels
|
||||||
) OPUS_ARG_NONNULL(1);
|
) OPUS_ARG_NONNULL(1);
|
||||||
|
|
||||||
/** Creates a new decoder state. Each stream needs its own decoder state (can't
|
|
||||||
* be shared across simultaneous streams).
|
|
||||||
* @param [in] mode <tt>OpusCustomMode</tt>: Contains all the information about the characteristics of the
|
|
||||||
* stream (must be the same characteristics as used for the encoder)
|
|
||||||
* @param [in] channels <tt>int</tt>: Number of channels
|
|
||||||
* @param [out] error <tt>int*</tt>: Returns an error code
|
|
||||||
* @return Newly created decoder state.
|
|
||||||
*/
|
|
||||||
OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomDecoder *opus_custom_decoder_create(
|
|
||||||
const OpusCustomMode *mode,
|
|
||||||
int channels,
|
|
||||||
int *error
|
|
||||||
) OPUS_ARG_NONNULL(1);
|
|
||||||
|
|
||||||
/** Initializes a previously allocated decoder state
|
/** Initializes a previously allocated decoder state
|
||||||
* The memory pointed to by st must be the size returned by opus_custom_decoder_get_size.
|
* The memory pointed to by st must be the size returned by opus_custom_decoder_get_size.
|
||||||
* This is intended for applications which use their own allocator instead of malloc.
|
* This is intended for applications which use their own allocator instead of malloc.
|
||||||
|
@ -273,6 +269,23 @@ OPUS_CUSTOM_EXPORT_STATIC int opus_custom_decoder_init(
|
||||||
int channels
|
int channels
|
||||||
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);
|
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/** Creates a new decoder state. Each stream needs its own decoder state (can't
|
||||||
|
* be shared across simultaneous streams).
|
||||||
|
* @param [in] mode <tt>OpusCustomMode</tt>: Contains all the information about the characteristics of the
|
||||||
|
* stream (must be the same characteristics as used for the encoder)
|
||||||
|
* @param [in] channels <tt>int</tt>: Number of channels
|
||||||
|
* @param [out] error <tt>int*</tt>: Returns an error code
|
||||||
|
* @return Newly created decoder state.
|
||||||
|
*/
|
||||||
|
OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomDecoder *opus_custom_decoder_create(
|
||||||
|
const OpusCustomMode *mode,
|
||||||
|
int channels,
|
||||||
|
int *error
|
||||||
|
) OPUS_ARG_NONNULL(1);
|
||||||
|
|
||||||
/** Destroys a an decoder state.
|
/** Destroys a an decoder state.
|
||||||
* @param[in] st <tt>OpusCustomDecoder*</tt>: State to be freed.
|
* @param[in] st <tt>OpusCustomDecoder*</tt>: State to be freed.
|
||||||
*/
|
*/
|
|
@ -64,14 +64,14 @@ extern "C" {
|
||||||
/**Export control for opus functions */
|
/**Export control for opus functions */
|
||||||
|
|
||||||
#ifndef OPUS_EXPORT
|
#ifndef OPUS_EXPORT
|
||||||
# if defined(__GNUC__) && defined(OPUS_BUILD)
|
# if defined(WIN32)
|
||||||
# define OPUS_EXPORT __attribute__ ((visibility ("default")))
|
|
||||||
# elif defined(WIN32) && !defined(__MINGW32__)
|
|
||||||
# ifdef OPUS_BUILD
|
# ifdef OPUS_BUILD
|
||||||
# define OPUS_EXPORT __declspec(dllexport)
|
# define OPUS_EXPORT __declspec(dllexport)
|
||||||
# else
|
# else
|
||||||
# define OPUS_EXPORT
|
# define OPUS_EXPORT
|
||||||
# endif
|
# endif
|
||||||
|
# elif defined(__GNUC__) && defined(OPUS_BUILD)
|
||||||
|
# define OPUS_EXPORT __attribute__ ((visibility ("default")))
|
||||||
# else
|
# else
|
||||||
# define OPUS_EXPORT
|
# define OPUS_EXPORT
|
||||||
# endif
|
# endif
|
||||||
|
@ -98,6 +98,18 @@ extern "C" {
|
||||||
# define OPUS_RESTRICT restrict
|
# define OPUS_RESTRICT restrict
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) )
|
||||||
|
# if OPUS_GNUC_PREREQ(2,7)
|
||||||
|
# define OPUS_INLINE __inline__
|
||||||
|
# elif (defined(_MSC_VER))
|
||||||
|
# define OPUS_INLINE __inline
|
||||||
|
# else
|
||||||
|
# define OPUS_INLINE
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define OPUS_INLINE inline
|
||||||
|
#endif
|
||||||
|
|
||||||
/**Warning attributes for opus functions
|
/**Warning attributes for opus functions
|
||||||
* NONNULL is not used in OPUS_BUILD to avoid the compiler optimizing out
|
* NONNULL is not used in OPUS_BUILD to avoid the compiler optimizing out
|
||||||
* some paranoid null checks. */
|
* some paranoid null checks. */
|
||||||
|
@ -148,8 +160,11 @@ extern "C" {
|
||||||
#define OPUS_GET_GAIN_REQUEST 4045 /* Should have been 4035 */
|
#define OPUS_GET_GAIN_REQUEST 4045 /* Should have been 4035 */
|
||||||
#define OPUS_SET_LSB_DEPTH_REQUEST 4036
|
#define OPUS_SET_LSB_DEPTH_REQUEST 4036
|
||||||
#define OPUS_GET_LSB_DEPTH_REQUEST 4037
|
#define OPUS_GET_LSB_DEPTH_REQUEST 4037
|
||||||
|
|
||||||
#define OPUS_GET_LAST_PACKET_DURATION_REQUEST 4039
|
#define OPUS_GET_LAST_PACKET_DURATION_REQUEST 4039
|
||||||
|
#define OPUS_SET_EXPERT_FRAME_DURATION_REQUEST 4040
|
||||||
|
#define OPUS_GET_EXPERT_FRAME_DURATION_REQUEST 4041
|
||||||
|
#define OPUS_SET_PREDICTION_DISABLED_REQUEST 4042
|
||||||
|
#define OPUS_GET_PREDICTION_DISABLED_REQUEST 4043
|
||||||
|
|
||||||
/* Don't use 4045, it's already taken by OPUS_GET_GAIN_REQUEST */
|
/* Don't use 4045, it's already taken by OPUS_GET_GAIN_REQUEST */
|
||||||
|
|
||||||
|
@ -157,6 +172,7 @@ extern "C" {
|
||||||
#define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x))
|
#define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x))
|
||||||
#define __opus_check_int_ptr(ptr) ((ptr) + ((ptr) - (opus_int32*)(ptr)))
|
#define __opus_check_int_ptr(ptr) ((ptr) + ((ptr) - (opus_int32*)(ptr)))
|
||||||
#define __opus_check_uint_ptr(ptr) ((ptr) + ((ptr) - (opus_uint32*)(ptr)))
|
#define __opus_check_uint_ptr(ptr) ((ptr) + ((ptr) - (opus_uint32*)(ptr)))
|
||||||
|
#define __opus_check_val16_ptr(ptr) ((ptr) + ((ptr) - (opus_val16*)(ptr)))
|
||||||
/** @endcond */
|
/** @endcond */
|
||||||
|
|
||||||
/** @defgroup opus_ctlvalues Pre-defined values for CTL interface
|
/** @defgroup opus_ctlvalues Pre-defined values for CTL interface
|
||||||
|
@ -185,6 +201,14 @@ extern "C" {
|
||||||
#define OPUS_BANDWIDTH_SUPERWIDEBAND 1104 /**<12 kHz bandpass @hideinitializer*/
|
#define OPUS_BANDWIDTH_SUPERWIDEBAND 1104 /**<12 kHz bandpass @hideinitializer*/
|
||||||
#define OPUS_BANDWIDTH_FULLBAND 1105 /**<20 kHz bandpass @hideinitializer*/
|
#define OPUS_BANDWIDTH_FULLBAND 1105 /**<20 kHz bandpass @hideinitializer*/
|
||||||
|
|
||||||
|
#define OPUS_FRAMESIZE_ARG 5000 /**< Select frame size from the argument (default) */
|
||||||
|
#define OPUS_FRAMESIZE_2_5_MS 5001 /**< Use 2.5 ms frames */
|
||||||
|
#define OPUS_FRAMESIZE_5_MS 5002 /**< Use 5 ms frames */
|
||||||
|
#define OPUS_FRAMESIZE_10_MS 5003 /**< Use 10 ms frames */
|
||||||
|
#define OPUS_FRAMESIZE_20_MS 5004 /**< Use 20 ms frames */
|
||||||
|
#define OPUS_FRAMESIZE_40_MS 5005 /**< Use 40 ms frames */
|
||||||
|
#define OPUS_FRAMESIZE_60_MS 5006 /**< Use 60 ms frames */
|
||||||
|
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -525,6 +549,53 @@ extern "C" {
|
||||||
* @param[out] x <tt>opus_int32 *</tt>: Number of samples (at current sampling rate).
|
* @param[out] x <tt>opus_int32 *</tt>: Number of samples (at current sampling rate).
|
||||||
* @hideinitializer */
|
* @hideinitializer */
|
||||||
#define OPUS_GET_LAST_PACKET_DURATION(x) OPUS_GET_LAST_PACKET_DURATION_REQUEST, __opus_check_int_ptr(x)
|
#define OPUS_GET_LAST_PACKET_DURATION(x) OPUS_GET_LAST_PACKET_DURATION_REQUEST, __opus_check_int_ptr(x)
|
||||||
|
|
||||||
|
/** Configures the encoder's use of variable duration frames.
|
||||||
|
* When variable duration is enabled, the encoder is free to use a shorter frame
|
||||||
|
* size than the one requested in the opus_encode*() call.
|
||||||
|
* It is then the user's responsibility
|
||||||
|
* to verify how much audio was encoded by checking the ToC byte of the encoded
|
||||||
|
* packet. The part of the audio that was not encoded needs to be resent to the
|
||||||
|
* encoder for the next call. Do not use this option unless you <b>really</b>
|
||||||
|
* know what you are doing.
|
||||||
|
* @see OPUS_GET_EXPERT_VARIABLE_DURATION
|
||||||
|
* @param[in] x <tt>opus_int32</tt>: Allowed values:
|
||||||
|
* <dl>
|
||||||
|
* <dt>OPUS_FRAMESIZE_ARG</dt><dd>Select frame size from the argument (default).</dd>
|
||||||
|
* <dt>OPUS_FRAMESIZE_2_5_MS</dt><dd>Use 2.5 ms frames.</dd>
|
||||||
|
* <dt>OPUS_FRAMESIZE_5_MS</dt><dd>Use 2.5 ms frames.</dd>
|
||||||
|
* <dt>OPUS_FRAMESIZE_10_MS</dt><dd>Use 10 ms frames.</dd>
|
||||||
|
* <dt>OPUS_FRAMESIZE_20_MS</dt><dd>Use 20 ms frames.</dd>
|
||||||
|
* <dt>OPUS_FRAMESIZE_40_MS</dt><dd>Use 40 ms frames.</dd>
|
||||||
|
* <dt>OPUS_FRAMESIZE_60_MS</dt><dd>Use 60 ms frames.</dd>
|
||||||
|
* <dt>OPUS_FRAMESIZE_VARIABLE</dt><dd>Optimize the frame size dynamically.</dd>
|
||||||
|
* </dl>
|
||||||
|
* @hideinitializer */
|
||||||
|
#define OPUS_SET_EXPERT_FRAME_DURATION(x) OPUS_SET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int(x)
|
||||||
|
/** Gets the encoder's configured use of variable duration frames.
|
||||||
|
* @see OPUS_SET_EXPERT_VARIABLE_DURATION
|
||||||
|
* @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
|
||||||
|
* <dl>
|
||||||
|
* <dt>OPUS_FRAMESIZE_ARG</dt><dd>Select frame size from the argument (default).</dd>
|
||||||
|
* <dt>OPUS_FRAMESIZE_2_5_MS</dt><dd>Use 2.5 ms frames.</dd>
|
||||||
|
* <dt>OPUS_FRAMESIZE_5_MS</dt><dd>Use 2.5 ms frames.</dd>
|
||||||
|
* <dt>OPUS_FRAMESIZE_10_MS</dt><dd>Use 10 ms frames.</dd>
|
||||||
|
* <dt>OPUS_FRAMESIZE_20_MS</dt><dd>Use 20 ms frames.</dd>
|
||||||
|
* <dt>OPUS_FRAMESIZE_40_MS</dt><dd>Use 40 ms frames.</dd>
|
||||||
|
* <dt>OPUS_FRAMESIZE_60_MS</dt><dd>Use 60 ms frames.</dd>
|
||||||
|
* <dt>OPUS_FRAMESIZE_VARIABLE</dt><dd>Optimize the frame size dynamically.</dd>
|
||||||
|
* </dl>
|
||||||
|
* @hideinitializer */
|
||||||
|
#define OPUS_GET_EXPERT_FRAME_DURATION(x) OPUS_GET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int_ptr(x)
|
||||||
|
|
||||||
|
/** If set to 1, disables almost all use of prediction, making frames almost
|
||||||
|
completely independent. This reduces quality. (default : 0)
|
||||||
|
* @hideinitializer */
|
||||||
|
#define OPUS_SET_PREDICTION_DISABLED(x) OPUS_SET_PREDICTION_DISABLED_REQUEST, __opus_check_int(x)
|
||||||
|
/** Gets the encoder's configured prediction status.
|
||||||
|
* @hideinitializer */
|
||||||
|
#define OPUS_GET_PREDICTION_DISABLED(x) OPUS_GET_PREDICTION_DISABLED_REQUEST, __opus_check_int_ptr(x)
|
||||||
|
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
||||||
/** @defgroup opus_genericctls Generic CTLs
|
/** @defgroup opus_genericctls Generic CTLs
|
|
@ -205,6 +205,12 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_encoder_get_size
|
||||||
int coupled_streams
|
int coupled_streams
|
||||||
);
|
);
|
||||||
|
|
||||||
|
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_surround_encoder_get_size(
|
||||||
|
int channels,
|
||||||
|
int mapping_family
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
/** Allocates and initializes a multistream encoder state.
|
/** Allocates and initializes a multistream encoder state.
|
||||||
* Call opus_multistream_encoder_destroy() to release
|
* Call opus_multistream_encoder_destroy() to release
|
||||||
* this object when finished.
|
* this object when finished.
|
||||||
|
@ -258,6 +264,17 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_encoder_crea
|
||||||
int *error
|
int *error
|
||||||
) OPUS_ARG_NONNULL(5);
|
) OPUS_ARG_NONNULL(5);
|
||||||
|
|
||||||
|
OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_surround_encoder_create(
|
||||||
|
opus_int32 Fs,
|
||||||
|
int channels,
|
||||||
|
int mapping_family,
|
||||||
|
int *streams,
|
||||||
|
int *coupled_streams,
|
||||||
|
unsigned char *mapping,
|
||||||
|
int application,
|
||||||
|
int *error
|
||||||
|
) OPUS_ARG_NONNULL(5);
|
||||||
|
|
||||||
/** Initialize a previously allocated multistream encoder state.
|
/** Initialize a previously allocated multistream encoder state.
|
||||||
* The memory pointed to by \a st must be at least the size returned by
|
* The memory pointed to by \a st must be at least the size returned by
|
||||||
* opus_multistream_encoder_get_size().
|
* opus_multistream_encoder_get_size().
|
||||||
|
@ -316,6 +333,17 @@ OPUS_EXPORT int opus_multistream_encoder_init(
|
||||||
int application
|
int application
|
||||||
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
|
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
|
||||||
|
|
||||||
|
OPUS_EXPORT int opus_multistream_surround_encoder_init(
|
||||||
|
OpusMSEncoder *st,
|
||||||
|
opus_int32 Fs,
|
||||||
|
int channels,
|
||||||
|
int mapping_family,
|
||||||
|
int *streams,
|
||||||
|
int *coupled_streams,
|
||||||
|
unsigned char *mapping,
|
||||||
|
int application
|
||||||
|
) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
|
||||||
|
|
||||||
/** Encodes a multistream Opus frame.
|
/** Encodes a multistream Opus frame.
|
||||||
* @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
|
* @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
|
||||||
* @param[in] pcm <tt>const opus_int16*</tt>: The input signal as interleaved
|
* @param[in] pcm <tt>const opus_int16*</tt>: The input signal as interleaved
|
|
@ -8,11 +8,11 @@ this list of conditions and the following disclaimer.
|
||||||
- Redistributions in binary form must reproduce the above copyright
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
documentation and/or other materials provided with the distribution.
|
||||||
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
||||||
names of specific contributors, may be used to endorse or promote
|
names of specific contributors, may be used to endorse or promote
|
||||||
products derived from this software without specific prior written
|
products derived from this software without specific prior written
|
||||||
permission.
|
permission.
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
@ -44,7 +44,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
/* Helper function for A2NLSF(..) */
|
/* Helper function for A2NLSF(..) */
|
||||||
/* Transforms polynomials from cos(n*f) to cos(f)^n */
|
/* Transforms polynomials from cos(n*f) to cos(f)^n */
|
||||||
static inline void silk_A2NLSF_trans_poly(
|
static OPUS_INLINE void silk_A2NLSF_trans_poly(
|
||||||
opus_int32 *p, /* I/O Polynomial */
|
opus_int32 *p, /* I/O Polynomial */
|
||||||
const opus_int dd /* I Polynomial order (= filter order / 2 ) */
|
const opus_int dd /* I Polynomial order (= filter order / 2 ) */
|
||||||
)
|
)
|
||||||
|
@ -60,7 +60,7 @@ static inline void silk_A2NLSF_trans_poly(
|
||||||
}
|
}
|
||||||
/* Helper function for A2NLSF(..) */
|
/* Helper function for A2NLSF(..) */
|
||||||
/* Polynomial evaluation */
|
/* Polynomial evaluation */
|
||||||
static inline opus_int32 silk_A2NLSF_eval_poly( /* return the polynomial evaluation, in Q16 */
|
static OPUS_INLINE opus_int32 silk_A2NLSF_eval_poly( /* return the polynomial evaluation, in Q16 */
|
||||||
opus_int32 *p, /* I Polynomial, Q16 */
|
opus_int32 *p, /* I Polynomial, Q16 */
|
||||||
const opus_int32 x, /* I Evaluation point, Q12 */
|
const opus_int32 x, /* I Evaluation point, Q12 */
|
||||||
const opus_int dd /* I Order */
|
const opus_int dd /* I Order */
|
||||||
|
@ -77,7 +77,7 @@ static inline opus_int32 silk_A2NLSF_eval_poly( /* return the polynomial evaluat
|
||||||
return y32;
|
return y32;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void silk_A2NLSF_init(
|
static OPUS_INLINE void silk_A2NLSF_init(
|
||||||
const opus_int32 *a_Q16,
|
const opus_int32 *a_Q16,
|
||||||
opus_int32 *P,
|
opus_int32 *P,
|
||||||
opus_int32 *Q,
|
opus_int32 *Q,
|
|
@ -8,11 +8,11 @@ this list of conditions and the following disclaimer.
|
||||||
- Redistributions in binary form must reproduce the above copyright
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
documentation and/or other materials provided with the distribution.
|
||||||
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
||||||
names of specific contributors, may be used to endorse or promote
|
names of specific contributors, may be used to endorse or promote
|
||||||
products derived from this software without specific prior written
|
products derived from this software without specific prior written
|
||||||
permission.
|
permission.
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
@ -64,6 +64,7 @@ opus_int silk_Get_Encoder_Size( /* O Returns error co
|
||||||
/*************************/
|
/*************************/
|
||||||
opus_int silk_InitEncoder( /* O Returns error code */
|
opus_int silk_InitEncoder( /* O Returns error code */
|
||||||
void *encState, /* I/O State */
|
void *encState, /* I/O State */
|
||||||
|
int arch, /* I Run-time architecture */
|
||||||
silk_EncControlStruct *encStatus /* O Encoder Status */
|
silk_EncControlStruct *encStatus /* O Encoder Status */
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,11 +8,11 @@ this list of conditions and the following disclaimer.
|
||||||
- Redistributions in binary form must reproduce the above copyright
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
documentation and/or other materials provided with the distribution.
|
||||||
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
||||||
names of specific contributors, may be used to endorse or promote
|
names of specific contributors, may be used to endorse or promote
|
||||||
products derived from this software without specific prior written
|
products derived from this software without specific prior written
|
||||||
permission.
|
permission.
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
@ -30,9 +30,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "stack_alloc.h"
|
||||||
|
|
||||||
/* Generates excitation for CNG LPC synthesis */
|
/* Generates excitation for CNG LPC synthesis */
|
||||||
static inline void silk_CNG_exc(
|
static OPUS_INLINE void silk_CNG_exc(
|
||||||
opus_int32 residual_Q10[], /* O CNG residual signal Q10 */
|
opus_int32 residual_Q10[], /* O CNG residual signal Q10 */
|
||||||
opus_int32 exc_buf_Q14[], /* I Random samples buffer Q10 */
|
opus_int32 exc_buf_Q14[], /* I Random samples buffer Q10 */
|
||||||
opus_int32 Gain_Q16, /* I Gain to apply */
|
opus_int32 Gain_Q16, /* I Gain to apply */
|
||||||
|
@ -86,8 +87,8 @@ void silk_CNG(
|
||||||
opus_int i, subfr;
|
opus_int i, subfr;
|
||||||
opus_int32 sum_Q6, max_Gain_Q16;
|
opus_int32 sum_Q6, max_Gain_Q16;
|
||||||
opus_int16 A_Q12[ MAX_LPC_ORDER ];
|
opus_int16 A_Q12[ MAX_LPC_ORDER ];
|
||||||
opus_int32 CNG_sig_Q10[ MAX_FRAME_LENGTH + MAX_LPC_ORDER ];
|
|
||||||
silk_CNG_struct *psCNG = &psDec->sCNG;
|
silk_CNG_struct *psCNG = &psDec->sCNG;
|
||||||
|
SAVE_STACK;
|
||||||
|
|
||||||
if( psDec->fs_kHz != psCNG->fs_kHz ) {
|
if( psDec->fs_kHz != psCNG->fs_kHz ) {
|
||||||
/* Reset state */
|
/* Reset state */
|
||||||
|
@ -123,6 +124,9 @@ void silk_CNG(
|
||||||
|
|
||||||
/* Add CNG when packet is lost or during DTX */
|
/* Add CNG when packet is lost or during DTX */
|
||||||
if( psDec->lossCnt ) {
|
if( psDec->lossCnt ) {
|
||||||
|
VARDECL( opus_int32, CNG_sig_Q10 );
|
||||||
|
|
||||||
|
ALLOC( CNG_sig_Q10, length + MAX_LPC_ORDER, opus_int32 );
|
||||||
|
|
||||||
/* Generate CNG excitation */
|
/* Generate CNG excitation */
|
||||||
silk_CNG_exc( CNG_sig_Q10 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q14, psCNG->CNG_smth_Gain_Q16, length, &psCNG->rand_seed );
|
silk_CNG_exc( CNG_sig_Q10 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q14, psCNG->CNG_smth_Gain_Q16, length, &psCNG->rand_seed );
|
||||||
|
@ -164,4 +168,5 @@ void silk_CNG(
|
||||||
} else {
|
} else {
|
||||||
silk_memset( psCNG->CNG_synth_state, 0, psDec->LPC_order * sizeof( opus_int32 ) );
|
silk_memset( psCNG->CNG_synth_state, 0, psDec->LPC_order * sizeof( opus_int32 ) );
|
||||||
}
|
}
|
||||||
|
RESTORE_STACK;
|
||||||
}
|
}
|
|
@ -8,11 +8,11 @@ this list of conditions and the following disclaimer.
|
||||||
- Redistributions in binary form must reproduce the above copyright
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
documentation and/or other materials provided with the distribution.
|
||||||
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
||||||
names of specific contributors, may be used to endorse or promote
|
names of specific contributors, may be used to endorse or promote
|
||||||
products derived from this software without specific prior written
|
products derived from this software without specific prior written
|
||||||
permission.
|
permission.
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
@ -8,11 +8,11 @@ this list of conditions and the following disclaimer.
|
||||||
- Redistributions in binary form must reproduce the above copyright
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
documentation and/or other materials provided with the distribution.
|
||||||
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
||||||
names of specific contributors, may be used to endorse or promote
|
names of specific contributors, may be used to endorse or promote
|
||||||
products derived from this software without specific prior written
|
products derived from this software without specific prior written
|
||||||
permission.
|
permission.
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
@ -26,7 +26,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
/*! \file silk_Inlines.h
|
/*! \file silk_Inlines.h
|
||||||
* \brief silk_Inlines.h defines inline signal processing functions.
|
* \brief silk_Inlines.h defines OPUS_INLINE signal processing functions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SILK_FIX_INLINES_H
|
#ifndef SILK_FIX_INLINES_H
|
||||||
|
@ -38,7 +38,7 @@ extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* count leading zeros of opus_int64 */
|
/* count leading zeros of opus_int64 */
|
||||||
static inline opus_int32 silk_CLZ64( opus_int64 in )
|
static OPUS_INLINE opus_int32 silk_CLZ64( opus_int64 in )
|
||||||
{
|
{
|
||||||
opus_int32 in_upper;
|
opus_int32 in_upper;
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ static inline opus_int32 silk_CLZ64( opus_int64 in )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get number of leading zeros and fractional part (the bits right after the leading one */
|
/* get number of leading zeros and fractional part (the bits right after the leading one */
|
||||||
static inline void silk_CLZ_FRAC(
|
static OPUS_INLINE void silk_CLZ_FRAC(
|
||||||
opus_int32 in, /* I input */
|
opus_int32 in, /* I input */
|
||||||
opus_int32 *lz, /* O number of leading zeros */
|
opus_int32 *lz, /* O number of leading zeros */
|
||||||
opus_int32 *frac_Q7 /* O the 7 bits right after the leading one */
|
opus_int32 *frac_Q7 /* O the 7 bits right after the leading one */
|
||||||
|
@ -68,7 +68,7 @@ static inline void silk_CLZ_FRAC(
|
||||||
/* Approximation of square root */
|
/* Approximation of square root */
|
||||||
/* Accuracy: < +/- 10% for output values > 15 */
|
/* Accuracy: < +/- 10% for output values > 15 */
|
||||||
/* < +/- 2.5% for output values > 120 */
|
/* < +/- 2.5% for output values > 120 */
|
||||||
static inline opus_int32 silk_SQRT_APPROX( opus_int32 x )
|
static OPUS_INLINE opus_int32 silk_SQRT_APPROX( opus_int32 x )
|
||||||
{
|
{
|
||||||
opus_int32 y, lz, frac_Q7;
|
opus_int32 y, lz, frac_Q7;
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ static inline opus_int32 silk_SQRT_APPROX( opus_int32 x )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Divide two int32 values and return result as int32 in a given Q-domain */
|
/* Divide two int32 values and return result as int32 in a given Q-domain */
|
||||||
static inline opus_int32 silk_DIV32_varQ( /* O returns a good approximation of "(a32 << Qres) / b32" */
|
static OPUS_INLINE opus_int32 silk_DIV32_varQ( /* O returns a good approximation of "(a32 << Qres) / b32" */
|
||||||
const opus_int32 a32, /* I numerator (Q0) */
|
const opus_int32 a32, /* I numerator (Q0) */
|
||||||
const opus_int32 b32, /* I denominator (Q0) */
|
const opus_int32 b32, /* I denominator (Q0) */
|
||||||
const opus_int Qres /* I Q-domain of result (>= 0) */
|
const opus_int Qres /* I Q-domain of result (>= 0) */
|
||||||
|
@ -140,7 +140,7 @@ static inline opus_int32 silk_DIV32_varQ( /* O returns a good approximation
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Invert int32 value and return result as int32 in a given Q-domain */
|
/* Invert int32 value and return result as int32 in a given Q-domain */
|
||||||
static inline opus_int32 silk_INVERSE32_varQ( /* O returns a good approximation of "(1 << Qres) / b32" */
|
static OPUS_INLINE opus_int32 silk_INVERSE32_varQ( /* O returns a good approximation of "(1 << Qres) / b32" */
|
||||||
const opus_int32 b32, /* I denominator (Q0) */
|
const opus_int32 b32, /* I denominator (Q0) */
|
||||||
const opus_int Qres /* I Q-domain of result (> 0) */
|
const opus_int Qres /* I Q-domain of result (> 0) */
|
||||||
)
|
)
|
|
@ -8,11 +8,11 @@ this list of conditions and the following disclaimer.
|
||||||
- Redistributions in binary form must reproduce the above copyright
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
documentation and/or other materials provided with the distribution.
|
||||||
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
||||||
names of specific contributors, may be used to endorse or promote
|
names of specific contributors, may be used to endorse or promote
|
||||||
products derived from this software without specific prior written
|
products derived from this software without specific prior written
|
||||||
permission.
|
permission.
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "SigProc_FIX.h"
|
#include "SigProc_FIX.h"
|
||||||
|
#include "celt_lpc.h"
|
||||||
|
|
||||||
/*******************************************/
|
/*******************************************/
|
||||||
/* LPC analysis filter */
|
/* LPC analysis filter */
|
||||||
|
@ -46,14 +47,33 @@ void silk_LPC_analysis_filter(
|
||||||
const opus_int32 d /* I Filter order */
|
const opus_int32 d /* I Filter order */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
opus_int ix, j;
|
opus_int j;
|
||||||
|
#ifdef FIXED_POINT
|
||||||
|
opus_int16 mem[SILK_MAX_ORDER_LPC];
|
||||||
|
opus_int16 num[SILK_MAX_ORDER_LPC];
|
||||||
|
#else
|
||||||
|
int ix;
|
||||||
opus_int32 out32_Q12, out32;
|
opus_int32 out32_Q12, out32;
|
||||||
const opus_int16 *in_ptr;
|
const opus_int16 *in_ptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
silk_assert( d >= 6 );
|
silk_assert( d >= 6 );
|
||||||
silk_assert( (d & 1) == 0 );
|
silk_assert( (d & 1) == 0 );
|
||||||
silk_assert( d <= len );
|
silk_assert( d <= len );
|
||||||
|
|
||||||
|
#ifdef FIXED_POINT
|
||||||
|
silk_assert( d <= SILK_MAX_ORDER_LPC );
|
||||||
|
for ( j = 0; j < d; j++ ) {
|
||||||
|
num[ j ] = -B[ j ];
|
||||||
|
}
|
||||||
|
for (j=0;j<d;j++) {
|
||||||
|
mem[ j ] = in[ d - j - 1 ];
|
||||||
|
}
|
||||||
|
celt_fir( in + d, num, out + d, len - d, d, mem );
|
||||||
|
for ( j = 0; j < d; j++ ) {
|
||||||
|
out[ j ] = 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
for( ix = d; ix < len; ix++ ) {
|
for( ix = d; ix < len; ix++ ) {
|
||||||
in_ptr = &in[ ix - 1 ];
|
in_ptr = &in[ ix - 1 ];
|
||||||
|
|
||||||
|
@ -82,4 +102,5 @@ void silk_LPC_analysis_filter(
|
||||||
|
|
||||||
/* Set first d output samples to zero */
|
/* Set first d output samples to zero */
|
||||||
silk_memset( out, 0, d * sizeof( opus_int16 ) );
|
silk_memset( out, 0, d * sizeof( opus_int16 ) );
|
||||||
|
#endif
|
||||||
}
|
}
|
|
@ -8,11 +8,11 @@ this list of conditions and the following disclaimer.
|
||||||
- Redistributions in binary form must reproduce the above copyright
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
documentation and/or other materials provided with the distribution.
|
||||||
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
||||||
names of specific contributors, may be used to endorse or promote
|
names of specific contributors, may be used to endorse or promote
|
||||||
products derived from this software without specific prior written
|
products derived from this software without specific prior written
|
||||||
permission.
|
permission.
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
@ -8,11 +8,11 @@ this list of conditions and the following disclaimer.
|
||||||
- Redistributions in binary form must reproduce the above copyright
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
documentation and/or other materials provided with the distribution.
|
||||||
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
||||||
names of specific contributors, may be used to endorse or promote
|
names of specific contributors, may be used to endorse or promote
|
||||||
products derived from this software without specific prior written
|
products derived from this software without specific prior written
|
||||||
permission.
|
permission.
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
@ -38,7 +38,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
/* Helper function, interpolates the filter taps */
|
/* Helper function, interpolates the filter taps */
|
||||||
static inline void silk_LP_interpolate_filter_taps(
|
static OPUS_INLINE void silk_LP_interpolate_filter_taps(
|
||||||
opus_int32 B_Q28[ TRANSITION_NB ],
|
opus_int32 B_Q28[ TRANSITION_NB ],
|
||||||
opus_int32 A_Q28[ TRANSITION_NA ],
|
opus_int32 A_Q28[ TRANSITION_NA ],
|
||||||
const opus_int ind,
|
const opus_int ind,
|
|
@ -8,11 +8,11 @@ this list of conditions and the following disclaimer.
|
||||||
- Redistributions in binary form must reproduce the above copyright
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
documentation and/or other materials provided with the distribution.
|
||||||
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
||||||
names of specific contributors, may be used to endorse or promote
|
names of specific contributors, may be used to endorse or promote
|
||||||
products derived from this software without specific prior written
|
products derived from this software without specific prior written
|
||||||
permission.
|
permission.
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
@ -34,11 +34,11 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
extern opus_int64 ops_count;
|
extern opus_int64 ops_count;
|
||||||
|
|
||||||
static inline opus_int64 silk_SaveCount(){
|
static OPUS_INLINE opus_int64 silk_SaveCount(){
|
||||||
return(ops_count);
|
return(ops_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline opus_int64 silk_SaveResetCount(){
|
static OPUS_INLINE opus_int64 silk_SaveResetCount(){
|
||||||
opus_int64 ret;
|
opus_int64 ret;
|
||||||
|
|
||||||
ret = ops_count;
|
ret = ops_count;
|
||||||
|
@ -46,12 +46,12 @@ static inline opus_int64 silk_SaveResetCount(){
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline silk_PrintCount(){
|
static OPUS_INLINE silk_PrintCount(){
|
||||||
printf("ops_count = %d \n ", (opus_int32)ops_count);
|
printf("ops_count = %d \n ", (opus_int32)ops_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_MUL
|
#undef silk_MUL
|
||||||
static inline opus_int32 silk_MUL(opus_int32 a32, opus_int32 b32){
|
static OPUS_INLINE opus_int32 silk_MUL(opus_int32 a32, opus_int32 b32){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ops_count += 4;
|
ops_count += 4;
|
||||||
ret = a32 * b32;
|
ret = a32 * b32;
|
||||||
|
@ -59,14 +59,14 @@ static inline opus_int32 silk_MUL(opus_int32 a32, opus_int32 b32){
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_MUL_uint
|
#undef silk_MUL_uint
|
||||||
static inline opus_uint32 silk_MUL_uint(opus_uint32 a32, opus_uint32 b32){
|
static OPUS_INLINE opus_uint32 silk_MUL_uint(opus_uint32 a32, opus_uint32 b32){
|
||||||
opus_uint32 ret;
|
opus_uint32 ret;
|
||||||
ops_count += 4;
|
ops_count += 4;
|
||||||
ret = a32 * b32;
|
ret = a32 * b32;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#undef silk_MLA
|
#undef silk_MLA
|
||||||
static inline opus_int32 silk_MLA(opus_int32 a32, opus_int32 b32, opus_int32 c32){
|
static OPUS_INLINE opus_int32 silk_MLA(opus_int32 a32, opus_int32 b32, opus_int32 c32){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ops_count += 4;
|
ops_count += 4;
|
||||||
ret = a32 + b32 * c32;
|
ret = a32 + b32 * c32;
|
||||||
|
@ -74,7 +74,7 @@ static inline opus_int32 silk_MLA(opus_int32 a32, opus_int32 b32, opus_int32 c32
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_MLA_uint
|
#undef silk_MLA_uint
|
||||||
static inline opus_int32 silk_MLA_uint(opus_uint32 a32, opus_uint32 b32, opus_uint32 c32){
|
static OPUS_INLINE opus_int32 silk_MLA_uint(opus_uint32 a32, opus_uint32 b32, opus_uint32 c32){
|
||||||
opus_uint32 ret;
|
opus_uint32 ret;
|
||||||
ops_count += 4;
|
ops_count += 4;
|
||||||
ret = a32 + b32 * c32;
|
ret = a32 + b32 * c32;
|
||||||
|
@ -82,14 +82,14 @@ static inline opus_int32 silk_MLA_uint(opus_uint32 a32, opus_uint32 b32, opus_ui
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_SMULWB
|
#undef silk_SMULWB
|
||||||
static inline opus_int32 silk_SMULWB(opus_int32 a32, opus_int32 b32){
|
static OPUS_INLINE opus_int32 silk_SMULWB(opus_int32 a32, opus_int32 b32){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ops_count += 5;
|
ops_count += 5;
|
||||||
ret = (a32 >> 16) * (opus_int32)((opus_int16)b32) + (((a32 & 0x0000FFFF) * (opus_int32)((opus_int16)b32)) >> 16);
|
ret = (a32 >> 16) * (opus_int32)((opus_int16)b32) + (((a32 & 0x0000FFFF) * (opus_int32)((opus_int16)b32)) >> 16);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#undef silk_SMLAWB
|
#undef silk_SMLAWB
|
||||||
static inline opus_int32 silk_SMLAWB(opus_int32 a32, opus_int32 b32, opus_int32 c32){
|
static OPUS_INLINE opus_int32 silk_SMLAWB(opus_int32 a32, opus_int32 b32, opus_int32 c32){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ops_count += 5;
|
ops_count += 5;
|
||||||
ret = ((a32) + ((((b32) >> 16) * (opus_int32)((opus_int16)(c32))) + ((((b32) & 0x0000FFFF) * (opus_int32)((opus_int16)(c32))) >> 16)));
|
ret = ((a32) + ((((b32) >> 16) * (opus_int32)((opus_int16)(c32))) + ((((b32) & 0x0000FFFF) * (opus_int32)((opus_int16)(c32))) >> 16)));
|
||||||
|
@ -97,14 +97,14 @@ static inline opus_int32 silk_SMLAWB(opus_int32 a32, opus_int32 b32, opus_int32
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_SMULWT
|
#undef silk_SMULWT
|
||||||
static inline opus_int32 silk_SMULWT(opus_int32 a32, opus_int32 b32){
|
static OPUS_INLINE opus_int32 silk_SMULWT(opus_int32 a32, opus_int32 b32){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ops_count += 4;
|
ops_count += 4;
|
||||||
ret = (a32 >> 16) * (b32 >> 16) + (((a32 & 0x0000FFFF) * (b32 >> 16)) >> 16);
|
ret = (a32 >> 16) * (b32 >> 16) + (((a32 & 0x0000FFFF) * (b32 >> 16)) >> 16);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#undef silk_SMLAWT
|
#undef silk_SMLAWT
|
||||||
static inline opus_int32 silk_SMLAWT(opus_int32 a32, opus_int32 b32, opus_int32 c32){
|
static OPUS_INLINE opus_int32 silk_SMLAWT(opus_int32 a32, opus_int32 b32, opus_int32 c32){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ops_count += 4;
|
ops_count += 4;
|
||||||
ret = a32 + ((b32 >> 16) * (c32 >> 16)) + (((b32 & 0x0000FFFF) * ((c32 >> 16)) >> 16));
|
ret = a32 + ((b32 >> 16) * (c32 >> 16)) + (((b32 & 0x0000FFFF) * ((c32 >> 16)) >> 16));
|
||||||
|
@ -112,14 +112,14 @@ static inline opus_int32 silk_SMLAWT(opus_int32 a32, opus_int32 b32, opus_int32
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_SMULBB
|
#undef silk_SMULBB
|
||||||
static inline opus_int32 silk_SMULBB(opus_int32 a32, opus_int32 b32){
|
static OPUS_INLINE opus_int32 silk_SMULBB(opus_int32 a32, opus_int32 b32){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
ret = (opus_int32)((opus_int16)a32) * (opus_int32)((opus_int16)b32);
|
ret = (opus_int32)((opus_int16)a32) * (opus_int32)((opus_int16)b32);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#undef silk_SMLABB
|
#undef silk_SMLABB
|
||||||
static inline opus_int32 silk_SMLABB(opus_int32 a32, opus_int32 b32, opus_int32 c32){
|
static OPUS_INLINE opus_int32 silk_SMLABB(opus_int32 a32, opus_int32 b32, opus_int32 c32){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
ret = a32 + (opus_int32)((opus_int16)b32) * (opus_int32)((opus_int16)c32);
|
ret = a32 + (opus_int32)((opus_int16)b32) * (opus_int32)((opus_int16)c32);
|
||||||
|
@ -127,7 +127,7 @@ static inline opus_int32 silk_SMLABB(opus_int32 a32, opus_int32 b32, opus_int32
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_SMULBT
|
#undef silk_SMULBT
|
||||||
static inline opus_int32 silk_SMULBT(opus_int32 a32, opus_int32 b32 ){
|
static OPUS_INLINE opus_int32 silk_SMULBT(opus_int32 a32, opus_int32 b32 ){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ops_count += 4;
|
ops_count += 4;
|
||||||
ret = ((opus_int32)((opus_int16)a32)) * (b32 >> 16);
|
ret = ((opus_int32)((opus_int16)a32)) * (b32 >> 16);
|
||||||
|
@ -135,7 +135,7 @@ static inline opus_int32 silk_SMULBT(opus_int32 a32, opus_int32 b32 ){
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_SMLABT
|
#undef silk_SMLABT
|
||||||
static inline opus_int32 silk_SMLABT(opus_int32 a32, opus_int32 b32, opus_int32 c32){
|
static OPUS_INLINE opus_int32 silk_SMLABT(opus_int32 a32, opus_int32 b32, opus_int32 c32){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
ret = a32 + ((opus_int32)((opus_int16)b32)) * (c32 >> 16);
|
ret = a32 + ((opus_int32)((opus_int16)b32)) * (c32 >> 16);
|
||||||
|
@ -143,7 +143,7 @@ static inline opus_int32 silk_SMLABT(opus_int32 a32, opus_int32 b32, opus_int32
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_SMULTT
|
#undef silk_SMULTT
|
||||||
static inline opus_int32 silk_SMULTT(opus_int32 a32, opus_int32 b32){
|
static OPUS_INLINE opus_int32 silk_SMULTT(opus_int32 a32, opus_int32 b32){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
ret = (a32 >> 16) * (b32 >> 16);
|
ret = (a32 >> 16) * (b32 >> 16);
|
||||||
|
@ -151,7 +151,7 @@ static inline opus_int32 silk_SMULTT(opus_int32 a32, opus_int32 b32){
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_SMLATT
|
#undef silk_SMLATT
|
||||||
static inline opus_int32 silk_SMLATT(opus_int32 a32, opus_int32 b32, opus_int32 c32){
|
static OPUS_INLINE opus_int32 silk_SMLATT(opus_int32 a32, opus_int32 b32, opus_int32 c32){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
ret = a32 + (b32 >> 16) * (c32 >> 16);
|
ret = a32 + (b32 >> 16) * (c32 >> 16);
|
||||||
|
@ -179,7 +179,7 @@ static inline opus_int32 silk_SMLATT(opus_int32 a32, opus_int32 b32, opus_int32
|
||||||
#define silk_SMLAWT_ovflw silk_SMLAWT
|
#define silk_SMLAWT_ovflw silk_SMLAWT
|
||||||
|
|
||||||
#undef silk_SMULL
|
#undef silk_SMULL
|
||||||
static inline opus_int64 silk_SMULL(opus_int32 a32, opus_int32 b32){
|
static OPUS_INLINE opus_int64 silk_SMULL(opus_int32 a32, opus_int32 b32){
|
||||||
opus_int64 ret;
|
opus_int64 ret;
|
||||||
ops_count += 8;
|
ops_count += 8;
|
||||||
ret = ((opus_int64)(a32) * /*(opus_int64)*/(b32));
|
ret = ((opus_int64)(a32) * /*(opus_int64)*/(b32));
|
||||||
|
@ -187,14 +187,14 @@ static inline opus_int64 silk_SMULL(opus_int32 a32, opus_int32 b32){
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_SMLAL
|
#undef silk_SMLAL
|
||||||
static inline opus_int64 silk_SMLAL(opus_int64 a64, opus_int32 b32, opus_int32 c32){
|
static OPUS_INLINE opus_int64 silk_SMLAL(opus_int64 a64, opus_int32 b32, opus_int32 c32){
|
||||||
opus_int64 ret;
|
opus_int64 ret;
|
||||||
ops_count += 8;
|
ops_count += 8;
|
||||||
ret = a64 + ((opus_int64)(b32) * /*(opus_int64)*/(c32));
|
ret = a64 + ((opus_int64)(b32) * /*(opus_int64)*/(c32));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#undef silk_SMLALBB
|
#undef silk_SMLALBB
|
||||||
static inline opus_int64 silk_SMLALBB(opus_int64 a64, opus_int16 b16, opus_int16 c16){
|
static OPUS_INLINE opus_int64 silk_SMLALBB(opus_int64 a64, opus_int16 b16, opus_int16 c16){
|
||||||
opus_int64 ret;
|
opus_int64 ret;
|
||||||
ops_count += 4;
|
ops_count += 4;
|
||||||
ret = a64 + ((opus_int64)(b16) * /*(opus_int64)*/(c16));
|
ret = a64 + ((opus_int64)(b16) * /*(opus_int64)*/(c16));
|
||||||
|
@ -202,7 +202,7 @@ static inline opus_int64 silk_SMLALBB(opus_int64 a64, opus_int16 b16, opus_int16
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef SigProcFIX_CLZ16
|
#undef SigProcFIX_CLZ16
|
||||||
static inline opus_int32 SigProcFIX_CLZ16(opus_int16 in16)
|
static OPUS_INLINE opus_int32 SigProcFIX_CLZ16(opus_int16 in16)
|
||||||
{
|
{
|
||||||
opus_int32 out32 = 0;
|
opus_int32 out32 = 0;
|
||||||
ops_count += 10;
|
ops_count += 10;
|
||||||
|
@ -240,7 +240,7 @@ static inline opus_int32 SigProcFIX_CLZ16(opus_int16 in16)
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef SigProcFIX_CLZ32
|
#undef SigProcFIX_CLZ32
|
||||||
static inline opus_int32 SigProcFIX_CLZ32(opus_int32 in32)
|
static OPUS_INLINE opus_int32 SigProcFIX_CLZ32(opus_int32 in32)
|
||||||
{
|
{
|
||||||
/* test highest 16 bits and convert to opus_int16 */
|
/* test highest 16 bits and convert to opus_int16 */
|
||||||
ops_count += 2;
|
ops_count += 2;
|
||||||
|
@ -252,19 +252,19 @@ static inline opus_int32 SigProcFIX_CLZ32(opus_int32 in32)
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_DIV32
|
#undef silk_DIV32
|
||||||
static inline opus_int32 silk_DIV32(opus_int32 a32, opus_int32 b32){
|
static OPUS_INLINE opus_int32 silk_DIV32(opus_int32 a32, opus_int32 b32){
|
||||||
ops_count += 64;
|
ops_count += 64;
|
||||||
return a32 / b32;
|
return a32 / b32;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_DIV32_16
|
#undef silk_DIV32_16
|
||||||
static inline opus_int32 silk_DIV32_16(opus_int32 a32, opus_int32 b32){
|
static OPUS_INLINE opus_int32 silk_DIV32_16(opus_int32 a32, opus_int32 b32){
|
||||||
ops_count += 32;
|
ops_count += 32;
|
||||||
return a32 / b32;
|
return a32 / b32;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_SAT8
|
#undef silk_SAT8
|
||||||
static inline opus_int8 silk_SAT8(opus_int64 a){
|
static OPUS_INLINE opus_int8 silk_SAT8(opus_int64 a){
|
||||||
opus_int8 tmp;
|
opus_int8 tmp;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
tmp = (opus_int8)((a) > silk_int8_MAX ? silk_int8_MAX : \
|
tmp = (opus_int8)((a) > silk_int8_MAX ? silk_int8_MAX : \
|
||||||
|
@ -273,7 +273,7 @@ static inline opus_int8 silk_SAT8(opus_int64 a){
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_SAT16
|
#undef silk_SAT16
|
||||||
static inline opus_int16 silk_SAT16(opus_int64 a){
|
static OPUS_INLINE opus_int16 silk_SAT16(opus_int64 a){
|
||||||
opus_int16 tmp;
|
opus_int16 tmp;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
tmp = (opus_int16)((a) > silk_int16_MAX ? silk_int16_MAX : \
|
tmp = (opus_int16)((a) > silk_int16_MAX ? silk_int16_MAX : \
|
||||||
|
@ -281,7 +281,7 @@ static inline opus_int16 silk_SAT16(opus_int64 a){
|
||||||
return(tmp);
|
return(tmp);
|
||||||
}
|
}
|
||||||
#undef silk_SAT32
|
#undef silk_SAT32
|
||||||
static inline opus_int32 silk_SAT32(opus_int64 a){
|
static OPUS_INLINE opus_int32 silk_SAT32(opus_int64 a){
|
||||||
opus_int32 tmp;
|
opus_int32 tmp;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
tmp = (opus_int32)((a) > silk_int32_MAX ? silk_int32_MAX : \
|
tmp = (opus_int32)((a) > silk_int32_MAX ? silk_int32_MAX : \
|
||||||
|
@ -289,7 +289,7 @@ static inline opus_int32 silk_SAT32(opus_int64 a){
|
||||||
return(tmp);
|
return(tmp);
|
||||||
}
|
}
|
||||||
#undef silk_POS_SAT32
|
#undef silk_POS_SAT32
|
||||||
static inline opus_int32 silk_POS_SAT32(opus_int64 a){
|
static OPUS_INLINE opus_int32 silk_POS_SAT32(opus_int64 a){
|
||||||
opus_int32 tmp;
|
opus_int32 tmp;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
tmp = (opus_int32)((a) > silk_int32_MAX ? silk_int32_MAX : (a));
|
tmp = (opus_int32)((a) > silk_int32_MAX ? silk_int32_MAX : (a));
|
||||||
|
@ -297,14 +297,14 @@ static inline opus_int32 silk_POS_SAT32(opus_int64 a){
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_ADD_POS_SAT8
|
#undef silk_ADD_POS_SAT8
|
||||||
static inline opus_int8 silk_ADD_POS_SAT8(opus_int64 a, opus_int64 b){
|
static OPUS_INLINE opus_int8 silk_ADD_POS_SAT8(opus_int64 a, opus_int64 b){
|
||||||
opus_int8 tmp;
|
opus_int8 tmp;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
tmp = (opus_int8)((((a)+(b)) & 0x80) ? silk_int8_MAX : ((a)+(b)));
|
tmp = (opus_int8)((((a)+(b)) & 0x80) ? silk_int8_MAX : ((a)+(b)));
|
||||||
return(tmp);
|
return(tmp);
|
||||||
}
|
}
|
||||||
#undef silk_ADD_POS_SAT16
|
#undef silk_ADD_POS_SAT16
|
||||||
static inline opus_int16 silk_ADD_POS_SAT16(opus_int64 a, opus_int64 b){
|
static OPUS_INLINE opus_int16 silk_ADD_POS_SAT16(opus_int64 a, opus_int64 b){
|
||||||
opus_int16 tmp;
|
opus_int16 tmp;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
tmp = (opus_int16)((((a)+(b)) & 0x8000) ? silk_int16_MAX : ((a)+(b)));
|
tmp = (opus_int16)((((a)+(b)) & 0x8000) ? silk_int16_MAX : ((a)+(b)));
|
||||||
|
@ -312,7 +312,7 @@ static inline opus_int16 silk_ADD_POS_SAT16(opus_int64 a, opus_int64 b){
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_ADD_POS_SAT32
|
#undef silk_ADD_POS_SAT32
|
||||||
static inline opus_int32 silk_ADD_POS_SAT32(opus_int64 a, opus_int64 b){
|
static OPUS_INLINE opus_int32 silk_ADD_POS_SAT32(opus_int64 a, opus_int64 b){
|
||||||
opus_int32 tmp;
|
opus_int32 tmp;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
tmp = (opus_int32)((((a)+(b)) & 0x80000000) ? silk_int32_MAX : ((a)+(b)));
|
tmp = (opus_int32)((((a)+(b)) & 0x80000000) ? silk_int32_MAX : ((a)+(b)));
|
||||||
|
@ -320,7 +320,7 @@ static inline opus_int32 silk_ADD_POS_SAT32(opus_int64 a, opus_int64 b){
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_ADD_POS_SAT64
|
#undef silk_ADD_POS_SAT64
|
||||||
static inline opus_int64 silk_ADD_POS_SAT64(opus_int64 a, opus_int64 b){
|
static OPUS_INLINE opus_int64 silk_ADD_POS_SAT64(opus_int64 a, opus_int64 b){
|
||||||
opus_int64 tmp;
|
opus_int64 tmp;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
tmp = ((((a)+(b)) & 0x8000000000000000LL) ? silk_int64_MAX : ((a)+(b)));
|
tmp = ((((a)+(b)) & 0x8000000000000000LL) ? silk_int64_MAX : ((a)+(b)));
|
||||||
|
@ -328,40 +328,40 @@ static inline opus_int64 silk_ADD_POS_SAT64(opus_int64 a, opus_int64 b){
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_LSHIFT8
|
#undef silk_LSHIFT8
|
||||||
static inline opus_int8 silk_LSHIFT8(opus_int8 a, opus_int32 shift){
|
static OPUS_INLINE opus_int8 silk_LSHIFT8(opus_int8 a, opus_int32 shift){
|
||||||
opus_int8 ret;
|
opus_int8 ret;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
ret = a << shift;
|
ret = a << shift;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#undef silk_LSHIFT16
|
#undef silk_LSHIFT16
|
||||||
static inline opus_int16 silk_LSHIFT16(opus_int16 a, opus_int32 shift){
|
static OPUS_INLINE opus_int16 silk_LSHIFT16(opus_int16 a, opus_int32 shift){
|
||||||
opus_int16 ret;
|
opus_int16 ret;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
ret = a << shift;
|
ret = a << shift;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#undef silk_LSHIFT32
|
#undef silk_LSHIFT32
|
||||||
static inline opus_int32 silk_LSHIFT32(opus_int32 a, opus_int32 shift){
|
static OPUS_INLINE opus_int32 silk_LSHIFT32(opus_int32 a, opus_int32 shift){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
ret = a << shift;
|
ret = a << shift;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#undef silk_LSHIFT64
|
#undef silk_LSHIFT64
|
||||||
static inline opus_int64 silk_LSHIFT64(opus_int64 a, opus_int shift){
|
static OPUS_INLINE opus_int64 silk_LSHIFT64(opus_int64 a, opus_int shift){
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
return a << shift;
|
return a << shift;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_LSHIFT_ovflw
|
#undef silk_LSHIFT_ovflw
|
||||||
static inline opus_int32 silk_LSHIFT_ovflw(opus_int32 a, opus_int32 shift){
|
static OPUS_INLINE opus_int32 silk_LSHIFT_ovflw(opus_int32 a, opus_int32 shift){
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
return a << shift;
|
return a << shift;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_LSHIFT_uint
|
#undef silk_LSHIFT_uint
|
||||||
static inline opus_uint32 silk_LSHIFT_uint(opus_uint32 a, opus_int32 shift){
|
static OPUS_INLINE opus_uint32 silk_LSHIFT_uint(opus_uint32 a, opus_int32 shift){
|
||||||
opus_uint32 ret;
|
opus_uint32 ret;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
ret = a << shift;
|
ret = a << shift;
|
||||||
|
@ -369,83 +369,83 @@ static inline opus_uint32 silk_LSHIFT_uint(opus_uint32 a, opus_int32 shift){
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_RSHIFT8
|
#undef silk_RSHIFT8
|
||||||
static inline opus_int8 silk_RSHIFT8(opus_int8 a, opus_int32 shift){
|
static OPUS_INLINE opus_int8 silk_RSHIFT8(opus_int8 a, opus_int32 shift){
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
return a >> shift;
|
return a >> shift;
|
||||||
}
|
}
|
||||||
#undef silk_RSHIFT16
|
#undef silk_RSHIFT16
|
||||||
static inline opus_int16 silk_RSHIFT16(opus_int16 a, opus_int32 shift){
|
static OPUS_INLINE opus_int16 silk_RSHIFT16(opus_int16 a, opus_int32 shift){
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
return a >> shift;
|
return a >> shift;
|
||||||
}
|
}
|
||||||
#undef silk_RSHIFT32
|
#undef silk_RSHIFT32
|
||||||
static inline opus_int32 silk_RSHIFT32(opus_int32 a, opus_int32 shift){
|
static OPUS_INLINE opus_int32 silk_RSHIFT32(opus_int32 a, opus_int32 shift){
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
return a >> shift;
|
return a >> shift;
|
||||||
}
|
}
|
||||||
#undef silk_RSHIFT64
|
#undef silk_RSHIFT64
|
||||||
static inline opus_int64 silk_RSHIFT64(opus_int64 a, opus_int64 shift){
|
static OPUS_INLINE opus_int64 silk_RSHIFT64(opus_int64 a, opus_int64 shift){
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
return a >> shift;
|
return a >> shift;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_RSHIFT_uint
|
#undef silk_RSHIFT_uint
|
||||||
static inline opus_uint32 silk_RSHIFT_uint(opus_uint32 a, opus_int32 shift){
|
static OPUS_INLINE opus_uint32 silk_RSHIFT_uint(opus_uint32 a, opus_int32 shift){
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
return a >> shift;
|
return a >> shift;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_ADD_LSHIFT
|
#undef silk_ADD_LSHIFT
|
||||||
static inline opus_int32 silk_ADD_LSHIFT(opus_int32 a, opus_int32 b, opus_int32 shift){
|
static OPUS_INLINE opus_int32 silk_ADD_LSHIFT(opus_int32 a, opus_int32 b, opus_int32 shift){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
ret = a + (b << shift);
|
ret = a + (b << shift);
|
||||||
return ret; /* shift >= 0*/
|
return ret; /* shift >= 0*/
|
||||||
}
|
}
|
||||||
#undef silk_ADD_LSHIFT32
|
#undef silk_ADD_LSHIFT32
|
||||||
static inline opus_int32 silk_ADD_LSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){
|
static OPUS_INLINE opus_int32 silk_ADD_LSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
ret = a + (b << shift);
|
ret = a + (b << shift);
|
||||||
return ret; /* shift >= 0*/
|
return ret; /* shift >= 0*/
|
||||||
}
|
}
|
||||||
#undef silk_ADD_LSHIFT_uint
|
#undef silk_ADD_LSHIFT_uint
|
||||||
static inline opus_uint32 silk_ADD_LSHIFT_uint(opus_uint32 a, opus_uint32 b, opus_int32 shift){
|
static OPUS_INLINE opus_uint32 silk_ADD_LSHIFT_uint(opus_uint32 a, opus_uint32 b, opus_int32 shift){
|
||||||
opus_uint32 ret;
|
opus_uint32 ret;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
ret = a + (b << shift);
|
ret = a + (b << shift);
|
||||||
return ret; /* shift >= 0*/
|
return ret; /* shift >= 0*/
|
||||||
}
|
}
|
||||||
#undef silk_ADD_RSHIFT
|
#undef silk_ADD_RSHIFT
|
||||||
static inline opus_int32 silk_ADD_RSHIFT(opus_int32 a, opus_int32 b, opus_int32 shift){
|
static OPUS_INLINE opus_int32 silk_ADD_RSHIFT(opus_int32 a, opus_int32 b, opus_int32 shift){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
ret = a + (b >> shift);
|
ret = a + (b >> shift);
|
||||||
return ret; /* shift > 0*/
|
return ret; /* shift > 0*/
|
||||||
}
|
}
|
||||||
#undef silk_ADD_RSHIFT32
|
#undef silk_ADD_RSHIFT32
|
||||||
static inline opus_int32 silk_ADD_RSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){
|
static OPUS_INLINE opus_int32 silk_ADD_RSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
ret = a + (b >> shift);
|
ret = a + (b >> shift);
|
||||||
return ret; /* shift > 0*/
|
return ret; /* shift > 0*/
|
||||||
}
|
}
|
||||||
#undef silk_ADD_RSHIFT_uint
|
#undef silk_ADD_RSHIFT_uint
|
||||||
static inline opus_uint32 silk_ADD_RSHIFT_uint(opus_uint32 a, opus_uint32 b, opus_int32 shift){
|
static OPUS_INLINE opus_uint32 silk_ADD_RSHIFT_uint(opus_uint32 a, opus_uint32 b, opus_int32 shift){
|
||||||
opus_uint32 ret;
|
opus_uint32 ret;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
ret = a + (b >> shift);
|
ret = a + (b >> shift);
|
||||||
return ret; /* shift > 0*/
|
return ret; /* shift > 0*/
|
||||||
}
|
}
|
||||||
#undef silk_SUB_LSHIFT32
|
#undef silk_SUB_LSHIFT32
|
||||||
static inline opus_int32 silk_SUB_LSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){
|
static OPUS_INLINE opus_int32 silk_SUB_LSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
ret = a - (b << shift);
|
ret = a - (b << shift);
|
||||||
return ret; /* shift >= 0*/
|
return ret; /* shift >= 0*/
|
||||||
}
|
}
|
||||||
#undef silk_SUB_RSHIFT32
|
#undef silk_SUB_RSHIFT32
|
||||||
static inline opus_int32 silk_SUB_RSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){
|
static OPUS_INLINE opus_int32 silk_SUB_RSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
ret = a - (b >> shift);
|
ret = a - (b >> shift);
|
||||||
|
@ -453,7 +453,7 @@ static inline opus_int32 silk_SUB_RSHIFT32(opus_int32 a, opus_int32 b, opus_int3
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_RSHIFT_ROUND
|
#undef silk_RSHIFT_ROUND
|
||||||
static inline opus_int32 silk_RSHIFT_ROUND(opus_int32 a, opus_int32 shift){
|
static OPUS_INLINE opus_int32 silk_RSHIFT_ROUND(opus_int32 a, opus_int32 shift){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ops_count += 3;
|
ops_count += 3;
|
||||||
ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1;
|
ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1;
|
||||||
|
@ -461,7 +461,7 @@ static inline opus_int32 silk_RSHIFT_ROUND(opus_int32 a, opus_int32 shift){
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_RSHIFT_ROUND64
|
#undef silk_RSHIFT_ROUND64
|
||||||
static inline opus_int64 silk_RSHIFT_ROUND64(opus_int64 a, opus_int32 shift){
|
static OPUS_INLINE opus_int64 silk_RSHIFT_ROUND64(opus_int64 a, opus_int32 shift){
|
||||||
opus_int64 ret;
|
opus_int64 ret;
|
||||||
ops_count += 6;
|
ops_count += 6;
|
||||||
ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1;
|
ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1;
|
||||||
|
@ -469,13 +469,13 @@ static inline opus_int64 silk_RSHIFT_ROUND64(opus_int64 a, opus_int32 shift){
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_abs_int64
|
#undef silk_abs_int64
|
||||||
static inline opus_int64 silk_abs_int64(opus_int64 a){
|
static OPUS_INLINE opus_int64 silk_abs_int64(opus_int64 a){
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
return (((a) > 0) ? (a) : -(a)); /* Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN*/
|
return (((a) > 0) ? (a) : -(a)); /* Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN*/
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_abs_int32
|
#undef silk_abs_int32
|
||||||
static inline opus_int32 silk_abs_int32(opus_int32 a){
|
static OPUS_INLINE opus_int32 silk_abs_int32(opus_int32 a){
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
return silk_abs(a);
|
return silk_abs(a);
|
||||||
}
|
}
|
||||||
|
@ -498,7 +498,7 @@ static silk_sign(a){
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_ADD16
|
#undef silk_ADD16
|
||||||
static inline opus_int16 silk_ADD16(opus_int16 a, opus_int16 b){
|
static OPUS_INLINE opus_int16 silk_ADD16(opus_int16 a, opus_int16 b){
|
||||||
opus_int16 ret;
|
opus_int16 ret;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
ret = a + b;
|
ret = a + b;
|
||||||
|
@ -506,7 +506,7 @@ static inline opus_int16 silk_ADD16(opus_int16 a, opus_int16 b){
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_ADD32
|
#undef silk_ADD32
|
||||||
static inline opus_int32 silk_ADD32(opus_int32 a, opus_int32 b){
|
static OPUS_INLINE opus_int32 silk_ADD32(opus_int32 a, opus_int32 b){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
ret = a + b;
|
ret = a + b;
|
||||||
|
@ -514,7 +514,7 @@ static inline opus_int32 silk_ADD32(opus_int32 a, opus_int32 b){
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_ADD64
|
#undef silk_ADD64
|
||||||
static inline opus_int64 silk_ADD64(opus_int64 a, opus_int64 b){
|
static OPUS_INLINE opus_int64 silk_ADD64(opus_int64 a, opus_int64 b){
|
||||||
opus_int64 ret;
|
opus_int64 ret;
|
||||||
ops_count += 2;
|
ops_count += 2;
|
||||||
ret = a + b;
|
ret = a + b;
|
||||||
|
@ -522,7 +522,7 @@ static inline opus_int64 silk_ADD64(opus_int64 a, opus_int64 b){
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_SUB16
|
#undef silk_SUB16
|
||||||
static inline opus_int16 silk_SUB16(opus_int16 a, opus_int16 b){
|
static OPUS_INLINE opus_int16 silk_SUB16(opus_int16 a, opus_int16 b){
|
||||||
opus_int16 ret;
|
opus_int16 ret;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
ret = a - b;
|
ret = a - b;
|
||||||
|
@ -530,7 +530,7 @@ static inline opus_int16 silk_SUB16(opus_int16 a, opus_int16 b){
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_SUB32
|
#undef silk_SUB32
|
||||||
static inline opus_int32 silk_SUB32(opus_int32 a, opus_int32 b){
|
static OPUS_INLINE opus_int32 silk_SUB32(opus_int32 a, opus_int32 b){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
ret = a - b;
|
ret = a - b;
|
||||||
|
@ -538,7 +538,7 @@ static inline opus_int32 silk_SUB32(opus_int32 a, opus_int32 b){
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_SUB64
|
#undef silk_SUB64
|
||||||
static inline opus_int64 silk_SUB64(opus_int64 a, opus_int64 b){
|
static OPUS_INLINE opus_int64 silk_SUB64(opus_int64 a, opus_int64 b){
|
||||||
opus_int64 ret;
|
opus_int64 ret;
|
||||||
ops_count += 2;
|
ops_count += 2;
|
||||||
ret = a - b;
|
ret = a - b;
|
||||||
|
@ -546,7 +546,7 @@ static inline opus_int64 silk_SUB64(opus_int64 a, opus_int64 b){
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_ADD_SAT16
|
#undef silk_ADD_SAT16
|
||||||
static inline opus_int16 silk_ADD_SAT16( opus_int16 a16, opus_int16 b16 ) {
|
static OPUS_INLINE opus_int16 silk_ADD_SAT16( opus_int16 a16, opus_int16 b16 ) {
|
||||||
opus_int16 res;
|
opus_int16 res;
|
||||||
/* Nb will be counted in AKP_add32 and silk_SAT16*/
|
/* Nb will be counted in AKP_add32 and silk_SAT16*/
|
||||||
res = (opus_int16)silk_SAT16( silk_ADD32( (opus_int32)(a16), (b16) ) );
|
res = (opus_int16)silk_SAT16( silk_ADD32( (opus_int32)(a16), (b16) ) );
|
||||||
|
@ -554,7 +554,7 @@ static inline opus_int16 silk_ADD_SAT16( opus_int16 a16, opus_int16 b16 ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_ADD_SAT32
|
#undef silk_ADD_SAT32
|
||||||
static inline opus_int32 silk_ADD_SAT32(opus_int32 a32, opus_int32 b32){
|
static OPUS_INLINE opus_int32 silk_ADD_SAT32(opus_int32 a32, opus_int32 b32){
|
||||||
opus_int32 res;
|
opus_int32 res;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
res = ((((a32) + (b32)) & 0x80000000) == 0 ? \
|
res = ((((a32) + (b32)) & 0x80000000) == 0 ? \
|
||||||
|
@ -564,7 +564,7 @@ static inline opus_int32 silk_ADD_SAT32(opus_int32 a32, opus_int32 b32){
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_ADD_SAT64
|
#undef silk_ADD_SAT64
|
||||||
static inline opus_int64 silk_ADD_SAT64( opus_int64 a64, opus_int64 b64 ) {
|
static OPUS_INLINE opus_int64 silk_ADD_SAT64( opus_int64 a64, opus_int64 b64 ) {
|
||||||
opus_int64 res;
|
opus_int64 res;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
res = ((((a64) + (b64)) & 0x8000000000000000LL) == 0 ? \
|
res = ((((a64) + (b64)) & 0x8000000000000000LL) == 0 ? \
|
||||||
|
@ -574,7 +574,7 @@ static inline opus_int64 silk_ADD_SAT64( opus_int64 a64, opus_int64 b64 ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_SUB_SAT16
|
#undef silk_SUB_SAT16
|
||||||
static inline opus_int16 silk_SUB_SAT16( opus_int16 a16, opus_int16 b16 ) {
|
static OPUS_INLINE opus_int16 silk_SUB_SAT16( opus_int16 a16, opus_int16 b16 ) {
|
||||||
opus_int16 res;
|
opus_int16 res;
|
||||||
silk_assert(0);
|
silk_assert(0);
|
||||||
/* Nb will be counted in sub-macros*/
|
/* Nb will be counted in sub-macros*/
|
||||||
|
@ -583,7 +583,7 @@ static inline opus_int16 silk_SUB_SAT16( opus_int16 a16, opus_int16 b16 ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_SUB_SAT32
|
#undef silk_SUB_SAT32
|
||||||
static inline opus_int32 silk_SUB_SAT32( opus_int32 a32, opus_int32 b32 ) {
|
static OPUS_INLINE opus_int32 silk_SUB_SAT32( opus_int32 a32, opus_int32 b32 ) {
|
||||||
opus_int32 res;
|
opus_int32 res;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
res = ((((a32)-(b32)) & 0x80000000) == 0 ? \
|
res = ((((a32)-(b32)) & 0x80000000) == 0 ? \
|
||||||
|
@ -593,7 +593,7 @@ static inline opus_int32 silk_SUB_SAT32( opus_int32 a32, opus_int32 b32 ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_SUB_SAT64
|
#undef silk_SUB_SAT64
|
||||||
static inline opus_int64 silk_SUB_SAT64( opus_int64 a64, opus_int64 b64 ) {
|
static OPUS_INLINE opus_int64 silk_SUB_SAT64( opus_int64 a64, opus_int64 b64 ) {
|
||||||
opus_int64 res;
|
opus_int64 res;
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
res = ((((a64)-(b64)) & 0x8000000000000000LL) == 0 ? \
|
res = ((((a64)-(b64)) & 0x8000000000000000LL) == 0 ? \
|
||||||
|
@ -604,7 +604,7 @@ static inline opus_int64 silk_SUB_SAT64( opus_int64 a64, opus_int64 b64 ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_SMULWW
|
#undef silk_SMULWW
|
||||||
static inline opus_int32 silk_SMULWW(opus_int32 a32, opus_int32 b32){
|
static OPUS_INLINE opus_int32 silk_SMULWW(opus_int32 a32, opus_int32 b32){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
/* Nb will be counted in sub-macros*/
|
/* Nb will be counted in sub-macros*/
|
||||||
ret = silk_MLA(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16));
|
ret = silk_MLA(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16));
|
||||||
|
@ -612,7 +612,7 @@ static inline opus_int32 silk_SMULWW(opus_int32 a32, opus_int32 b32){
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_SMLAWW
|
#undef silk_SMLAWW
|
||||||
static inline opus_int32 silk_SMLAWW(opus_int32 a32, opus_int32 b32, opus_int32 c32){
|
static OPUS_INLINE opus_int32 silk_SMLAWW(opus_int32 a32, opus_int32 b32, opus_int32 c32){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
/* Nb will be counted in sub-macros*/
|
/* Nb will be counted in sub-macros*/
|
||||||
ret = silk_MLA(silk_SMLAWB((a32), (b32), (c32)), (b32), silk_RSHIFT_ROUND((c32), 16));
|
ret = silk_MLA(silk_SMLAWB((a32), (b32), (c32)), (b32), silk_RSHIFT_ROUND((c32), 16));
|
||||||
|
@ -620,26 +620,26 @@ static inline opus_int32 silk_SMLAWW(opus_int32 a32, opus_int32 b32, opus_int32
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_min_int
|
#undef silk_min_int
|
||||||
static inline opus_int silk_min_int(opus_int a, opus_int b)
|
static OPUS_INLINE opus_int silk_min_int(opus_int a, opus_int b)
|
||||||
{
|
{
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
return (((a) < (b)) ? (a) : (b));
|
return (((a) < (b)) ? (a) : (b));
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_min_16
|
#undef silk_min_16
|
||||||
static inline opus_int16 silk_min_16(opus_int16 a, opus_int16 b)
|
static OPUS_INLINE opus_int16 silk_min_16(opus_int16 a, opus_int16 b)
|
||||||
{
|
{
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
return (((a) < (b)) ? (a) : (b));
|
return (((a) < (b)) ? (a) : (b));
|
||||||
}
|
}
|
||||||
#undef silk_min_32
|
#undef silk_min_32
|
||||||
static inline opus_int32 silk_min_32(opus_int32 a, opus_int32 b)
|
static OPUS_INLINE opus_int32 silk_min_32(opus_int32 a, opus_int32 b)
|
||||||
{
|
{
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
return (((a) < (b)) ? (a) : (b));
|
return (((a) < (b)) ? (a) : (b));
|
||||||
}
|
}
|
||||||
#undef silk_min_64
|
#undef silk_min_64
|
||||||
static inline opus_int64 silk_min_64(opus_int64 a, opus_int64 b)
|
static OPUS_INLINE opus_int64 silk_min_64(opus_int64 a, opus_int64 b)
|
||||||
{
|
{
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
return (((a) < (b)) ? (a) : (b));
|
return (((a) < (b)) ? (a) : (b));
|
||||||
|
@ -647,26 +647,26 @@ static inline opus_int64 silk_min_64(opus_int64 a, opus_int64 b)
|
||||||
|
|
||||||
/* silk_min() versions with typecast in the function call */
|
/* silk_min() versions with typecast in the function call */
|
||||||
#undef silk_max_int
|
#undef silk_max_int
|
||||||
static inline opus_int silk_max_int(opus_int a, opus_int b)
|
static OPUS_INLINE opus_int silk_max_int(opus_int a, opus_int b)
|
||||||
{
|
{
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
return (((a) > (b)) ? (a) : (b));
|
return (((a) > (b)) ? (a) : (b));
|
||||||
}
|
}
|
||||||
#undef silk_max_16
|
#undef silk_max_16
|
||||||
static inline opus_int16 silk_max_16(opus_int16 a, opus_int16 b)
|
static OPUS_INLINE opus_int16 silk_max_16(opus_int16 a, opus_int16 b)
|
||||||
{
|
{
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
return (((a) > (b)) ? (a) : (b));
|
return (((a) > (b)) ? (a) : (b));
|
||||||
}
|
}
|
||||||
#undef silk_max_32
|
#undef silk_max_32
|
||||||
static inline opus_int32 silk_max_32(opus_int32 a, opus_int32 b)
|
static OPUS_INLINE opus_int32 silk_max_32(opus_int32 a, opus_int32 b)
|
||||||
{
|
{
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
return (((a) > (b)) ? (a) : (b));
|
return (((a) > (b)) ? (a) : (b));
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_max_64
|
#undef silk_max_64
|
||||||
static inline opus_int64 silk_max_64(opus_int64 a, opus_int64 b)
|
static OPUS_INLINE opus_int64 silk_max_64(opus_int64 a, opus_int64 b)
|
||||||
{
|
{
|
||||||
ops_count += 1;
|
ops_count += 1;
|
||||||
return (((a) > (b)) ? (a) : (b));
|
return (((a) > (b)) ? (a) : (b));
|
||||||
|
@ -674,7 +674,7 @@ static inline opus_int64 silk_max_64(opus_int64 a, opus_int64 b)
|
||||||
|
|
||||||
|
|
||||||
#undef silk_LIMIT_int
|
#undef silk_LIMIT_int
|
||||||
static inline opus_int silk_LIMIT_int(opus_int a, opus_int limit1, opus_int limit2)
|
static OPUS_INLINE opus_int silk_LIMIT_int(opus_int a, opus_int limit1, opus_int limit2)
|
||||||
{
|
{
|
||||||
opus_int ret;
|
opus_int ret;
|
||||||
ops_count += 6;
|
ops_count += 6;
|
||||||
|
@ -686,7 +686,7 @@ static inline opus_int silk_LIMIT_int(opus_int a, opus_int limit1, opus_int limi
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef silk_LIMIT_16
|
#undef silk_LIMIT_16
|
||||||
static inline opus_int16 silk_LIMIT_16(opus_int16 a, opus_int16 limit1, opus_int16 limit2)
|
static OPUS_INLINE opus_int16 silk_LIMIT_16(opus_int16 a, opus_int16 limit1, opus_int16 limit2)
|
||||||
{
|
{
|
||||||
opus_int16 ret;
|
opus_int16 ret;
|
||||||
ops_count += 6;
|
ops_count += 6;
|
||||||
|
@ -699,7 +699,7 @@ return(ret);
|
||||||
|
|
||||||
|
|
||||||
#undef silk_LIMIT_32
|
#undef silk_LIMIT_32
|
||||||
static inline opus_int silk_LIMIT_32(opus_int32 a, opus_int32 limit1, opus_int32 limit2)
|
static OPUS_INLINE opus_int silk_LIMIT_32(opus_int32 a, opus_int32 limit1, opus_int32 limit2)
|
||||||
{
|
{
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ops_count += 6;
|
ops_count += 6;
|
|
@ -9,11 +9,11 @@ this list of conditions and the following disclaimer.
|
||||||
- Redistributions in binary form must reproduce the above copyright
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
documentation and/or other materials provided with the distribution.
|
||||||
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
||||||
names of specific contributors, may be used to endorse or promote
|
names of specific contributors, may be used to endorse or promote
|
||||||
products derived from this software without specific prior written
|
products derived from this software without specific prior written
|
||||||
permission.
|
permission.
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
@ -36,7 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#undef silk_ADD16
|
#undef silk_ADD16
|
||||||
#define silk_ADD16(a,b) silk_ADD16_((a), (b), __FILE__, __LINE__)
|
#define silk_ADD16(a,b) silk_ADD16_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int16 silk_ADD16_(opus_int16 a, opus_int16 b, char *file, int line){
|
static OPUS_INLINE opus_int16 silk_ADD16_(opus_int16 a, opus_int16 b, char *file, int line){
|
||||||
opus_int16 ret;
|
opus_int16 ret;
|
||||||
|
|
||||||
ret = a + b;
|
ret = a + b;
|
||||||
|
@ -52,7 +52,7 @@ static inline opus_int16 silk_ADD16_(opus_int16 a, opus_int16 b, char *file, int
|
||||||
|
|
||||||
#undef silk_ADD32
|
#undef silk_ADD32
|
||||||
#define silk_ADD32(a,b) silk_ADD32_((a), (b), __FILE__, __LINE__)
|
#define silk_ADD32(a,b) silk_ADD32_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_ADD32_(opus_int32 a, opus_int32 b, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_ADD32_(opus_int32 a, opus_int32 b, char *file, int line){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
|
|
||||||
ret = a + b;
|
ret = a + b;
|
||||||
|
@ -68,7 +68,7 @@ static inline opus_int32 silk_ADD32_(opus_int32 a, opus_int32 b, char *file, int
|
||||||
|
|
||||||
#undef silk_ADD64
|
#undef silk_ADD64
|
||||||
#define silk_ADD64(a,b) silk_ADD64_((a), (b), __FILE__, __LINE__)
|
#define silk_ADD64(a,b) silk_ADD64_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int64 silk_ADD64_(opus_int64 a, opus_int64 b, char *file, int line){
|
static OPUS_INLINE opus_int64 silk_ADD64_(opus_int64 a, opus_int64 b, char *file, int line){
|
||||||
opus_int64 ret;
|
opus_int64 ret;
|
||||||
|
|
||||||
ret = a + b;
|
ret = a + b;
|
||||||
|
@ -84,7 +84,7 @@ static inline opus_int64 silk_ADD64_(opus_int64 a, opus_int64 b, char *file, int
|
||||||
|
|
||||||
#undef silk_SUB16
|
#undef silk_SUB16
|
||||||
#define silk_SUB16(a,b) silk_SUB16_((a), (b), __FILE__, __LINE__)
|
#define silk_SUB16(a,b) silk_SUB16_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int16 silk_SUB16_(opus_int16 a, opus_int16 b, char *file, int line){
|
static OPUS_INLINE opus_int16 silk_SUB16_(opus_int16 a, opus_int16 b, char *file, int line){
|
||||||
opus_int16 ret;
|
opus_int16 ret;
|
||||||
|
|
||||||
ret = a - b;
|
ret = a - b;
|
||||||
|
@ -100,7 +100,7 @@ static inline opus_int16 silk_SUB16_(opus_int16 a, opus_int16 b, char *file, int
|
||||||
|
|
||||||
#undef silk_SUB32
|
#undef silk_SUB32
|
||||||
#define silk_SUB32(a,b) silk_SUB32_((a), (b), __FILE__, __LINE__)
|
#define silk_SUB32(a,b) silk_SUB32_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_SUB32_(opus_int32 a, opus_int32 b, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_SUB32_(opus_int32 a, opus_int32 b, char *file, int line){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
|
|
||||||
ret = a - b;
|
ret = a - b;
|
||||||
|
@ -116,7 +116,7 @@ static inline opus_int32 silk_SUB32_(opus_int32 a, opus_int32 b, char *file, int
|
||||||
|
|
||||||
#undef silk_SUB64
|
#undef silk_SUB64
|
||||||
#define silk_SUB64(a,b) silk_SUB64_((a), (b), __FILE__, __LINE__)
|
#define silk_SUB64(a,b) silk_SUB64_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int64 silk_SUB64_(opus_int64 a, opus_int64 b, char *file, int line){
|
static OPUS_INLINE opus_int64 silk_SUB64_(opus_int64 a, opus_int64 b, char *file, int line){
|
||||||
opus_int64 ret;
|
opus_int64 ret;
|
||||||
|
|
||||||
ret = a - b;
|
ret = a - b;
|
||||||
|
@ -132,7 +132,7 @@ static inline opus_int64 silk_SUB64_(opus_int64 a, opus_int64 b, char *file, int
|
||||||
|
|
||||||
#undef silk_ADD_SAT16
|
#undef silk_ADD_SAT16
|
||||||
#define silk_ADD_SAT16(a,b) silk_ADD_SAT16_((a), (b), __FILE__, __LINE__)
|
#define silk_ADD_SAT16(a,b) silk_ADD_SAT16_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int16 silk_ADD_SAT16_( opus_int16 a16, opus_int16 b16, char *file, int line) {
|
static OPUS_INLINE opus_int16 silk_ADD_SAT16_( opus_int16 a16, opus_int16 b16, char *file, int line) {
|
||||||
opus_int16 res;
|
opus_int16 res;
|
||||||
res = (opus_int16)silk_SAT16( silk_ADD32( (opus_int32)(a16), (b16) ) );
|
res = (opus_int16)silk_SAT16( silk_ADD32( (opus_int32)(a16), (b16) ) );
|
||||||
if ( res != silk_SAT16( (opus_int32)a16 + (opus_int32)b16 ) )
|
if ( res != silk_SAT16( (opus_int32)a16 + (opus_int32)b16 ) )
|
||||||
|
@ -147,7 +147,7 @@ static inline opus_int16 silk_ADD_SAT16_( opus_int16 a16, opus_int16 b16, char *
|
||||||
|
|
||||||
#undef silk_ADD_SAT32
|
#undef silk_ADD_SAT32
|
||||||
#define silk_ADD_SAT32(a,b) silk_ADD_SAT32_((a), (b), __FILE__, __LINE__)
|
#define silk_ADD_SAT32(a,b) silk_ADD_SAT32_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_ADD_SAT32_(opus_int32 a32, opus_int32 b32, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_ADD_SAT32_(opus_int32 a32, opus_int32 b32, char *file, int line){
|
||||||
opus_int32 res;
|
opus_int32 res;
|
||||||
res = ((((opus_uint32)(a32) + (opus_uint32)(b32)) & 0x80000000) == 0 ? \
|
res = ((((opus_uint32)(a32) + (opus_uint32)(b32)) & 0x80000000) == 0 ? \
|
||||||
((((a32) & (b32)) & 0x80000000) != 0 ? silk_int32_MIN : (a32)+(b32)) : \
|
((((a32) & (b32)) & 0x80000000) != 0 ? silk_int32_MIN : (a32)+(b32)) : \
|
||||||
|
@ -164,7 +164,7 @@ static inline opus_int32 silk_ADD_SAT32_(opus_int32 a32, opus_int32 b32, char *f
|
||||||
|
|
||||||
#undef silk_ADD_SAT64
|
#undef silk_ADD_SAT64
|
||||||
#define silk_ADD_SAT64(a,b) silk_ADD_SAT64_((a), (b), __FILE__, __LINE__)
|
#define silk_ADD_SAT64(a,b) silk_ADD_SAT64_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int64 silk_ADD_SAT64_( opus_int64 a64, opus_int64 b64, char *file, int line) {
|
static OPUS_INLINE opus_int64 silk_ADD_SAT64_( opus_int64 a64, opus_int64 b64, char *file, int line) {
|
||||||
opus_int64 res;
|
opus_int64 res;
|
||||||
int fail = 0;
|
int fail = 0;
|
||||||
res = ((((a64) + (b64)) & 0x8000000000000000LL) == 0 ? \
|
res = ((((a64) + (b64)) & 0x8000000000000000LL) == 0 ? \
|
||||||
|
@ -193,7 +193,7 @@ static inline opus_int64 silk_ADD_SAT64_( opus_int64 a64, opus_int64 b64, char *
|
||||||
|
|
||||||
#undef silk_SUB_SAT16
|
#undef silk_SUB_SAT16
|
||||||
#define silk_SUB_SAT16(a,b) silk_SUB_SAT16_((a), (b), __FILE__, __LINE__)
|
#define silk_SUB_SAT16(a,b) silk_SUB_SAT16_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int16 silk_SUB_SAT16_( opus_int16 a16, opus_int16 b16, char *file, int line ) {
|
static OPUS_INLINE opus_int16 silk_SUB_SAT16_( opus_int16 a16, opus_int16 b16, char *file, int line ) {
|
||||||
opus_int16 res;
|
opus_int16 res;
|
||||||
res = (opus_int16)silk_SAT16( silk_SUB32( (opus_int32)(a16), (b16) ) );
|
res = (opus_int16)silk_SAT16( silk_SUB32( (opus_int32)(a16), (b16) ) );
|
||||||
if ( res != silk_SAT16( (opus_int32)a16 - (opus_int32)b16 ) )
|
if ( res != silk_SAT16( (opus_int32)a16 - (opus_int32)b16 ) )
|
||||||
|
@ -208,7 +208,7 @@ static inline opus_int16 silk_SUB_SAT16_( opus_int16 a16, opus_int16 b16, char *
|
||||||
|
|
||||||
#undef silk_SUB_SAT32
|
#undef silk_SUB_SAT32
|
||||||
#define silk_SUB_SAT32(a,b) silk_SUB_SAT32_((a), (b), __FILE__, __LINE__)
|
#define silk_SUB_SAT32(a,b) silk_SUB_SAT32_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_SUB_SAT32_( opus_int32 a32, opus_int32 b32, char *file, int line ) {
|
static OPUS_INLINE opus_int32 silk_SUB_SAT32_( opus_int32 a32, opus_int32 b32, char *file, int line ) {
|
||||||
opus_int32 res;
|
opus_int32 res;
|
||||||
res = ((((opus_uint32)(a32)-(opus_uint32)(b32)) & 0x80000000) == 0 ? \
|
res = ((((opus_uint32)(a32)-(opus_uint32)(b32)) & 0x80000000) == 0 ? \
|
||||||
(( (a32) & ((b32)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a32)-(b32)) : \
|
(( (a32) & ((b32)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a32)-(b32)) : \
|
||||||
|
@ -225,7 +225,7 @@ static inline opus_int32 silk_SUB_SAT32_( opus_int32 a32, opus_int32 b32, char *
|
||||||
|
|
||||||
#undef silk_SUB_SAT64
|
#undef silk_SUB_SAT64
|
||||||
#define silk_SUB_SAT64(a,b) silk_SUB_SAT64_((a), (b), __FILE__, __LINE__)
|
#define silk_SUB_SAT64(a,b) silk_SUB_SAT64_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int64 silk_SUB_SAT64_( opus_int64 a64, opus_int64 b64, char *file, int line ) {
|
static OPUS_INLINE opus_int64 silk_SUB_SAT64_( opus_int64 a64, opus_int64 b64, char *file, int line ) {
|
||||||
opus_int64 res;
|
opus_int64 res;
|
||||||
int fail = 0;
|
int fail = 0;
|
||||||
res = ((((a64)-(b64)) & 0x8000000000000000LL) == 0 ? \
|
res = ((((a64)-(b64)) & 0x8000000000000000LL) == 0 ? \
|
||||||
|
@ -254,7 +254,7 @@ static inline opus_int64 silk_SUB_SAT64_( opus_int64 a64, opus_int64 b64, char *
|
||||||
|
|
||||||
#undef silk_MUL
|
#undef silk_MUL
|
||||||
#define silk_MUL(a,b) silk_MUL_((a), (b), __FILE__, __LINE__)
|
#define silk_MUL(a,b) silk_MUL_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_MUL_(opus_int32 a32, opus_int32 b32, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_MUL_(opus_int32 a32, opus_int32 b32, char *file, int line){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
opus_int64 ret64;
|
opus_int64 ret64;
|
||||||
ret = a32 * b32;
|
ret = a32 * b32;
|
||||||
|
@ -271,7 +271,7 @@ static inline opus_int32 silk_MUL_(opus_int32 a32, opus_int32 b32, char *file, i
|
||||||
|
|
||||||
#undef silk_MUL_uint
|
#undef silk_MUL_uint
|
||||||
#define silk_MUL_uint(a,b) silk_MUL_uint_((a), (b), __FILE__, __LINE__)
|
#define silk_MUL_uint(a,b) silk_MUL_uint_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_uint32 silk_MUL_uint_(opus_uint32 a32, opus_uint32 b32, char *file, int line){
|
static OPUS_INLINE opus_uint32 silk_MUL_uint_(opus_uint32 a32, opus_uint32 b32, char *file, int line){
|
||||||
opus_uint32 ret;
|
opus_uint32 ret;
|
||||||
ret = a32 * b32;
|
ret = a32 * b32;
|
||||||
if ( (opus_uint64)ret != (opus_uint64)a32 * (opus_uint64)b32 )
|
if ( (opus_uint64)ret != (opus_uint64)a32 * (opus_uint64)b32 )
|
||||||
|
@ -286,7 +286,7 @@ static inline opus_uint32 silk_MUL_uint_(opus_uint32 a32, opus_uint32 b32, char
|
||||||
|
|
||||||
#undef silk_MLA
|
#undef silk_MLA
|
||||||
#define silk_MLA(a,b,c) silk_MLA_((a), (b), (c), __FILE__, __LINE__)
|
#define silk_MLA(a,b,c) silk_MLA_((a), (b), (c), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_MLA_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_MLA_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ret = a32 + b32 * c32;
|
ret = a32 + b32 * c32;
|
||||||
if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (opus_int64)c32 )
|
if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (opus_int64)c32 )
|
||||||
|
@ -301,7 +301,7 @@ static inline opus_int32 silk_MLA_(opus_int32 a32, opus_int32 b32, opus_int32 c3
|
||||||
|
|
||||||
#undef silk_MLA_uint
|
#undef silk_MLA_uint
|
||||||
#define silk_MLA_uint(a,b,c) silk_MLA_uint_((a), (b), (c), __FILE__, __LINE__)
|
#define silk_MLA_uint(a,b,c) silk_MLA_uint_((a), (b), (c), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_MLA_uint_(opus_uint32 a32, opus_uint32 b32, opus_uint32 c32, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_MLA_uint_(opus_uint32 a32, opus_uint32 b32, opus_uint32 c32, char *file, int line){
|
||||||
opus_uint32 ret;
|
opus_uint32 ret;
|
||||||
ret = a32 + b32 * c32;
|
ret = a32 + b32 * c32;
|
||||||
if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (opus_int64)c32 )
|
if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (opus_int64)c32 )
|
||||||
|
@ -316,7 +316,7 @@ static inline opus_int32 silk_MLA_uint_(opus_uint32 a32, opus_uint32 b32, opus_u
|
||||||
|
|
||||||
#undef silk_SMULWB
|
#undef silk_SMULWB
|
||||||
#define silk_SMULWB(a,b) silk_SMULWB_((a), (b), __FILE__, __LINE__)
|
#define silk_SMULWB(a,b) silk_SMULWB_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_SMULWB_(opus_int32 a32, opus_int32 b32, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_SMULWB_(opus_int32 a32, opus_int32 b32, char *file, int line){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ret = (a32 >> 16) * (opus_int32)((opus_int16)b32) + (((a32 & 0x0000FFFF) * (opus_int32)((opus_int16)b32)) >> 16);
|
ret = (a32 >> 16) * (opus_int32)((opus_int16)b32) + (((a32 & 0x0000FFFF) * (opus_int32)((opus_int16)b32)) >> 16);
|
||||||
if ( (opus_int64)ret != ((opus_int64)a32 * (opus_int16)b32) >> 16 )
|
if ( (opus_int64)ret != ((opus_int64)a32 * (opus_int16)b32) >> 16 )
|
||||||
|
@ -331,7 +331,7 @@ static inline opus_int32 silk_SMULWB_(opus_int32 a32, opus_int32 b32, char *file
|
||||||
|
|
||||||
#undef silk_SMLAWB
|
#undef silk_SMLAWB
|
||||||
#define silk_SMLAWB(a,b,c) silk_SMLAWB_((a), (b), (c), __FILE__, __LINE__)
|
#define silk_SMLAWB(a,b,c) silk_SMLAWB_((a), (b), (c), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_SMLAWB_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_SMLAWB_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ret = silk_ADD32( a32, silk_SMULWB( b32, c32 ) );
|
ret = silk_ADD32( a32, silk_SMULWB( b32, c32 ) );
|
||||||
if ( silk_ADD32( a32, silk_SMULWB( b32, c32 ) ) != silk_ADD_SAT32( a32, silk_SMULWB( b32, c32 ) ) )
|
if ( silk_ADD32( a32, silk_SMULWB( b32, c32 ) ) != silk_ADD_SAT32( a32, silk_SMULWB( b32, c32 ) ) )
|
||||||
|
@ -346,7 +346,7 @@ static inline opus_int32 silk_SMLAWB_(opus_int32 a32, opus_int32 b32, opus_int32
|
||||||
|
|
||||||
#undef silk_SMULWT
|
#undef silk_SMULWT
|
||||||
#define silk_SMULWT(a,b) silk_SMULWT_((a), (b), __FILE__, __LINE__)
|
#define silk_SMULWT(a,b) silk_SMULWT_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_SMULWT_(opus_int32 a32, opus_int32 b32, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_SMULWT_(opus_int32 a32, opus_int32 b32, char *file, int line){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ret = (a32 >> 16) * (b32 >> 16) + (((a32 & 0x0000FFFF) * (b32 >> 16)) >> 16);
|
ret = (a32 >> 16) * (b32 >> 16) + (((a32 & 0x0000FFFF) * (b32 >> 16)) >> 16);
|
||||||
if ( (opus_int64)ret != ((opus_int64)a32 * (b32 >> 16)) >> 16 )
|
if ( (opus_int64)ret != ((opus_int64)a32 * (b32 >> 16)) >> 16 )
|
||||||
|
@ -361,7 +361,7 @@ static inline opus_int32 silk_SMULWT_(opus_int32 a32, opus_int32 b32, char *file
|
||||||
|
|
||||||
#undef silk_SMLAWT
|
#undef silk_SMLAWT
|
||||||
#define silk_SMLAWT(a,b,c) silk_SMLAWT_((a), (b), (c), __FILE__, __LINE__)
|
#define silk_SMLAWT(a,b,c) silk_SMLAWT_((a), (b), (c), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_SMLAWT_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_SMLAWT_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ret = a32 + ((b32 >> 16) * (c32 >> 16)) + (((b32 & 0x0000FFFF) * ((c32 >> 16)) >> 16));
|
ret = a32 + ((b32 >> 16) * (c32 >> 16)) + (((b32 & 0x0000FFFF) * ((c32 >> 16)) >> 16));
|
||||||
if ( (opus_int64)ret != (opus_int64)a32 + (((opus_int64)b32 * (c32 >> 16)) >> 16) )
|
if ( (opus_int64)ret != (opus_int64)a32 + (((opus_int64)b32 * (c32 >> 16)) >> 16) )
|
||||||
|
@ -376,7 +376,7 @@ static inline opus_int32 silk_SMLAWT_(opus_int32 a32, opus_int32 b32, opus_int32
|
||||||
|
|
||||||
#undef silk_SMULL
|
#undef silk_SMULL
|
||||||
#define silk_SMULL(a,b) silk_SMULL_((a), (b), __FILE__, __LINE__)
|
#define silk_SMULL(a,b) silk_SMULL_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int64 silk_SMULL_(opus_int64 a64, opus_int64 b64, char *file, int line){
|
static OPUS_INLINE opus_int64 silk_SMULL_(opus_int64 a64, opus_int64 b64, char *file, int line){
|
||||||
opus_int64 ret64;
|
opus_int64 ret64;
|
||||||
int fail = 0;
|
int fail = 0;
|
||||||
ret64 = a64 * b64;
|
ret64 = a64 * b64;
|
||||||
|
@ -398,7 +398,7 @@ static inline opus_int64 silk_SMULL_(opus_int64 a64, opus_int64 b64, char *file,
|
||||||
/* no checking needed for silk_SMULBB */
|
/* no checking needed for silk_SMULBB */
|
||||||
#undef silk_SMLABB
|
#undef silk_SMLABB
|
||||||
#define silk_SMLABB(a,b,c) silk_SMLABB_((a), (b), (c), __FILE__, __LINE__)
|
#define silk_SMLABB(a,b,c) silk_SMLABB_((a), (b), (c), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_SMLABB_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_SMLABB_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ret = a32 + (opus_int32)((opus_int16)b32) * (opus_int32)((opus_int16)c32);
|
ret = a32 + (opus_int32)((opus_int16)b32) * (opus_int32)((opus_int16)c32);
|
||||||
if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (opus_int16)c32 )
|
if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (opus_int16)c32 )
|
||||||
|
@ -414,7 +414,7 @@ static inline opus_int32 silk_SMLABB_(opus_int32 a32, opus_int32 b32, opus_int32
|
||||||
/* no checking needed for silk_SMULBT */
|
/* no checking needed for silk_SMULBT */
|
||||||
#undef silk_SMLABT
|
#undef silk_SMLABT
|
||||||
#define silk_SMLABT(a,b,c) silk_SMLABT_((a), (b), (c), __FILE__, __LINE__)
|
#define silk_SMLABT(a,b,c) silk_SMLABT_((a), (b), (c), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_SMLABT_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_SMLABT_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ret = a32 + ((opus_int32)((opus_int16)b32)) * (c32 >> 16);
|
ret = a32 + ((opus_int32)((opus_int16)b32)) * (c32 >> 16);
|
||||||
if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (c32 >> 16) )
|
if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (c32 >> 16) )
|
||||||
|
@ -430,7 +430,7 @@ static inline opus_int32 silk_SMLABT_(opus_int32 a32, opus_int32 b32, opus_int32
|
||||||
/* no checking needed for silk_SMULTT */
|
/* no checking needed for silk_SMULTT */
|
||||||
#undef silk_SMLATT
|
#undef silk_SMLATT
|
||||||
#define silk_SMLATT(a,b,c) silk_SMLATT_((a), (b), (c), __FILE__, __LINE__)
|
#define silk_SMLATT(a,b,c) silk_SMLATT_((a), (b), (c), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_SMLATT_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_SMLATT_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ret = a32 + (b32 >> 16) * (c32 >> 16);
|
ret = a32 + (b32 >> 16) * (c32 >> 16);
|
||||||
if ( (opus_int64)ret != (opus_int64)a32 + (b32 >> 16) * (c32 >> 16) )
|
if ( (opus_int64)ret != (opus_int64)a32 + (b32 >> 16) * (c32 >> 16) )
|
||||||
|
@ -445,7 +445,7 @@ static inline opus_int32 silk_SMLATT_(opus_int32 a32, opus_int32 b32, opus_int32
|
||||||
|
|
||||||
#undef silk_SMULWW
|
#undef silk_SMULWW
|
||||||
#define silk_SMULWW(a,b) silk_SMULWW_((a), (b), __FILE__, __LINE__)
|
#define silk_SMULWW(a,b) silk_SMULWW_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_SMULWW_(opus_int32 a32, opus_int32 b32, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_SMULWW_(opus_int32 a32, opus_int32 b32, char *file, int line){
|
||||||
opus_int32 ret, tmp1, tmp2;
|
opus_int32 ret, tmp1, tmp2;
|
||||||
opus_int64 ret64;
|
opus_int64 ret64;
|
||||||
int fail = 0;
|
int fail = 0;
|
||||||
|
@ -476,7 +476,7 @@ static inline opus_int32 silk_SMULWW_(opus_int32 a32, opus_int32 b32, char *file
|
||||||
|
|
||||||
#undef silk_SMLAWW
|
#undef silk_SMLAWW
|
||||||
#define silk_SMLAWW(a,b,c) silk_SMLAWW_((a), (b), (c), __FILE__, __LINE__)
|
#define silk_SMLAWW(a,b,c) silk_SMLAWW_((a), (b), (c), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_SMLAWW_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_SMLAWW_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){
|
||||||
opus_int32 ret, tmp;
|
opus_int32 ret, tmp;
|
||||||
|
|
||||||
tmp = silk_SMULWW( b32, c32 );
|
tmp = silk_SMULWW( b32, c32 );
|
||||||
|
@ -505,7 +505,7 @@ static inline opus_int32 silk_SMLAWW_(opus_int32 a32, opus_int32 b32, opus_int32
|
||||||
|
|
||||||
#undef silk_DIV32
|
#undef silk_DIV32
|
||||||
#define silk_DIV32(a,b) silk_DIV32_((a), (b), __FILE__, __LINE__)
|
#define silk_DIV32(a,b) silk_DIV32_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_DIV32_(opus_int32 a32, opus_int32 b32, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_DIV32_(opus_int32 a32, opus_int32 b32, char *file, int line){
|
||||||
if ( b32 == 0 )
|
if ( b32 == 0 )
|
||||||
{
|
{
|
||||||
fprintf (stderr, "silk_DIV32(%d, %d) in %s: line %d\n", a32, b32, file, line);
|
fprintf (stderr, "silk_DIV32(%d, %d) in %s: line %d\n", a32, b32, file, line);
|
||||||
|
@ -518,7 +518,7 @@ static inline opus_int32 silk_DIV32_(opus_int32 a32, opus_int32 b32, char *file,
|
||||||
|
|
||||||
#undef silk_DIV32_16
|
#undef silk_DIV32_16
|
||||||
#define silk_DIV32_16(a,b) silk_DIV32_16_((a), (b), __FILE__, __LINE__)
|
#define silk_DIV32_16(a,b) silk_DIV32_16_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_DIV32_16_(opus_int32 a32, opus_int32 b32, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_DIV32_16_(opus_int32 a32, opus_int32 b32, char *file, int line){
|
||||||
int fail = 0;
|
int fail = 0;
|
||||||
fail |= b32 == 0;
|
fail |= b32 == 0;
|
||||||
fail |= b32 > silk_int16_MAX;
|
fail |= b32 > silk_int16_MAX;
|
||||||
|
@ -544,7 +544,7 @@ static inline opus_int32 silk_DIV32_16_(opus_int32 a32, opus_int32 b32, char *fi
|
||||||
|
|
||||||
#undef silk_LSHIFT8
|
#undef silk_LSHIFT8
|
||||||
#define silk_LSHIFT8(a,b) silk_LSHIFT8_((a), (b), __FILE__, __LINE__)
|
#define silk_LSHIFT8(a,b) silk_LSHIFT8_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int8 silk_LSHIFT8_(opus_int8 a, opus_int32 shift, char *file, int line){
|
static OPUS_INLINE opus_int8 silk_LSHIFT8_(opus_int8 a, opus_int32 shift, char *file, int line){
|
||||||
opus_int8 ret;
|
opus_int8 ret;
|
||||||
int fail = 0;
|
int fail = 0;
|
||||||
ret = a << shift;
|
ret = a << shift;
|
||||||
|
@ -563,7 +563,7 @@ static inline opus_int8 silk_LSHIFT8_(opus_int8 a, opus_int32 shift, char *file,
|
||||||
|
|
||||||
#undef silk_LSHIFT16
|
#undef silk_LSHIFT16
|
||||||
#define silk_LSHIFT16(a,b) silk_LSHIFT16_((a), (b), __FILE__, __LINE__)
|
#define silk_LSHIFT16(a,b) silk_LSHIFT16_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int16 silk_LSHIFT16_(opus_int16 a, opus_int32 shift, char *file, int line){
|
static OPUS_INLINE opus_int16 silk_LSHIFT16_(opus_int16 a, opus_int32 shift, char *file, int line){
|
||||||
opus_int16 ret;
|
opus_int16 ret;
|
||||||
int fail = 0;
|
int fail = 0;
|
||||||
ret = a << shift;
|
ret = a << shift;
|
||||||
|
@ -582,7 +582,7 @@ static inline opus_int16 silk_LSHIFT16_(opus_int16 a, opus_int32 shift, char *fi
|
||||||
|
|
||||||
#undef silk_LSHIFT32
|
#undef silk_LSHIFT32
|
||||||
#define silk_LSHIFT32(a,b) silk_LSHIFT32_((a), (b), __FILE__, __LINE__)
|
#define silk_LSHIFT32(a,b) silk_LSHIFT32_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_LSHIFT32_(opus_int32 a, opus_int32 shift, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_LSHIFT32_(opus_int32 a, opus_int32 shift, char *file, int line){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
int fail = 0;
|
int fail = 0;
|
||||||
ret = a << shift;
|
ret = a << shift;
|
||||||
|
@ -601,7 +601,7 @@ static inline opus_int32 silk_LSHIFT32_(opus_int32 a, opus_int32 shift, char *fi
|
||||||
|
|
||||||
#undef silk_LSHIFT64
|
#undef silk_LSHIFT64
|
||||||
#define silk_LSHIFT64(a,b) silk_LSHIFT64_((a), (b), __FILE__, __LINE__)
|
#define silk_LSHIFT64(a,b) silk_LSHIFT64_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int64 silk_LSHIFT64_(opus_int64 a, opus_int shift, char *file, int line){
|
static OPUS_INLINE opus_int64 silk_LSHIFT64_(opus_int64 a, opus_int shift, char *file, int line){
|
||||||
opus_int64 ret;
|
opus_int64 ret;
|
||||||
int fail = 0;
|
int fail = 0;
|
||||||
ret = a << shift;
|
ret = a << shift;
|
||||||
|
@ -620,7 +620,7 @@ static inline opus_int64 silk_LSHIFT64_(opus_int64 a, opus_int shift, char *file
|
||||||
|
|
||||||
#undef silk_LSHIFT_ovflw
|
#undef silk_LSHIFT_ovflw
|
||||||
#define silk_LSHIFT_ovflw(a,b) silk_LSHIFT_ovflw_((a), (b), __FILE__, __LINE__)
|
#define silk_LSHIFT_ovflw(a,b) silk_LSHIFT_ovflw_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_LSHIFT_ovflw_(opus_int32 a, opus_int32 shift, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_LSHIFT_ovflw_(opus_int32 a, opus_int32 shift, char *file, int line){
|
||||||
if ( (shift < 0) || (shift >= 32) ) /* no check for overflow */
|
if ( (shift < 0) || (shift >= 32) ) /* no check for overflow */
|
||||||
{
|
{
|
||||||
fprintf (stderr, "silk_LSHIFT_ovflw(%d, %d) in %s: line %d\n", a, shift, file, line);
|
fprintf (stderr, "silk_LSHIFT_ovflw(%d, %d) in %s: line %d\n", a, shift, file, line);
|
||||||
|
@ -633,7 +633,7 @@ static inline opus_int32 silk_LSHIFT_ovflw_(opus_int32 a, opus_int32 shift, char
|
||||||
|
|
||||||
#undef silk_LSHIFT_uint
|
#undef silk_LSHIFT_uint
|
||||||
#define silk_LSHIFT_uint(a,b) silk_LSHIFT_uint_((a), (b), __FILE__, __LINE__)
|
#define silk_LSHIFT_uint(a,b) silk_LSHIFT_uint_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_uint32 silk_LSHIFT_uint_(opus_uint32 a, opus_int32 shift, char *file, int line){
|
static OPUS_INLINE opus_uint32 silk_LSHIFT_uint_(opus_uint32 a, opus_int32 shift, char *file, int line){
|
||||||
opus_uint32 ret;
|
opus_uint32 ret;
|
||||||
ret = a << shift;
|
ret = a << shift;
|
||||||
if ( (shift < 0) || ((opus_int64)ret != ((opus_int64)a) << shift))
|
if ( (shift < 0) || ((opus_int64)ret != ((opus_int64)a) << shift))
|
||||||
|
@ -648,7 +648,7 @@ static inline opus_uint32 silk_LSHIFT_uint_(opus_uint32 a, opus_int32 shift, cha
|
||||||
|
|
||||||
#undef silk_RSHIFT8
|
#undef silk_RSHIFT8
|
||||||
#define silk_RSHITF8(a,b) silk_RSHIFT8_((a), (b), __FILE__, __LINE__)
|
#define silk_RSHITF8(a,b) silk_RSHIFT8_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int8 silk_RSHIFT8_(opus_int8 a, opus_int32 shift, char *file, int line){
|
static OPUS_INLINE opus_int8 silk_RSHIFT8_(opus_int8 a, opus_int32 shift, char *file, int line){
|
||||||
if ( (shift < 0) || (shift>=8) )
|
if ( (shift < 0) || (shift>=8) )
|
||||||
{
|
{
|
||||||
fprintf (stderr, "silk_RSHITF8(%d, %d) in %s: line %d\n", a, shift, file, line);
|
fprintf (stderr, "silk_RSHITF8(%d, %d) in %s: line %d\n", a, shift, file, line);
|
||||||
|
@ -661,7 +661,7 @@ static inline opus_int8 silk_RSHIFT8_(opus_int8 a, opus_int32 shift, char *file,
|
||||||
|
|
||||||
#undef silk_RSHIFT16
|
#undef silk_RSHIFT16
|
||||||
#define silk_RSHITF16(a,b) silk_RSHIFT16_((a), (b), __FILE__, __LINE__)
|
#define silk_RSHITF16(a,b) silk_RSHIFT16_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int16 silk_RSHIFT16_(opus_int16 a, opus_int32 shift, char *file, int line){
|
static OPUS_INLINE opus_int16 silk_RSHIFT16_(opus_int16 a, opus_int32 shift, char *file, int line){
|
||||||
if ( (shift < 0) || (shift>=16) )
|
if ( (shift < 0) || (shift>=16) )
|
||||||
{
|
{
|
||||||
fprintf (stderr, "silk_RSHITF16(%d, %d) in %s: line %d\n", a, shift, file, line);
|
fprintf (stderr, "silk_RSHITF16(%d, %d) in %s: line %d\n", a, shift, file, line);
|
||||||
|
@ -674,7 +674,7 @@ static inline opus_int16 silk_RSHIFT16_(opus_int16 a, opus_int32 shift, char *fi
|
||||||
|
|
||||||
#undef silk_RSHIFT32
|
#undef silk_RSHIFT32
|
||||||
#define silk_RSHIFT32(a,b) silk_RSHIFT32_((a), (b), __FILE__, __LINE__)
|
#define silk_RSHIFT32(a,b) silk_RSHIFT32_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_RSHIFT32_(opus_int32 a, opus_int32 shift, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_RSHIFT32_(opus_int32 a, opus_int32 shift, char *file, int line){
|
||||||
if ( (shift < 0) || (shift>=32) )
|
if ( (shift < 0) || (shift>=32) )
|
||||||
{
|
{
|
||||||
fprintf (stderr, "silk_RSHITF32(%d, %d) in %s: line %d\n", a, shift, file, line);
|
fprintf (stderr, "silk_RSHITF32(%d, %d) in %s: line %d\n", a, shift, file, line);
|
||||||
|
@ -687,7 +687,7 @@ static inline opus_int32 silk_RSHIFT32_(opus_int32 a, opus_int32 shift, char *fi
|
||||||
|
|
||||||
#undef silk_RSHIFT64
|
#undef silk_RSHIFT64
|
||||||
#define silk_RSHIFT64(a,b) silk_RSHIFT64_((a), (b), __FILE__, __LINE__)
|
#define silk_RSHIFT64(a,b) silk_RSHIFT64_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int64 silk_RSHIFT64_(opus_int64 a, opus_int64 shift, char *file, int line){
|
static OPUS_INLINE opus_int64 silk_RSHIFT64_(opus_int64 a, opus_int64 shift, char *file, int line){
|
||||||
if ( (shift < 0) || (shift>=64) )
|
if ( (shift < 0) || (shift>=64) )
|
||||||
{
|
{
|
||||||
fprintf (stderr, "silk_RSHITF64(%lld, %lld) in %s: line %d\n", (long long)a, (long long)shift, file, line);
|
fprintf (stderr, "silk_RSHITF64(%lld, %lld) in %s: line %d\n", (long long)a, (long long)shift, file, line);
|
||||||
|
@ -700,7 +700,7 @@ static inline opus_int64 silk_RSHIFT64_(opus_int64 a, opus_int64 shift, char *fi
|
||||||
|
|
||||||
#undef silk_RSHIFT_uint
|
#undef silk_RSHIFT_uint
|
||||||
#define silk_RSHIFT_uint(a,b) silk_RSHIFT_uint_((a), (b), __FILE__, __LINE__)
|
#define silk_RSHIFT_uint(a,b) silk_RSHIFT_uint_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_uint32 silk_RSHIFT_uint_(opus_uint32 a, opus_int32 shift, char *file, int line){
|
static OPUS_INLINE opus_uint32 silk_RSHIFT_uint_(opus_uint32 a, opus_int32 shift, char *file, int line){
|
||||||
if ( (shift < 0) || (shift>32) )
|
if ( (shift < 0) || (shift>32) )
|
||||||
{
|
{
|
||||||
fprintf (stderr, "silk_RSHIFT_uint(%u, %d) in %s: line %d\n", a, shift, file, line);
|
fprintf (stderr, "silk_RSHIFT_uint(%u, %d) in %s: line %d\n", a, shift, file, line);
|
||||||
|
@ -713,7 +713,7 @@ static inline opus_uint32 silk_RSHIFT_uint_(opus_uint32 a, opus_int32 shift, cha
|
||||||
|
|
||||||
#undef silk_ADD_LSHIFT
|
#undef silk_ADD_LSHIFT
|
||||||
#define silk_ADD_LSHIFT(a,b,c) silk_ADD_LSHIFT_((a), (b), (c), __FILE__, __LINE__)
|
#define silk_ADD_LSHIFT(a,b,c) silk_ADD_LSHIFT_((a), (b), (c), __FILE__, __LINE__)
|
||||||
static inline int silk_ADD_LSHIFT_(int a, int b, int shift, char *file, int line){
|
static OPUS_INLINE int silk_ADD_LSHIFT_(int a, int b, int shift, char *file, int line){
|
||||||
opus_int16 ret;
|
opus_int16 ret;
|
||||||
ret = a + (b << shift);
|
ret = a + (b << shift);
|
||||||
if ( (shift < 0) || (shift>15) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) )
|
if ( (shift < 0) || (shift>15) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) )
|
||||||
|
@ -728,7 +728,7 @@ static inline int silk_ADD_LSHIFT_(int a, int b, int shift, char *file, int line
|
||||||
|
|
||||||
#undef silk_ADD_LSHIFT32
|
#undef silk_ADD_LSHIFT32
|
||||||
#define silk_ADD_LSHIFT32(a,b,c) silk_ADD_LSHIFT32_((a), (b), (c), __FILE__, __LINE__)
|
#define silk_ADD_LSHIFT32(a,b,c) silk_ADD_LSHIFT32_((a), (b), (c), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_ADD_LSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_ADD_LSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ret = a + (b << shift);
|
ret = a + (b << shift);
|
||||||
if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) )
|
if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) )
|
||||||
|
@ -743,7 +743,7 @@ static inline opus_int32 silk_ADD_LSHIFT32_(opus_int32 a, opus_int32 b, opus_int
|
||||||
|
|
||||||
#undef silk_ADD_LSHIFT_uint
|
#undef silk_ADD_LSHIFT_uint
|
||||||
#define silk_ADD_LSHIFT_uint(a,b,c) silk_ADD_LSHIFT_uint_((a), (b), (c), __FILE__, __LINE__)
|
#define silk_ADD_LSHIFT_uint(a,b,c) silk_ADD_LSHIFT_uint_((a), (b), (c), __FILE__, __LINE__)
|
||||||
static inline opus_uint32 silk_ADD_LSHIFT_uint_(opus_uint32 a, opus_uint32 b, opus_int32 shift, char *file, int line){
|
static OPUS_INLINE opus_uint32 silk_ADD_LSHIFT_uint_(opus_uint32 a, opus_uint32 b, opus_int32 shift, char *file, int line){
|
||||||
opus_uint32 ret;
|
opus_uint32 ret;
|
||||||
ret = a + (b << shift);
|
ret = a + (b << shift);
|
||||||
if ( (shift < 0) || (shift>32) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) )
|
if ( (shift < 0) || (shift>32) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) )
|
||||||
|
@ -758,7 +758,7 @@ static inline opus_uint32 silk_ADD_LSHIFT_uint_(opus_uint32 a, opus_uint32 b, op
|
||||||
|
|
||||||
#undef silk_ADD_RSHIFT
|
#undef silk_ADD_RSHIFT
|
||||||
#define silk_ADD_RSHIFT(a,b,c) silk_ADD_RSHIFT_((a), (b), (c), __FILE__, __LINE__)
|
#define silk_ADD_RSHIFT(a,b,c) silk_ADD_RSHIFT_((a), (b), (c), __FILE__, __LINE__)
|
||||||
static inline int silk_ADD_RSHIFT_(int a, int b, int shift, char *file, int line){
|
static OPUS_INLINE int silk_ADD_RSHIFT_(int a, int b, int shift, char *file, int line){
|
||||||
opus_int16 ret;
|
opus_int16 ret;
|
||||||
ret = a + (b >> shift);
|
ret = a + (b >> shift);
|
||||||
if ( (shift < 0) || (shift>15) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) )
|
if ( (shift < 0) || (shift>15) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) )
|
||||||
|
@ -773,7 +773,7 @@ static inline int silk_ADD_RSHIFT_(int a, int b, int shift, char *file, int line
|
||||||
|
|
||||||
#undef silk_ADD_RSHIFT32
|
#undef silk_ADD_RSHIFT32
|
||||||
#define silk_ADD_RSHIFT32(a,b,c) silk_ADD_RSHIFT32_((a), (b), (c), __FILE__, __LINE__)
|
#define silk_ADD_RSHIFT32(a,b,c) silk_ADD_RSHIFT32_((a), (b), (c), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_ADD_RSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_ADD_RSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ret = a + (b >> shift);
|
ret = a + (b >> shift);
|
||||||
if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) )
|
if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) )
|
||||||
|
@ -788,7 +788,7 @@ static inline opus_int32 silk_ADD_RSHIFT32_(opus_int32 a, opus_int32 b, opus_int
|
||||||
|
|
||||||
#undef silk_ADD_RSHIFT_uint
|
#undef silk_ADD_RSHIFT_uint
|
||||||
#define silk_ADD_RSHIFT_uint(a,b,c) silk_ADD_RSHIFT_uint_((a), (b), (c), __FILE__, __LINE__)
|
#define silk_ADD_RSHIFT_uint(a,b,c) silk_ADD_RSHIFT_uint_((a), (b), (c), __FILE__, __LINE__)
|
||||||
static inline opus_uint32 silk_ADD_RSHIFT_uint_(opus_uint32 a, opus_uint32 b, opus_int32 shift, char *file, int line){
|
static OPUS_INLINE opus_uint32 silk_ADD_RSHIFT_uint_(opus_uint32 a, opus_uint32 b, opus_int32 shift, char *file, int line){
|
||||||
opus_uint32 ret;
|
opus_uint32 ret;
|
||||||
ret = a + (b >> shift);
|
ret = a + (b >> shift);
|
||||||
if ( (shift < 0) || (shift>32) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) )
|
if ( (shift < 0) || (shift>32) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) )
|
||||||
|
@ -803,7 +803,7 @@ static inline opus_uint32 silk_ADD_RSHIFT_uint_(opus_uint32 a, opus_uint32 b, op
|
||||||
|
|
||||||
#undef silk_SUB_LSHIFT32
|
#undef silk_SUB_LSHIFT32
|
||||||
#define silk_SUB_LSHIFT32(a,b,c) silk_SUB_LSHIFT32_((a), (b), (c), __FILE__, __LINE__)
|
#define silk_SUB_LSHIFT32(a,b,c) silk_SUB_LSHIFT32_((a), (b), (c), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_SUB_LSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_SUB_LSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ret = a - (b << shift);
|
ret = a - (b << shift);
|
||||||
if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a - (((opus_int64)b) << shift)) )
|
if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a - (((opus_int64)b) << shift)) )
|
||||||
|
@ -818,7 +818,7 @@ static inline opus_int32 silk_SUB_LSHIFT32_(opus_int32 a, opus_int32 b, opus_int
|
||||||
|
|
||||||
#undef silk_SUB_RSHIFT32
|
#undef silk_SUB_RSHIFT32
|
||||||
#define silk_SUB_RSHIFT32(a,b,c) silk_SUB_RSHIFT32_((a), (b), (c), __FILE__, __LINE__)
|
#define silk_SUB_RSHIFT32(a,b,c) silk_SUB_RSHIFT32_((a), (b), (c), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_SUB_RSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_SUB_RSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ret = a - (b >> shift);
|
ret = a - (b >> shift);
|
||||||
if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a - (((opus_int64)b) >> shift)) )
|
if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a - (((opus_int64)b) >> shift)) )
|
||||||
|
@ -833,7 +833,7 @@ static inline opus_int32 silk_SUB_RSHIFT32_(opus_int32 a, opus_int32 b, opus_int
|
||||||
|
|
||||||
#undef silk_RSHIFT_ROUND
|
#undef silk_RSHIFT_ROUND
|
||||||
#define silk_RSHIFT_ROUND(a,b) silk_RSHIFT_ROUND_((a), (b), __FILE__, __LINE__)
|
#define silk_RSHIFT_ROUND(a,b) silk_RSHIFT_ROUND_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_RSHIFT_ROUND_(opus_int32 a, opus_int32 shift, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_RSHIFT_ROUND_(opus_int32 a, opus_int32 shift, char *file, int line){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1;
|
ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1;
|
||||||
/* the marco definition can't handle a shift of zero */
|
/* the marco definition can't handle a shift of zero */
|
||||||
|
@ -849,7 +849,7 @@ static inline opus_int32 silk_RSHIFT_ROUND_(opus_int32 a, opus_int32 shift, char
|
||||||
|
|
||||||
#undef silk_RSHIFT_ROUND64
|
#undef silk_RSHIFT_ROUND64
|
||||||
#define silk_RSHIFT_ROUND64(a,b) silk_RSHIFT_ROUND64_((a), (b), __FILE__, __LINE__)
|
#define silk_RSHIFT_ROUND64(a,b) silk_RSHIFT_ROUND64_((a), (b), __FILE__, __LINE__)
|
||||||
static inline opus_int64 silk_RSHIFT_ROUND64_(opus_int64 a, opus_int32 shift, char *file, int line){
|
static OPUS_INLINE opus_int64 silk_RSHIFT_ROUND64_(opus_int64 a, opus_int32 shift, char *file, int line){
|
||||||
opus_int64 ret;
|
opus_int64 ret;
|
||||||
/* the marco definition can't handle a shift of zero */
|
/* the marco definition can't handle a shift of zero */
|
||||||
if ( (shift <= 0) || (shift>=64) )
|
if ( (shift <= 0) || (shift>=64) )
|
||||||
|
@ -865,14 +865,14 @@ static inline opus_int64 silk_RSHIFT_ROUND64_(opus_int64 a, opus_int32 shift, ch
|
||||||
|
|
||||||
/* silk_abs is used on floats also, so doesn't work... */
|
/* silk_abs is used on floats also, so doesn't work... */
|
||||||
/*#undef silk_abs
|
/*#undef silk_abs
|
||||||
static inline opus_int32 silk_abs(opus_int32 a){
|
static OPUS_INLINE opus_int32 silk_abs(opus_int32 a){
|
||||||
silk_assert(a != 0x80000000);
|
silk_assert(a != 0x80000000);
|
||||||
return (((a) > 0) ? (a) : -(a)); // Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN
|
return (((a) > 0) ? (a) : -(a)); // Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
#undef silk_abs_int64
|
#undef silk_abs_int64
|
||||||
#define silk_abs_int64(a) silk_abs_int64_((a), __FILE__, __LINE__)
|
#define silk_abs_int64(a) silk_abs_int64_((a), __FILE__, __LINE__)
|
||||||
static inline opus_int64 silk_abs_int64_(opus_int64 a, char *file, int line){
|
static OPUS_INLINE opus_int64 silk_abs_int64_(opus_int64 a, char *file, int line){
|
||||||
if ( a == silk_int64_MIN )
|
if ( a == silk_int64_MIN )
|
||||||
{
|
{
|
||||||
fprintf (stderr, "silk_abs_int64(%lld) in %s: line %d\n", (long long)a, file, line);
|
fprintf (stderr, "silk_abs_int64(%lld) in %s: line %d\n", (long long)a, file, line);
|
||||||
|
@ -885,7 +885,7 @@ static inline opus_int64 silk_abs_int64_(opus_int64 a, char *file, int line){
|
||||||
|
|
||||||
#undef silk_abs_int32
|
#undef silk_abs_int32
|
||||||
#define silk_abs_int32(a) silk_abs_int32_((a), __FILE__, __LINE__)
|
#define silk_abs_int32(a) silk_abs_int32_((a), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_abs_int32_(opus_int32 a, char *file, int line){
|
static OPUS_INLINE opus_int32 silk_abs_int32_(opus_int32 a, char *file, int line){
|
||||||
if ( a == silk_int32_MIN )
|
if ( a == silk_int32_MIN )
|
||||||
{
|
{
|
||||||
fprintf (stderr, "silk_abs_int32(%d) in %s: line %d\n", a, file, line);
|
fprintf (stderr, "silk_abs_int32(%d) in %s: line %d\n", a, file, line);
|
||||||
|
@ -898,7 +898,7 @@ static inline opus_int32 silk_abs_int32_(opus_int32 a, char *file, int line){
|
||||||
|
|
||||||
#undef silk_CHECK_FIT8
|
#undef silk_CHECK_FIT8
|
||||||
#define silk_CHECK_FIT8(a) silk_CHECK_FIT8_((a), __FILE__, __LINE__)
|
#define silk_CHECK_FIT8(a) silk_CHECK_FIT8_((a), __FILE__, __LINE__)
|
||||||
static inline opus_int8 silk_CHECK_FIT8_( opus_int64 a, char *file, int line ){
|
static OPUS_INLINE opus_int8 silk_CHECK_FIT8_( opus_int64 a, char *file, int line ){
|
||||||
opus_int8 ret;
|
opus_int8 ret;
|
||||||
ret = (opus_int8)a;
|
ret = (opus_int8)a;
|
||||||
if ( (opus_int64)ret != a )
|
if ( (opus_int64)ret != a )
|
||||||
|
@ -913,7 +913,7 @@ static inline opus_int8 silk_CHECK_FIT8_( opus_int64 a, char *file, int line ){
|
||||||
|
|
||||||
#undef silk_CHECK_FIT16
|
#undef silk_CHECK_FIT16
|
||||||
#define silk_CHECK_FIT16(a) silk_CHECK_FIT16_((a), __FILE__, __LINE__)
|
#define silk_CHECK_FIT16(a) silk_CHECK_FIT16_((a), __FILE__, __LINE__)
|
||||||
static inline opus_int16 silk_CHECK_FIT16_( opus_int64 a, char *file, int line ){
|
static OPUS_INLINE opus_int16 silk_CHECK_FIT16_( opus_int64 a, char *file, int line ){
|
||||||
opus_int16 ret;
|
opus_int16 ret;
|
||||||
ret = (opus_int16)a;
|
ret = (opus_int16)a;
|
||||||
if ( (opus_int64)ret != a )
|
if ( (opus_int64)ret != a )
|
||||||
|
@ -928,7 +928,7 @@ static inline opus_int16 silk_CHECK_FIT16_( opus_int64 a, char *file, int line )
|
||||||
|
|
||||||
#undef silk_CHECK_FIT32
|
#undef silk_CHECK_FIT32
|
||||||
#define silk_CHECK_FIT32(a) silk_CHECK_FIT32_((a), __FILE__, __LINE__)
|
#define silk_CHECK_FIT32(a) silk_CHECK_FIT32_((a), __FILE__, __LINE__)
|
||||||
static inline opus_int32 silk_CHECK_FIT32_( opus_int64 a, char *file, int line ){
|
static OPUS_INLINE opus_int32 silk_CHECK_FIT32_( opus_int64 a, char *file, int line ){
|
||||||
opus_int32 ret;
|
opus_int32 ret;
|
||||||
ret = (opus_int32)a;
|
ret = (opus_int32)a;
|
||||||
if ( (opus_int64)ret != a )
|
if ( (opus_int64)ret != a )
|
|
@ -8,11 +8,11 @@ this list of conditions and the following disclaimer.
|
||||||
- Redistributions in binary form must reproduce the above copyright
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
documentation and/or other materials provided with the distribution.
|
||||||
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
||||||
names of specific contributors, may be used to endorse or promote
|
names of specific contributors, may be used to endorse or promote
|
||||||
products derived from this software without specific prior written
|
products derived from this software without specific prior written
|
||||||
permission.
|
permission.
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
@ -41,7 +41,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define QA 16
|
#define QA 16
|
||||||
|
|
||||||
/* helper function for NLSF2A(..) */
|
/* helper function for NLSF2A(..) */
|
||||||
static inline void silk_NLSF2A_find_poly(
|
static OPUS_INLINE void silk_NLSF2A_find_poly(
|
||||||
opus_int32 *out, /* O intermediate polynomial, QA [dd+1] */
|
opus_int32 *out, /* O intermediate polynomial, QA [dd+1] */
|
||||||
const opus_int32 *cLSF, /* I vector of interleaved 2*cos(LSFs), QA [d] */
|
const opus_int32 *cLSF, /* I vector of interleaved 2*cos(LSFs), QA [d] */
|
||||||
opus_int dd /* I polynomial order (= 1/2 * filter order) */
|
opus_int dd /* I polynomial order (= 1/2 * filter order) */
|
|
@ -8,11 +8,11 @@ this list of conditions and the following disclaimer.
|
||||||
- Redistributions in binary form must reproduce the above copyright
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
documentation and/or other materials provided with the distribution.
|
||||||
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
||||||
names of specific contributors, may be used to endorse or promote
|
names of specific contributors, may be used to endorse or promote
|
||||||
products derived from this software without specific prior written
|
products derived from this software without specific prior written
|
||||||
permission.
|
permission.
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
@ -8,11 +8,11 @@ this list of conditions and the following disclaimer.
|
||||||
- Redistributions in binary form must reproduce the above copyright
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
documentation and/or other materials provided with the distribution.
|
||||||
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
||||||
names of specific contributors, may be used to endorse or promote
|
names of specific contributors, may be used to endorse or promote
|
||||||
products derived from this software without specific prior written
|
products derived from this software without specific prior written
|
||||||
permission.
|
permission.
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
@ -8,11 +8,11 @@ this list of conditions and the following disclaimer.
|
||||||
- Redistributions in binary form must reproduce the above copyright
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
documentation and/or other materials provided with the distribution.
|
||||||
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
||||||
names of specific contributors, may be used to endorse or promote
|
names of specific contributors, may be used to endorse or promote
|
||||||
products derived from this software without specific prior written
|
products derived from this software without specific prior written
|
||||||
permission.
|
permission.
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
/* Predictive dequantizer for NLSF residuals */
|
/* Predictive dequantizer for NLSF residuals */
|
||||||
static inline void silk_NLSF_residual_dequant( /* O Returns RD value in Q30 */
|
static OPUS_INLINE void silk_NLSF_residual_dequant( /* O Returns RD value in Q30 */
|
||||||
opus_int16 x_Q10[], /* O Output [ order ] */
|
opus_int16 x_Q10[], /* O Output [ order ] */
|
||||||
const opus_int8 indices[], /* I Quantization indices [ order ] */
|
const opus_int8 indices[], /* I Quantization indices [ order ] */
|
||||||
const opus_uint8 pred_coef_Q8[], /* I Backward predictor coefs [ order ] */
|
const opus_uint8 pred_coef_Q8[], /* I Backward predictor coefs [ order ] */
|
|
@ -8,11 +8,11 @@ this list of conditions and the following disclaimer.
|
||||||
- Redistributions in binary form must reproduce the above copyright
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
documentation and/or other materials provided with the distribution.
|
||||||
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
||||||
names of specific contributors, may be used to endorse or promote
|
names of specific contributors, may be used to endorse or promote
|
||||||
products derived from this software without specific prior written
|
products derived from this software without specific prior written
|
||||||
permission.
|
permission.
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
@ -121,7 +121,7 @@ opus_int32 silk_NLSF_del_dec_quant( /* O Returns
|
||||||
RD_Q25[ j + nStates ] = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate1_Q5 );
|
RD_Q25[ j + nStates ] = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate1_Q5 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nStates < NLSF_QUANT_DEL_DEC_STATES ) {
|
if( nStates <= ( NLSF_QUANT_DEL_DEC_STATES >> 1 ) ) {
|
||||||
/* double number of states and copy */
|
/* double number of states and copy */
|
||||||
for( j = 0; j < nStates; j++ ) {
|
for( j = 0; j < nStates; j++ ) {
|
||||||
ind[ j + nStates ][ i ] = ind[ j ][ i ] + 1;
|
ind[ j + nStates ][ i ] = ind[ j ][ i ] + 1;
|
|
@ -8,11 +8,11 @@ this list of conditions and the following disclaimer.
|
||||||
- Redistributions in binary form must reproduce the above copyright
|
- Redistributions in binary form must reproduce the above copyright
|
||||||
notice, this list of conditions and the following disclaimer in the
|
notice, this list of conditions and the following disclaimer in the
|
||||||
documentation and/or other materials provided with the distribution.
|
documentation and/or other materials provided with the distribution.
|
||||||
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
- Neither the name of Internet Society, IETF or IETF Trust, nor the
|
||||||
names of specific contributors, may be used to endorse or promote
|
names of specific contributors, may be used to endorse or promote
|
||||||
products derived from this software without specific prior written
|
products derived from this software without specific prior written
|
||||||
permission.
|
permission.
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "stack_alloc.h"
|
||||||
|
|
||||||
/***********************/
|
/***********************/
|
||||||
/* NLSF vector encoder */
|
/* NLSF vector encoder */
|
||||||
|
@ -46,10 +47,10 @@ opus_int32 silk_NLSF_encode( /* O Returns
|
||||||
{
|
{
|
||||||
opus_int i, s, ind1, bestIndex, prob_Q8, bits_q7;
|
opus_int i, s, ind1, bestIndex, prob_Q8, bits_q7;
|
||||||
opus_int32 W_tmp_Q9;
|
opus_int32 W_tmp_Q9;
|
||||||
opus_int32 err_Q26[ NLSF_VQ_MAX_VECTORS ];
|
VARDECL( opus_int32, err_Q26 );
|
||||||
opus_int32 RD_Q25[ NLSF_VQ_MAX_SURVIVORS ];
|
VARDECL( opus_int32, RD_Q25 );
|
||||||
opus_int tempIndices1[ NLSF_VQ_MAX_SURVIVORS ];
|
VARDECL( opus_int, tempIndices1 );
|
||||||
opus_int8 tempIndices2[ NLSF_VQ_MAX_SURVIVORS * MAX_LPC_ORDER ];
|
VARDECL( opus_int8, tempIndices2 );
|
||||||
opus_int16 res_Q15[ MAX_LPC_ORDER ];
|
opus_int16 res_Q15[ MAX_LPC_ORDER ];
|
||||||
opus_int16 res_Q10[ MAX_LPC_ORDER ];
|
opus_int16 res_Q10[ MAX_LPC_ORDER ];
|
||||||
opus_int16 NLSF_tmp_Q15[ MAX_LPC_ORDER ];
|
opus_int16 NLSF_tmp_Q15[ MAX_LPC_ORDER ];
|
||||||
|
@ -58,6 +59,7 @@ opus_int32 silk_NLSF_encode( /* O Returns
|
||||||
opus_uint8 pred_Q8[ MAX_LPC_ORDER ];
|
opus_uint8 pred_Q8[ MAX_LPC_ORDER ];
|
||||||
opus_int16 ec_ix[ MAX_LPC_ORDER ];
|
opus_int16 ec_ix[ MAX_LPC_ORDER ];
|
||||||
const opus_uint8 *pCB_element, *iCDF_ptr;
|
const opus_uint8 *pCB_element, *iCDF_ptr;
|
||||||
|
SAVE_STACK;
|
||||||
|
|
||||||
silk_assert( nSurvivors <= NLSF_VQ_MAX_SURVIVORS );
|
silk_assert( nSurvivors <= NLSF_VQ_MAX_SURVIVORS );
|
||||||
silk_assert( signalType >= 0 && signalType <= 2 );
|
silk_assert( signalType >= 0 && signalType <= 2 );
|
||||||
|
@ -67,11 +69,16 @@ opus_int32 silk_NLSF_encode( /* O Returns
|
||||||
silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->deltaMin_Q15, psNLSF_CB->order );
|
silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->deltaMin_Q15, psNLSF_CB->order );
|
||||||
|
|
||||||
/* First stage: VQ */
|
/* First stage: VQ */
|
||||||
|
ALLOC( err_Q26, psNLSF_CB->nVectors, opus_int32 );
|
||||||
silk_NLSF_VQ( err_Q26, pNLSF_Q15, psNLSF_CB->CB1_NLSF_Q8, psNLSF_CB->nVectors, psNLSF_CB->order );
|
silk_NLSF_VQ( err_Q26, pNLSF_Q15, psNLSF_CB->CB1_NLSF_Q8, psNLSF_CB->nVectors, psNLSF_CB->order );
|
||||||
|
|
||||||
/* Sort the quantization errors */
|
/* Sort the quantization errors */
|
||||||
|
ALLOC( tempIndices1, nSurvivors, opus_int );
|
||||||
silk_insertion_sort_increasing( err_Q26, tempIndices1, psNLSF_CB->nVectors, nSurvivors );
|
silk_insertion_sort_increasing( err_Q26, tempIndices1, psNLSF_CB->nVectors, nSurvivors );
|
||||||
|
|
||||||
|
ALLOC( RD_Q25, nSurvivors, opus_int32 );
|
||||||
|
ALLOC( tempIndices2, nSurvivors * MAX_LPC_ORDER, opus_int8 );
|
||||||
|
|
||||||
/* Loop over survivors */
|
/* Loop over survivors */
|
||||||
for( s = 0; s < nSurvivors; s++ ) {
|
for( s = 0; s < nSurvivors; s++ ) {
|
||||||
ind1 = tempIndices1[ s ];
|
ind1 = tempIndices1[ s ];
|
||||||
|
@ -124,5 +131,6 @@ opus_int32 silk_NLSF_encode( /* O Returns
|
||||||
/* Decode */
|
/* Decode */
|
||||||
silk_NLSF_decode( pNLSF_Q15, NLSFIndices, psNLSF_CB );
|
silk_NLSF_decode( pNLSF_Q15, NLSFIndices, psNLSF_CB );
|
||||||
|
|
||||||
|
RESTORE_STACK;
|
||||||
return RD_Q25[ 0 ];
|
return RD_Q25[ 0 ];
|
||||||
}
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue