diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..fbfa0202 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,37 @@ +name: Build tests + +on: + push: + branches: + - "*" + pull_request: + branches: + - "*" + +jobs: + build-linux-32: + runs-on: ubuntu-18.04 + + steps: + - uses: actions/checkout@v2 + - name: Build linux-i386 + run: | + scripts/build-ubuntu-i386.sh + + build-linux-64: + runs-on: ubuntu-18.04 + + steps: + - uses: actions/checkout@v2 + - name: Build linux-amd64 + run: | + scripts/build-ubuntu-amd64.sh + + build-android-armv7a: + runs-on: ubuntu-18.04 + + steps: + - uses: actions/checkout@v2 + - name: Build android-armv7a + run: | + scripts/build-android-armv7a.sh diff --git a/.gitignore b/.gitignore index 9edacd8f..a96f2908 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,6 @@ *.vpc.* *.project *obj_* -build/ .waf* .lock-waf* __pycache__ @@ -29,4 +28,11 @@ Release_*/ *.ilk ValveETWProviderEvents.h game/client/*/client.lib -game/server/*/server.lib \ No newline at end of file +game/server/*/server.lib +.DS_Store +build*/ +android/ +.cache/ +.ccache/ +waf3*/ +.vscode/ \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 3fcb4af5..8072bb24 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "ivp"] path = ivp url = https://github.com/nillerusr/source-physics +[submodule "lib"] + path = lib + url = https://github.com/nillerusr/source-engine-libs diff --git a/README.md b/README.md index 164ca1f1..9b98ac05 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,21 @@ # source-engine +Welcome to source engine:) -# Goals -* fixing bugs -* ~~NEON support~~ -* DXVK support -* remove unnecessary dependencies -* Elbrus port -* ~~Arm(android) port~~ -* improve performance -* ~~replace current buildsystem with waf~~ -* rewrite achivement system( to work without steam ) -* 64-bit support +Discord: https://discord.gg/hZRB7WMgGw -# How to Build? -Clone repo and change directory: -``` -git clone https://github.com/nillerusr/source-engine --recursive --depth 1 -cd source-engine -``` -On Linux: +# Current tasks +- [x] NEON support +- [x] remove unnecessary dependencies +- [x] Arm(android) port +- [x] replace current buildsystem with waf +- [x] rewrite achivement system( to work without steam ) +- [x] 64-bit support +- [ ] improve performance +- [ ] fixing bugs +- [ ] dxvk-native support +- [ ] Elbrus port +- [ ] rewrite serverbrowser to work without steam +- [ ] Windows build support for waf -dependencies: -fontconfig, freetype2, OpenAL, SDL2, libbz2, libcurl, libjpeg, libpng, zlib -``` -./waf configure -T debug -./waf build -``` -On Linux for Android(**Note: only Android NDK r10e is supported**): -``` -export ANDROID_NDK=/path/to/ndk -./waf configure -T debug --android=armeabi-v7a,4.9,21 -./waf build -``` -On Windows/MacOS: -**TODO(WAF is not configured for Windows/MacOS. Use VPC as temporary solution)** + +# [How to Build?](https://github.com/nillerusr/source-engine/wiki/How-to-build) diff --git a/appframework/glmdisplaydb_linuxwin.inl b/appframework/glmdisplaydb_linuxwin.inl index 3a516f2a..daa28d85 100644 --- a/appframework/glmdisplaydb_linuxwin.inl +++ b/appframework/glmdisplaydb_linuxwin.inl @@ -595,9 +595,13 @@ void GLMDisplayInfo::PopulateModes( void ) // Add double of everything also - Retina proofing hopefully. m_modes->AddToTail( new GLMDisplayMode( w * 2, h * 2, 0 ) ); } + + m_modes->AddToTail( new GLMDisplayMode( w, w * ((float)m_info.m_displayPixelHeight/m_info.m_displayPixelWidth), 0 ) ); } } + m_modes->AddToTail( new GLMDisplayMode( m_info.m_displayPixelWidth / 2, m_info.m_displayPixelHeight / 2, 0 ) ); + m_modes->Sort( DisplayModeSortFunction ); // remove dupes. diff --git a/appframework/glmrendererinfo_osx.mm b/appframework/glmrendererinfo_osx.mm index fbaf3150..a36f6249 100644 --- a/appframework/glmrendererinfo_osx.mm +++ b/appframework/glmrendererinfo_osx.mm @@ -206,7 +206,7 @@ GLMRendererInfo::GLMRendererInfo( GLMRendererInfoFields *info ) kCGLPFADoubleBuffer, kCGLPFANoRecovery, kCGLPFAAccelerated, kCGLPFADepthSize, 0, kCGLPFAColorSize, 32, - kCGLPFARendererID, info->m_rendererID, + kCGLPFARendererID, (unsigned int)info->m_rendererID, 0 }; @@ -859,7 +859,7 @@ void GLMDisplayDB::PopulateRenderers( void ) { // grab the OS version - long vMajor = 0; long vMinor = 0; long vMinorMinor = 0; + SInt32 vMajor = 0; SInt32 vMinor = 0; SInt32 vMinorMinor = 0; OSStatus gestalt_err = 0; gestalt_err = Gestalt(gestaltSystemVersionMajor, &vMajor); @@ -1374,7 +1374,7 @@ bool GLMDisplayDB::GetModeInfo( int rendererIndex, int displayIndex, int modeInd { int modeIndex=0; number = (CFNumberRef)CFDictionaryGetValue(curModeDict, kCGDisplayMode); - CFNumberGetValue(number, kCFNumberLongType, &modeIndex); + CFNumberGetValue(number, kCFNumberIntType, &modeIndex); // grab the width and height, I am unclear on whether this is the displayed FB width or the display device width. int screenWidth=0; @@ -1382,11 +1382,11 @@ bool GLMDisplayDB::GetModeInfo( int rendererIndex, int displayIndex, int modeInd int refreshHz=0; number = (CFNumberRef)CFDictionaryGetValue(curModeDict, kCGDisplayWidth); - CFNumberGetValue(number, kCFNumberLongType, &screenWidth); + CFNumberGetValue(number, kCFNumberIntType, &screenWidth); number = (CFNumberRef)CFDictionaryGetValue(curModeDict, kCGDisplayHeight); - CFNumberGetValue(number, kCFNumberLongType, &screenHeight); + CFNumberGetValue(number, kCFNumberIntType, &screenHeight); number = (CFNumberRef)CFDictionaryGetValue(curModeDict, kCGDisplayRefreshRate); - CFNumberGetValue(number, kCFNumberLongType, &refreshHz); + CFNumberGetValue(number, kCFNumberIntType, &refreshHz); GLMPRINTF(( "-D- GLMDisplayDB::GetModeInfo sees mode-index=%d, width=%d, height=%d on CGID %08x (display index %d on rendererindex %d)", modeIndex, @@ -1574,7 +1574,7 @@ void GLMDisplayInfo::PopulateModes( void ) void GLMDisplayInfo::Dump( int which ) { - GLMPRINTF(("\n #%d: GLMDisplayInfo @ %08x, cg-id=%08x display-mask=%08x pixwidth=%d pixheight=%d", which, (int)this, m_info.m_cgDisplayID, m_info.m_glDisplayMask, m_info.m_displayPixelWidth, m_info.m_displayPixelHeight )); + GLMPRINTF(("\n #%d: GLMDisplayInfo @ %08x, cg-id=%08x display-mask=%08x pixwidth=%d pixheight=%d", which, (int)(intp)this, m_info.m_cgDisplayID, m_info.m_glDisplayMask, m_info.m_displayPixelWidth, m_info.m_displayPixelHeight )); FOR_EACH_VEC( *m_modes, i ) { diff --git a/appframework/sdlmgr.cpp b/appframework/sdlmgr.cpp index 4fc1878e..e8e5a388 100644 --- a/appframework/sdlmgr.cpp +++ b/appframework/sdlmgr.cpp @@ -19,7 +19,9 @@ #include "tier1/utllinkedlist.h" #include "tier1/convar.h" +#ifdef TOGLES #include +#endif // NOTE: This has to be the last file included! (turned off below, since this is included like a header) #include "tier0/memdbgon.h" @@ -63,10 +65,16 @@ static void *l_egl = NULL; static void *l_gles = NULL; typedef void *(*t_glGetProcAddress)( const char * ); -t_glGetProcAddress _glGetProcAddress; - typedef EGLBoolean (*t_eglBindAPI)(EGLenum api); +typedef EGLBoolean (*t_eglInitialize)(EGLDisplay display, EGLint *major, EGLint *minor); +typedef EGLDisplay (*t_eglGetDisplay)(NativeDisplayType native_display); +typedef char const *(*t_eglQueryString)(EGLDisplay display, EGLint name); + t_eglBindAPI _eglBindAPI; +t_glGetProcAddress _glGetProcAddress; +t_eglInitialize _eglInitialize; +t_eglGetDisplay _eglGetDisplay; +t_eglQueryString _eglQueryString; #endif /* @@ -594,11 +602,25 @@ InitReturnVal_t CSDLMgr::Init() l_gles = dlopen("libGLESv3.so", RTLD_LAZY); if( l_egl ) + { _glGetProcAddress = (t_glGetProcAddress)dlsym(l_egl, "eglGetProcAddress"); + } SET_GL_ATTR(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); SET_GL_ATTR(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SET_GL_ATTR(SDL_GL_CONTEXT_MINOR_VERSION, 0); + + _eglInitialize = (t_eglInitialize)dlsym(l_egl, "eglInitialize"); + _eglGetDisplay = (t_eglGetDisplay)dlsym(l_egl, "eglGetDisplay"); + _eglQueryString = (t_eglQueryString)dlsym(l_egl, "eglQueryString"); + + if( _eglInitialize && _eglInitialize && _eglQueryString ) + { + EGLDisplay display = _eglGetDisplay(EGL_DEFAULT_DISPLAY); + if( _eglInitialize(display, NULL, NULL) != -1 + && strstr(_eglQueryString(display, EGL_EXTENSIONS) ,"EGL_KHR_gl_colorspace") ) + SET_GL_ATTR(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 1) + } #elif ANDROID bool m_bOGL = false; diff --git a/bitmap/colorconversion.cpp b/bitmap/colorconversion.cpp index ac033fd2..38601ed1 100644 --- a/bitmap/colorconversion.cpp +++ b/bitmap/colorconversion.cpp @@ -10,7 +10,6 @@ #include "bitmap/imageformat.h" #include "basetypes.h" #include "tier0/dbg.h" -#include #include #include "mathlib/mathlib.h" #include "mathlib/vector.h" @@ -435,7 +434,8 @@ static inline void DecodeAlpha3BitLinear( CDestPixel *pImPos, DXTAlphaBlock3BitL // pRows = (Alpha3BitRows*) & ( pAlphaBlock->stuff[0] ); const DWORD mask = 0x00000007; // bits = 00 00 01 11 - DWORD bits = *( (DWORD*) & ( pAlphaBlock->stuff[0] )); + DWORD bits; + memcpy( &bits, &(pAlphaBlock->stuff[0]), sizeof(DWORD) ); gBits[0][0] = (BYTE)( bits & mask ); bits >>= 3; @@ -454,7 +454,7 @@ static inline void DecodeAlpha3BitLinear( CDestPixel *pImPos, DXTAlphaBlock3BitL gBits[1][3] = (BYTE)( bits & mask ); // now for last two rows: - bits = *( (DWORD*) & ( pAlphaBlock->stuff[3] )); // last 3 bytes + memcpy( &bits, &(pAlphaBlock->stuff[3]), sizeof(DWORD) ); gBits[2][0] = (BYTE)( bits & mask ); bits >>= 3; diff --git a/bitmap/float_bm.cpp b/bitmap/float_bm.cpp index 33ab8c1f..f10264ec 100644 --- a/bitmap/float_bm.cpp +++ b/bitmap/float_bm.cpp @@ -311,13 +311,16 @@ FloatBitMap_t *FloatBitMap_t::QuarterSize(void) const FloatBitMap_t *newbm=new FloatBitMap_t(Width/2,Height/2); for(int y=0;yPixel(x,y,c)=((Pixel(x*2,y*2,c)+Pixel(x*2+1,y*2,c)+ Pixel(x*2,y*2+1,c)+Pixel(x*2+1,y*2+1,c))/4); } - return newbm; + } + + return newbm; } FloatBitMap_t *FloatBitMap_t::QuarterSizeBlocky(void) const @@ -326,12 +329,14 @@ FloatBitMap_t *FloatBitMap_t::QuarterSizeBlocky(void) const FloatBitMap_t *newbm=new FloatBitMap_t(Width/2,Height/2); for(int y=0;yPixel(x,y,c)=Pixel(x*2,y*2,c); } - return newbm; + } + return newbm; } Vector FloatBitMap_t::AverageColor(void) @@ -349,12 +354,15 @@ float FloatBitMap_t::BrightestColor(void) { float ret=0.0; for(int y=0;y static inline void SWAP(T & a, T & b) @@ -394,6 +402,7 @@ void FloatBitMap_t::UnLogize(void) void FloatBitMap_t::Clear(float r, float g, float b, float alpha) { for(int y=0;yPixel(x,y,c)=dx1; + for (int i = 0; i < NDELTAS; i++) + { + int x1 = x + dx[i]; + int y1 = y + dy[i]; + x1 = MAX(0, x1); + x1 = MIN(Width - 1, x1); + y1 = MAX(0, y1); + y1 = MIN(Height - 1, y1); + float dx1 = Pixel(x, y, c) - Pixel(x1, y1, c); + deltas[i]->Pixel(x, y, c) = dx1; + } } } - for(int x=1;xPixel(x + xofs, y + yofs, c) = diff; + if (Flags & SPFLAGS_MAXGRADIENT) { - float diff=b.Pixel(x,y,c)-b.Pixel(x+dx[i],y+dy[i],c); - deltas[i]->Pixel(x+xofs,y+yofs,c)=diff; - if (Flags & SPFLAGS_MAXGRADIENT) - { - float dx1=Pixel(x+xofs,y+yofs,c)-Pixel(x+dx[i]+xofs,y+dy[i]+yofs,c); - if (fabs(dx1)>fabs(diff)) - deltas[i]->Pixel(x+xofs,y+yofs,c)=dx1; - } + float dx1 = Pixel(x + xofs, y + yofs, c) - Pixel(x + dx[i] + xofs, y + dy[i] + yofs, c); + if (fabs(dx1) > fabs(diff)) + deltas[i]->Pixel(x + xofs, y + yofs, c) = dx1; } } + } + } + } - // now, calculate modifiability - for(int x=0;xxofs+1) && (x<=xofs+b.Width-2) && - (y>yofs+1) && (y<=yofs+b.Height-2)) - modify=1; - Alpha(x,y)=modify; - } - - // // now, force a fex pixels in center to be constant - // int midx=xofs+b.Width/2; - // int midy=yofs+b.Height/2; - // for(x=midx-10;x xofs + 1) && (x <= xofs + b.Width - 2) && + (y > yofs + 1) && (y <= yofs + b.Height - 2)) + modify = 1; + Alpha(x, y) = modify; + } + } + // // now, force a fex pixels in center to be constant + // int midx=xofs+b.Width/2; + // int midy=yofs+b.Height/2; + // for(x=midx-10;xPixel(x,y,c)=dx1; - gsum+=fabs(dx1); + int x1 = x + dx[i]; + int y1 = y + dy[i]; + x1 = MAX(0, x1); + x1 = MIN(Width - 1, x1); + y1 = MAX(0, y1); + y1 = MIN(Height - 1, y1); + float dx1 = Pixel(x, y, c) - Pixel(x1, y1, c); + deltas[i]->Pixel(x, y, c) = dx1; + gsum += fabs(dx1); + } + } + // now, reduce gradient changes + // float gavg=gsum/(Width*Height); + for (int x = 0; x < Width; x++) + for (int y = 0; y < Height; y++) + for (int c = 0; c < 3; c++) + { + for (int i = 0; i < NDELTAS; i++) + { + float norml = 1.1 *deltas[i]->Pixel(x, y, c); + // if (norml < 0.0) + // norml=-pow(-norml,1.2); + // else + // norml=pow(norml,1.2); + deltas[i]->Pixel(x, y, c) = norml; } } - // now, reduce gradient changes - // float gavg=gsum/(Width*Height); - for(int x=0;xPixel(x,y,c); - // if (norml<0.0) - // norml=-pow(-norml,1.2); - // else - // norml=pow(norml,1.2); - deltas[i]->Pixel(x,y,c)=norml; - } - } - // now, calculate modifiability - for(int x=0;x0) && (x 0) && (x < Width - 1) && + (y) && (y < Height - 1)) + { + modify = 1; + Alpha(x, y) = modify; + } + } - Poisson(deltas,2200,0); + Poisson(deltas, 2200, 0); } @@ -553,7 +572,9 @@ void FloatBitMap_t::MakeTileable(void) // set each pixel=avg-pixel FloatBitMap_t *cursrc=&rslta; for(int x=1;xPixel(x+1,y,c); @@ -596,12 +619,16 @@ void FloatBitMap_t::MakeTileable(void) error+=SQ(desired-cursrc->Pixel(x,y,c)); } SWAP(cursrc,curdst); + } + } } // paste result for(int x=0;xPixel(x,y,c); + } + } } @@ -613,15 +640,18 @@ void FloatBitMap_t::GetAlphaBounds(int &minx, int &miny, int &maxx,int &maxy) for(y=0;y=0;maxx--) { int y; for(y=0;yPoisson(lowdeltas,n_iters*4,flags); // now, propagate results from tmp to us for(int x=0;xWidth;x++) + { for(int y=0;yHeight;y++) + { for(int xi=0;xi<2;xi++) + { for(int yi=0;yi<2;yi++) + { if (Alpha(x*2+xi,y*2+yi)) { for(int c=0;c<3;c++) @@ -683,6 +719,10 @@ void FloatBitMap_t::Poisson(FloatBitMap_t *deltas[4], delete tmp; for(int i=0;iPixel(x,y,c)+cursrc->Pixel(x+dx[i],y+dy[i],c); desired*=(1.0/NDELTAS); - // desired=FLerp(Pixel(x,y,c),desired,Alpha(x,y)); + // desired=FLerp(Pixel(x,y,c),desired,Alpha(x,y)); curdst->Pixel(x,y,c)=FLerp(cursrc->Pixel(x,y,c),desired,0.5); error+=SQ(desired-cursrc->Pixel(x,y,c)); } diff --git a/bitmap/float_bm4.cpp b/bitmap/float_bm4.cpp index 7130b27e..79f9073e 100644 --- a/bitmap/float_bm4.cpp +++ b/bitmap/float_bm4.cpp @@ -40,7 +40,7 @@ struct SSBumpCalculationContext // what each thread needs to see }; -static unsigned SSBumpCalculationThreadFN( void * ctx1 ) +static uintp SSBumpCalculationThreadFN( void * ctx1 ) { SSBumpCalculationContext *ctx = ( SSBumpCalculationContext * ) ctx1; diff --git a/bitmap/float_bm_bilateral_filter.cpp b/bitmap/float_bm_bilateral_filter.cpp index 4d45eb9e..919b07e7 100644 --- a/bitmap/float_bm_bilateral_filter.cpp +++ b/bitmap/float_bm_bilateral_filter.cpp @@ -24,7 +24,7 @@ struct TBFCalculationContext FloatBitMap_t *dest_bm; }; -static unsigned TBFCalculationThreadFN( void *ctx1 ) +static uintp TBFCalculationThreadFN( void *ctx1 ) { TBFCalculationContext *ctx = (TBFCalculationContext *) ctx1; for(int y=ctx->min_y; y <= ctx->max_y; y++) diff --git a/bitmap/imageformat.cpp b/bitmap/imageformat.cpp index bce9b67c..c2222653 100644 --- a/bitmap/imageformat.cpp +++ b/bitmap/imageformat.cpp @@ -11,7 +11,6 @@ #include "bitmap/imageformat.h" #include "basetypes.h" #include "tier0/dbg.h" -#include #include #include "nvtc.h" #include "mathlib/mathlib.h" @@ -312,12 +311,17 @@ ImageFormat D3DFormatToImageFormat( D3DFORMAT format ) switch ( format ) { -#if !defined( _X360 ) +#ifdef TOGLES + case D3DFMT_R8G8B8: + return IMAGE_FORMAT_RGB888; + case D3DFMT_A8R8G8B8: + return IMAGE_FORMAT_RGBA8888; +#else case D3DFMT_R8G8B8: return IMAGE_FORMAT_BGR888; -#endif case D3DFMT_A8R8G8B8: return IMAGE_FORMAT_BGRA8888; +#endif case D3DFMT_X8R8G8B8: return IMAGE_FORMAT_BGRX8888; case D3DFMT_R5G6B5: @@ -426,6 +430,10 @@ D3DFORMAT ImageFormatToD3DFormat( ImageFormat format ) #endif case IMAGE_FORMAT_BGRA8888: return D3DFMT_A8R8G8B8; + case IMAGE_FORMAT_RGB888: + return D3DFMT_R8G8B8; + case IMAGE_FORMAT_RGBA8888: + return D3DFMT_A8R8G8B8; case IMAGE_FORMAT_BGRX8888: return D3DFMT_X8R8G8B8; case IMAGE_FORMAT_BGR565: diff --git a/bitmap/resample.cpp b/bitmap/resample.cpp index 0ca61f0d..98998899 100644 --- a/bitmap/resample.cpp +++ b/bitmap/resample.cpp @@ -8,7 +8,6 @@ #include "bitmap/imageformat.h" #include "basetypes.h" #include "tier0/dbg.h" -#include #include #include "mathlib/mathlib.h" #include "mathlib/vector.h" diff --git a/bitmap/tgawriter.cpp b/bitmap/tgawriter.cpp index a73c9965..d1324fbc 100644 --- a/bitmap/tgawriter.cpp +++ b/bitmap/tgawriter.cpp @@ -7,7 +7,6 @@ #include #include #include "tier0/dbg.h" -#include #include "filesystem.h" #include "bitmap/tgawriter.h" #include "tier1/utlbuffer.h" diff --git a/build.sh b/build.sh deleted file mode 100755 index 5e1218e0..00000000 --- a/build.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -# example: ./build.sh everything togl - -make MAKE_VERBOSE=1 NO_CHROOT=1 -f $1.mak $2 -j$(nproc --all) diff --git a/common/GameUI/IGameConsole.h b/common/GameUI/IGameConsole.h index a18f3310..15b22bcd 100644 --- a/common/GameUI/IGameConsole.h +++ b/common/GameUI/IGameConsole.h @@ -33,7 +33,7 @@ public: // return true if the console has focus virtual bool IsConsoleVisible() = 0; - virtual void SetParent( int parent ) = 0; + virtual void SetParent( intp parent ) = 0; }; #define GAMECONSOLE_INTERFACE_VERSION "GameConsole004" diff --git a/common/GameUI/ObjectList.cpp b/common/GameUI/ObjectList.cpp index 7da11005..4b8758ce 100644 --- a/common/GameUI/ObjectList.cpp +++ b/common/GameUI/ObjectList.cpp @@ -6,7 +6,11 @@ // //=============================================================================// #include +#ifdef OSX +#include +#else #include +#endif #include "ObjectList.h" #include "tier1/strtools.h" diff --git a/common/GameUI/scriptobject.cpp b/common/GameUI/scriptobject.cpp index e83f5fd5..f810fb8c 100644 --- a/common/GameUI/scriptobject.cpp +++ b/common/GameUI/scriptobject.cpp @@ -15,6 +15,7 @@ #include "filesystem.h" #include "tier1/convar.h" #include "cdll_int.h" +#include "vcrmode.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -1150,4 +1151,4 @@ void CInfoDescription::WriteFileHeader( FileHandle_t fp ) g_pFullFileSystem->FPrintf( fp, "//\r\n//\r\n// Cvar\t-\tSetting\r\n\r\n" ); } -//----------------------------------------------------------------------------- \ No newline at end of file +//----------------------------------------------------------------------------- diff --git a/common/engine/idownloadsystem.h b/common/engine/idownloadsystem.h index 3cc020fa..6eb527eb 100644 --- a/common/engine/idownloadsystem.h +++ b/common/engine/idownloadsystem.h @@ -32,7 +32,7 @@ struct RequestContext_t; class IDownloadSystem : public IBaseInterface { public: - virtual DWORD CreateDownloadThread( RequestContext_t *pContext ) = 0; + virtual uintp CreateDownloadThread( RequestContext_t *pContext ) = 0; }; //---------------------------------------------------------------------------------------- diff --git a/common/freetype/config/ftconfig.h b/common/freetype/config/ftconfig.h index 5e19c414..200dd57f 100644 --- a/common/freetype/config/ftconfig.h +++ b/common/freetype/config/ftconfig.h @@ -3,6 +3,8 @@ #ifdef ANDROID #include +#elif defined(OSX) +#include #else #include #endif diff --git a/common/iconv.h b/common/iconv.h index 3ef7ed7d..6cf88588 100644 --- a/common/iconv.h +++ b/common/iconv.h @@ -55,8 +55,7 @@ typedef struct __iconv_t* iconv_t; * Available since API level 28. */ -#if __ANDROID_API__ >= 28 -iconv_t iconv_open(const char* __src_encoding, const char* __dst_encoding) __INTRODUCED_IN(28); +iconv_t iconv_open(const char* __src_encoding, const char* __dst_encoding); /** * [iconv(3)](http://man7.org/linux/man-pages/man3/iconv.3.html) converts characters from one @@ -70,7 +69,7 @@ iconv_t iconv_open(const char* __src_encoding, const char* __dst_encoding) __INT * * Available since API level 28. */ -size_t iconv(iconv_t __converter, char** __src_buf, size_t* __src_bytes_left, char** __dst_buf, size_t* __dst_bytes_left) __INTRODUCED_IN(28); +size_t iconv(iconv_t __converter, char** __src_buf, size_t* __src_bytes_left, char** __dst_buf, size_t* __dst_bytes_left); /** * [iconv_close(3)](http://man7.org/linux/man-pages/man3/iconv_close.3.html) deallocates a converter @@ -80,8 +79,6 @@ size_t iconv(iconv_t __converter, char** __src_buf, size_t* __src_bytes_left, ch * * Available since API level 28. */ -int iconv_close(iconv_t __converter) __INTRODUCED_IN(28); -#endif /* __ANDROID_API__ >= 28 */ - +int iconv_close(iconv_t __converter); __END_DECLS diff --git a/common/openal/alc.h b/common/openal/alc.h index 062e505a..e04c33f2 100644 --- a/common/openal/alc.h +++ b/common/openal/alc.h @@ -22,7 +22,7 @@ extern "C" { #define ALC_APIENTRY #endif -#if TARGET_OS_MAC +#if defined(TARGET_OS_MAC) && TARGET_OS_MAC #pragma export on #endif @@ -279,7 +279,7 @@ typedef void (ALC_APIENTRY *LPALCCAPTURESAMPLES)( ALCdevice *device, A #endif /* ALC_NO_PROTOTYPES */ -#if TARGET_OS_MAC +#if defined(TARGET_OS_MAC) && TARGET_OS_MAC #pragma export off #endif diff --git a/common/sse2neon.h b/common/sse2neon.h index 9e512acf..490c0a45 100644 --- a/common/sse2neon.h +++ b/common/sse2neon.h @@ -52,9 +52,9 @@ /* Enable precise implementation of math operations * This would slow down the computation a bit, but gives consistent result with - * x86 SSE2. (e.g. would solve a hole or NaN pixel in the rendering result) + * x86 SSE. (e.g. would solve a hole or NaN pixel in the rendering result) */ -/* _mm_min_ps and _mm_max_ps */ +/* _mm_min|max_ps|ss|pd|sd */ #ifndef SSE2NEON_PRECISE_MINMAX #define SSE2NEON_PRECISE_MINMAX (0) #endif @@ -66,33 +66,36 @@ #ifndef SSE2NEON_PRECISE_SQRT #define SSE2NEON_PRECISE_SQRT (0) #endif +/* _mm_dp_pd */ +#ifndef SSE2NEON_PRECISE_DP +#define SSE2NEON_PRECISE_DP (0) +#endif +/* compiler specific definitions */ #if defined(__GNUC__) || defined(__clang__) #pragma push_macro("FORCE_INLINE") #pragma push_macro("ALIGN_STRUCT") #define FORCE_INLINE static inline __attribute__((always_inline)) #define ALIGN_STRUCT(x) __attribute__((aligned(x))) -#ifndef likely -#define likely(x) __builtin_expect(!!(x), 1) -#endif -#ifndef unlikely -#define unlikely(x) __builtin_expect(!!(x), 0) -#endif -#else -#error "Macro name collisions may happen with unsupported compiler." -#ifdef FORCE_INLINE -#undef FORCE_INLINE -#endif +#define _sse2neon_likely(x) __builtin_expect(!!(x), 1) +#define _sse2neon_unlikely(x) __builtin_expect(!!(x), 0) +#else /* non-GNU / non-clang compilers */ +#warning "Macro name collisions may happen with unsupported compiler." +#ifndef FORCE_INLINE #define FORCE_INLINE static inline +#endif #ifndef ALIGN_STRUCT #define ALIGN_STRUCT(x) __declspec(align(x)) #endif +#define _sse2neon_likely(x) (x) +#define _sse2neon_unlikely(x) (x) #endif -#ifndef likely -#define likely(x) (x) -#endif -#ifndef unlikely -#define unlikely(x) (x) + +/* C language does not allow initializing a variable with a function call. */ +#ifdef __cplusplus +#define _sse2neon_const static const +#else +#define _sse2neon_const const #endif #include @@ -118,12 +121,25 @@ #pragma GCC push_options #pragma GCC target("+simd") #endif +#elif __ARM_ARCH == 8 +#if !defined(__ARM_NEON) || !defined(__ARM_NEON__) +#error \ + "You must enable NEON instructions (e.g. -mfpu=neon-fp-armv8) to use SSE2NEON." +#endif +#if !defined(__clang__) +#pragma GCC push_options +#endif #else #error "Unsupported target. Must be either ARMv7-A+NEON or ARMv8-A." #endif #endif #include +#if !defined(__aarch64__) && (__ARM_ARCH == 8) +#if defined __has_include && __has_include() +#include +#endif +#endif /* Rounding functions require either Aarch64 instructions or libm failback */ #if !defined(__aarch64__) @@ -135,7 +151,7 @@ */ #ifndef __has_builtin /* GCC prior to 10 or non-clang compilers */ /* Compatibility with gcc <= 9 */ -#if __GNUC__ <= 9 +#if defined(__GNUC__) && (__GNUC__ <= 9) #define __has_builtin(x) HAS##x #define HAS__builtin_popcount 1 #define HAS__builtin_popcountll 1 @@ -162,10 +178,25 @@ #define _MM_FROUND_TO_ZERO 0x03 #define _MM_FROUND_CUR_DIRECTION 0x04 #define _MM_FROUND_NO_EXC 0x08 +#define _MM_FROUND_RAISE_EXC 0x00 +#define _MM_FROUND_NINT (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_RAISE_EXC) +#define _MM_FROUND_FLOOR (_MM_FROUND_TO_NEG_INF | _MM_FROUND_RAISE_EXC) +#define _MM_FROUND_CEIL (_MM_FROUND_TO_POS_INF | _MM_FROUND_RAISE_EXC) +#define _MM_FROUND_TRUNC (_MM_FROUND_TO_ZERO | _MM_FROUND_RAISE_EXC) +#define _MM_FROUND_RINT (_MM_FROUND_CUR_DIRECTION | _MM_FROUND_RAISE_EXC) +#define _MM_FROUND_NEARBYINT (_MM_FROUND_CUR_DIRECTION | _MM_FROUND_NO_EXC) #define _MM_ROUND_NEAREST 0x0000 #define _MM_ROUND_DOWN 0x2000 #define _MM_ROUND_UP 0x4000 #define _MM_ROUND_TOWARD_ZERO 0x6000 +/* Flush zero mode macros. */ +#define _MM_FLUSH_ZERO_MASK 0x8000 +#define _MM_FLUSH_ZERO_ON 0x8000 +#define _MM_FLUSH_ZERO_OFF 0x0000 +/* Denormals are zeros mode macros. */ +#define _MM_DENORMALS_ZERO_MASK 0x0040 +#define _MM_DENORMALS_ZERO_ON 0x0040 +#define _MM_DENORMALS_ZERO_OFF 0x0000 /* indicate immediate constant argument in a given range */ #define __constrange(a, b) const @@ -188,6 +219,16 @@ typedef float32x4_t __m128d; #endif typedef int64x2_t __m128i; /* 128-bit vector containing integers */ +// __int64 is defined in the Intrinsics Guide which maps to different datatype +// in different data model +#if !(defined(_WIN32) || defined(_WIN64) || defined(__int64)) +#if (defined(__x86_64__) || defined(__i386__)) +#define __int64 long long +#else +#define __int64 int64_t +#endif +#endif + /* type-safe casting between types */ #define vreinterpretq_m128_f16(x) vreinterpretq_f32_f16(x) @@ -301,10 +342,10 @@ typedef int64x2_t __m128i; /* 128-bit vector containing integers */ #endif // A struct is defined in this header file called 'SIMDVec' which can be used -// by applications which attempt to access the contents of an _m128 struct +// by applications which attempt to access the contents of an __m128 struct // directly. It is important to note that accessing the __m128 struct directly // is bad coding practice by Microsoft: @see: -// https://msdn.microsoft.com/en-us/library/ayeb3ayc.aspx +// https://docs.microsoft.com/en-us/cpp/cpp/m128 // // However, some legacy source code may try to access the contents of an __m128 // struct directly so the developer can use the SIMDVec as an alias for it. Any @@ -340,13 +381,48 @@ typedef union ALIGN_STRUCT(16) SIMDVec { #define vreinterpretq_nth_u32_m128i(x, n) (((SIMDVec *) &x)->m128_u32[n]) #define vreinterpretq_nth_u8_m128i(x, n) (((SIMDVec *) &x)->m128_u8[n]) +/* SSE macros */ +#define _MM_GET_FLUSH_ZERO_MODE _sse2neon_mm_get_flush_zero_mode +#define _MM_SET_FLUSH_ZERO_MODE _sse2neon_mm_set_flush_zero_mode +#define _MM_GET_DENORMALS_ZERO_MODE _sse2neon_mm_get_denormals_zero_mode +#define _MM_SET_DENORMALS_ZERO_MODE _sse2neon_mm_set_denormals_zero_mode + +// Function declaration +// SSE +FORCE_INLINE unsigned int _MM_GET_ROUNDING_MODE(); +FORCE_INLINE __m128 _mm_move_ss(__m128, __m128); +FORCE_INLINE __m128 _mm_or_ps(__m128, __m128); +FORCE_INLINE __m128 _mm_set_ps1(float); +FORCE_INLINE __m128 _mm_setzero_ps(void); +// SSE2 +FORCE_INLINE __m128i _mm_and_si128(__m128i, __m128i); +FORCE_INLINE __m128i _mm_castps_si128(__m128); +FORCE_INLINE __m128i _mm_cmpeq_epi32(__m128i, __m128i); +FORCE_INLINE __m128i _mm_cvtps_epi32(__m128); +FORCE_INLINE __m128d _mm_move_sd(__m128d, __m128d); +FORCE_INLINE __m128i _mm_or_si128(__m128i, __m128i); +FORCE_INLINE __m128i _mm_set_epi32(int, int, int, int); +FORCE_INLINE __m128i _mm_set_epi64x(int64_t, int64_t); +FORCE_INLINE __m128d _mm_set_pd(double, double); +FORCE_INLINE __m128i _mm_set1_epi32(int); +FORCE_INLINE __m128i _mm_setzero_si128(); +// SSE4.1 +FORCE_INLINE __m128d _mm_ceil_pd(__m128d); +FORCE_INLINE __m128 _mm_ceil_ps(__m128); +FORCE_INLINE __m128d _mm_floor_pd(__m128d); +FORCE_INLINE __m128 _mm_floor_ps(__m128); +FORCE_INLINE __m128d _mm_round_pd(__m128d, int); +FORCE_INLINE __m128 _mm_round_ps(__m128, int); +// SSE4.2 +FORCE_INLINE uint32_t _mm_crc32_u8(uint32_t, uint8_t); + /* Backwards compatibility for compilers with lack of specific type support */ // Older gcc does not define vld1q_u8_x4 type -#if defined(__GNUC__) && !defined(__clang__) && \ - ((__GNUC__ == 10 && (__GNUC_MINOR__ <= 1)) || \ - (__GNUC__ == 9 && (__GNUC_MINOR__ <= 3)) || \ - (__GNUC__ == 8 && (__GNUC_MINOR__ <= 4)) || __GNUC__ <= 7) +#if defined(__GNUC__) && !defined(__clang__) && \ + ((__GNUC__ <= 10 && defined(__arm__)) || \ + (__GNUC__ == 10 && __GNUC_MINOR__ < 3 && defined(__aarch64__)) || \ + (__GNUC__ <= 9 && defined(__aarch64__))) FORCE_INLINE uint8x16x4_t _sse2neon_vld1q_u8_x4(const uint8_t *p) { uint8x16x4_t ret; @@ -441,8 +517,6 @@ FORCE_INLINE uint8x16x4_t _sse2neon_vld1q_u8_x4(const uint8_t *p) +------+------+------+------+------+------+-------------+ */ -/* Set/get methods */ - /* Constants for use with _mm_prefetch. */ enum _mm_hint { _MM_HINT_NTA = 0, /* load data to L1 and L2 cache, mark it as NTA */ @@ -455,1323 +529,18 @@ enum _mm_hint { _MM_HINT_ET2 = 7 /* exclusive version of _MM_HINT_T2 */ }; -// Loads one cache line of data from address p to a location closer to the -// processor. https://msdn.microsoft.com/en-us/library/84szxsww(v=vs.100).aspx -FORCE_INLINE void _mm_prefetch(const void *p, int i) -{ - (void) i; - __builtin_prefetch(p); -} - -// Pause the processor. This is typically used in spin-wait loops and depending -// on the x86 processor typical values are in the 40-100 cycle range. The -// 'yield' instruction isn't a good fit beacuse it's effectively a nop on most -// Arm cores. Experience with several databases has shown has shown an 'isb' is -// a reasonable approximation. -FORCE_INLINE void _mm_pause() -{ - __asm__ __volatile__("isb\n"); -} - -// Copy the lower single-precision (32-bit) floating-point element of a to dst. -// -// dst[31:0] := a[31:0] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_f32 -FORCE_INLINE float _mm_cvtss_f32(__m128 a) -{ - return vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); -} - -// Convert the lower single-precision (32-bit) floating-point element in b to a -// double-precision (64-bit) floating-point element, store the result in the -// lower element of dst, and copy the upper element from a to the upper element -// of dst. -// -// dst[63:0] := Convert_FP32_To_FP64(b[31:0]) -// dst[127:64] := a[127:64] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_sd -FORCE_INLINE __m128d _mm_cvtss_sd(__m128d a, __m128 b) -{ - double d = (double) vgetq_lane_f32(vreinterpretq_f32_m128(b), 0); +// The bit field mapping to the FPCR(floating-point control register) +typedef struct { + uint16_t res0; + uint8_t res1 : 6; + uint8_t bit22 : 1; + uint8_t bit23 : 1; + uint8_t bit24 : 1; + uint8_t res2 : 7; #if defined(__aarch64__) - return vreinterpretq_m128d_f64( - vsetq_lane_f64(d, vreinterpretq_f64_m128d(a), 0)); -#else - return vreinterpretq_m128d_s64( - vsetq_lane_s64(*(int64_t *) &d, vreinterpretq_s64_m128d(a), 0)); + uint32_t res3; #endif -} - -// Convert the lower single-precision (32-bit) floating-point element in a to a -// 32-bit integer, and store the result in dst. -// -// dst[31:0] := Convert_FP32_To_Int32(a[31:0]) -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_si32 -#define _mm_cvtss_si32(a) _mm_cvt_ss2si(a) - -// Convert the lower single-precision (32-bit) floating-point element in a to a -// 64-bit integer, and store the result in dst. -// -// dst[63:0] := Convert_FP32_To_Int64(a[31:0]) -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_si64 -FORCE_INLINE int _mm_cvtss_si64(__m128 a) -{ -#if defined(__aarch64__) - return vgetq_lane_s64( - vreinterpretq_s64_s32(vcvtnq_s32_f32(vreinterpretq_f32_m128(a))), 0); -#else - float32_t data = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); - float32_t diff = data - floor(data); - if (diff > 0.5) - return (int64_t) ceil(data); - if (unlikely(diff == 0.5)) { - int64_t f = (int64_t) floor(data); - int64_t c = (int64_t) ceil(data); - return c & 1 ? f : c; - } - return (int64_t) floor(data); -#endif -} - -// Convert packed single-precision (32-bit) floating-point elements in a to -// packed 32-bit integers with truncation, and store the results in dst. -// -// FOR j := 0 to 1 -// i := 32*j -// dst[i+31:i] := Convert_FP32_To_Int32_Truncate(a[i+31:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtt_ps2pi -FORCE_INLINE __m64 _mm_cvtt_ps2pi(__m128 a) -{ - return vreinterpret_m64_s32( - vget_low_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a)))); -} - -// Convert the lower single-precision (32-bit) floating-point element in a to a -// 32-bit integer with truncation, and store the result in dst. -// -// dst[31:0] := Convert_FP32_To_Int32_Truncate(a[31:0]) -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtt_ss2si -FORCE_INLINE int _mm_cvtt_ss2si(__m128 a) -{ - return vgetq_lane_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a)), 0); -} - -// Convert packed single-precision (32-bit) floating-point elements in a to -// packed 32-bit integers with truncation, and store the results in dst. -// -// FOR j := 0 to 1 -// i := 32*j -// dst[i+31:i] := Convert_FP32_To_Int32_Truncate(a[i+31:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttps_pi32 -#define _mm_cvttps_pi32(a) _mm_cvtt_ps2pi(a) - -// Convert the lower single-precision (32-bit) floating-point element in a to a -// 32-bit integer with truncation, and store the result in dst. -// -// dst[31:0] := Convert_FP32_To_Int32_Truncate(a[31:0]) -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttss_si32 -#define _mm_cvttss_si32(a) _mm_cvtt_ss2si(a) - -// Convert the lower single-precision (32-bit) floating-point element in a to a -// 64-bit integer with truncation, and store the result in dst. -// -// dst[63:0] := Convert_FP32_To_Int64_Truncate(a[31:0]) -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttss_si64 -FORCE_INLINE int64_t _mm_cvttss_si64(__m128 a) -{ - return vgetq_lane_s64( - vmovl_s32(vget_low_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a)))), 0); -} - -// Sets the 128-bit value to zero -// https://msdn.microsoft.com/en-us/library/vstudio/ys7dw0kh(v=vs.100).aspx -FORCE_INLINE __m128i _mm_setzero_si128(void) -{ - return vreinterpretq_m128i_s32(vdupq_n_s32(0)); -} - -// Clears the four single-precision, floating-point values. -// https://msdn.microsoft.com/en-us/library/vstudio/tk1t2tbz(v=vs.100).aspx -FORCE_INLINE __m128 _mm_setzero_ps(void) -{ - return vreinterpretq_m128_f32(vdupq_n_f32(0)); -} - -// Return vector of type __m128d with all elements set to zero. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_setzero_pd -FORCE_INLINE __m128d _mm_setzero_pd(void) -{ -#if defined(__aarch64__) - return vreinterpretq_m128d_f64(vdupq_n_f64(0)); -#else - return vreinterpretq_m128d_f32(vdupq_n_f32(0)); -#endif -} - -// Sets the four single-precision, floating-point values to w. -// -// r0 := r1 := r2 := r3 := w -// -// https://msdn.microsoft.com/en-us/library/vstudio/2x1se8ha(v=vs.100).aspx -FORCE_INLINE __m128 _mm_set1_ps(float _w) -{ - return vreinterpretq_m128_f32(vdupq_n_f32(_w)); -} - -// Sets the four single-precision, floating-point values to w. -// https://msdn.microsoft.com/en-us/library/vstudio/2x1se8ha(v=vs.100).aspx -FORCE_INLINE __m128 _mm_set_ps1(float _w) -{ - return vreinterpretq_m128_f32(vdupq_n_f32(_w)); -} - -// Sets the four single-precision, floating-point values to the four inputs. -// https://msdn.microsoft.com/en-us/library/vstudio/afh0zf75(v=vs.100).aspx -FORCE_INLINE __m128 _mm_set_ps(float w, float z, float y, float x) -{ - float ALIGN_STRUCT(16) data[4] = {x, y, z, w}; - return vreinterpretq_m128_f32(vld1q_f32(data)); -} - -// Copy single-precision (32-bit) floating-point element a to the lower element -// of dst, and zero the upper 3 elements. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_ss -FORCE_INLINE __m128 _mm_set_ss(float a) -{ - float ALIGN_STRUCT(16) data[4] = {a, 0, 0, 0}; - return vreinterpretq_m128_f32(vld1q_f32(data)); -} - -// Sets the four single-precision, floating-point values to the four inputs in -// reverse order. -// https://msdn.microsoft.com/en-us/library/vstudio/d2172ct3(v=vs.100).aspx -FORCE_INLINE __m128 _mm_setr_ps(float w, float z, float y, float x) -{ - float ALIGN_STRUCT(16) data[4] = {w, z, y, x}; - return vreinterpretq_m128_f32(vld1q_f32(data)); -} - -// Sets the 8 signed 16-bit integer values in reverse order. -// -// Return Value -// r0 := w0 -// r1 := w1 -// ... -// r7 := w7 -FORCE_INLINE __m128i _mm_setr_epi16(short w0, - short w1, - short w2, - short w3, - short w4, - short w5, - short w6, - short w7) -{ - int16_t ALIGN_STRUCT(16) data[8] = {w0, w1, w2, w3, w4, w5, w6, w7}; - return vreinterpretq_m128i_s16(vld1q_s16((int16_t *) data)); -} - -// Sets the 4 signed 32-bit integer values in reverse order -// https://technet.microsoft.com/en-us/library/security/27yb3ee5(v=vs.90).aspx -FORCE_INLINE __m128i _mm_setr_epi32(int i3, int i2, int i1, int i0) -{ - int32_t ALIGN_STRUCT(16) data[4] = {i3, i2, i1, i0}; - return vreinterpretq_m128i_s32(vld1q_s32(data)); -} - -// Set packed 64-bit integers in dst with the supplied values in reverse order. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_setr_epi64 -FORCE_INLINE __m128i _mm_setr_epi64(__m64 e1, __m64 e0) -{ - return vreinterpretq_m128i_s64(vcombine_s64(e1, e0)); -} - -// Sets the 16 signed 8-bit integer values to b. -// -// r0 := b -// r1 := b -// ... -// r15 := b -// -// https://msdn.microsoft.com/en-us/library/6e14xhyf(v=vs.100).aspx -FORCE_INLINE __m128i _mm_set1_epi8(signed char w) -{ - return vreinterpretq_m128i_s8(vdupq_n_s8(w)); -} - -// Broadcast double-precision (64-bit) floating-point value a to all elements of -// dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set1_pd -FORCE_INLINE __m128d _mm_set1_pd(double d) -{ -#if defined(__aarch64__) - return vreinterpretq_m128d_f64(vdupq_n_f64(d)); -#else - return vreinterpretq_m128d_s64(vdupq_n_s64(*(int64_t *) &d)); -#endif -} - -// Sets the 8 signed 16-bit integer values to w. -// -// r0 := w -// r1 := w -// ... -// r7 := w -// -// https://msdn.microsoft.com/en-us/library/k0ya3x0e(v=vs.90).aspx -FORCE_INLINE __m128i _mm_set1_epi16(short w) -{ - return vreinterpretq_m128i_s16(vdupq_n_s16(w)); -} - -// Sets the 16 signed 8-bit integer values. -// https://msdn.microsoft.com/en-us/library/x0cx8zd3(v=vs.90).aspx -FORCE_INLINE __m128i _mm_set_epi8(signed char b15, - signed char b14, - signed char b13, - signed char b12, - signed char b11, - signed char b10, - signed char b9, - signed char b8, - signed char b7, - signed char b6, - signed char b5, - signed char b4, - signed char b3, - signed char b2, - signed char b1, - signed char b0) -{ - int8_t ALIGN_STRUCT(16) - data[16] = {(int8_t) b0, (int8_t) b1, (int8_t) b2, (int8_t) b3, - (int8_t) b4, (int8_t) b5, (int8_t) b6, (int8_t) b7, - (int8_t) b8, (int8_t) b9, (int8_t) b10, (int8_t) b11, - (int8_t) b12, (int8_t) b13, (int8_t) b14, (int8_t) b15}; - return (__m128i) vld1q_s8(data); -} - -// Sets the 8 signed 16-bit integer values. -// https://msdn.microsoft.com/en-au/library/3e0fek84(v=vs.90).aspx -FORCE_INLINE __m128i _mm_set_epi16(short i7, - short i6, - short i5, - short i4, - short i3, - short i2, - short i1, - short i0) -{ - int16_t ALIGN_STRUCT(16) data[8] = {i0, i1, i2, i3, i4, i5, i6, i7}; - return vreinterpretq_m128i_s16(vld1q_s16(data)); -} - -// Sets the 16 signed 8-bit integer values in reverse order. -// https://msdn.microsoft.com/en-us/library/2khb9c7k(v=vs.90).aspx -FORCE_INLINE __m128i _mm_setr_epi8(signed char b0, - signed char b1, - signed char b2, - signed char b3, - signed char b4, - signed char b5, - signed char b6, - signed char b7, - signed char b8, - signed char b9, - signed char b10, - signed char b11, - signed char b12, - signed char b13, - signed char b14, - signed char b15) -{ - int8_t ALIGN_STRUCT(16) - data[16] = {(int8_t) b0, (int8_t) b1, (int8_t) b2, (int8_t) b3, - (int8_t) b4, (int8_t) b5, (int8_t) b6, (int8_t) b7, - (int8_t) b8, (int8_t) b9, (int8_t) b10, (int8_t) b11, - (int8_t) b12, (int8_t) b13, (int8_t) b14, (int8_t) b15}; - return (__m128i) vld1q_s8(data); -} - -// Sets the 4 signed 32-bit integer values to i. -// -// r0 := i -// r1 := i -// r2 := i -// r3 := I -// -// https://msdn.microsoft.com/en-us/library/vstudio/h4xscxat(v=vs.100).aspx -FORCE_INLINE __m128i _mm_set1_epi32(int _i) -{ - return vreinterpretq_m128i_s32(vdupq_n_s32(_i)); -} - -// Sets the 2 signed 64-bit integer values to i. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/whtfzhzk(v=vs.100) -FORCE_INLINE __m128i _mm_set1_epi64(__m64 _i) -{ - return vreinterpretq_m128i_s64(vdupq_n_s64((int64_t) _i)); -} - -// Sets the 2 signed 64-bit integer values to i. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set1_epi64x -FORCE_INLINE __m128i _mm_set1_epi64x(int64_t _i) -{ - return vreinterpretq_m128i_s64(vdupq_n_s64(_i)); -} - -// Sets the 4 signed 32-bit integer values. -// https://msdn.microsoft.com/en-us/library/vstudio/019beekt(v=vs.100).aspx -FORCE_INLINE __m128i _mm_set_epi32(int i3, int i2, int i1, int i0) -{ - int32_t ALIGN_STRUCT(16) data[4] = {i0, i1, i2, i3}; - return vreinterpretq_m128i_s32(vld1q_s32(data)); -} - -// Returns the __m128i structure with its two 64-bit integer values -// initialized to the values of the two 64-bit integers passed in. -// https://msdn.microsoft.com/en-us/library/dk2sdw0h(v=vs.120).aspx -FORCE_INLINE __m128i _mm_set_epi64x(int64_t i1, int64_t i2) -{ - return vreinterpretq_m128i_s64( - vcombine_s64(vcreate_s64(i2), vcreate_s64(i1))); -} - -// Returns the __m128i structure with its two 64-bit integer values -// initialized to the values of the two 64-bit integers passed in. -// https://msdn.microsoft.com/en-us/library/dk2sdw0h(v=vs.120).aspx -FORCE_INLINE __m128i _mm_set_epi64(__m64 i1, __m64 i2) -{ - return _mm_set_epi64x((int64_t) i1, (int64_t) i2); -} - -// Set packed double-precision (64-bit) floating-point elements in dst with the -// supplied values. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_pd -FORCE_INLINE __m128d _mm_set_pd(double e1, double e0) -{ - double ALIGN_STRUCT(16) data[2] = {e0, e1}; -#if defined(__aarch64__) - return vreinterpretq_m128d_f64(vld1q_f64((float64_t *) data)); -#else - return vreinterpretq_m128d_f32(vld1q_f32((float32_t *) data)); -#endif -} - -// Set packed double-precision (64-bit) floating-point elements in dst with the -// supplied values in reverse order. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_setr_pd -FORCE_INLINE __m128d _mm_setr_pd(double e1, double e0) -{ - return _mm_set_pd(e0, e1); -} - -// Copy double-precision (64-bit) floating-point element a to the lower element -// of dst, and zero the upper element. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_sd -FORCE_INLINE __m128d _mm_set_sd(double a) -{ - return _mm_set_pd(0, a); -} - -// Broadcast double-precision (64-bit) floating-point value a to all elements of -// dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_pd1 -#define _mm_set_pd1 _mm_set1_pd - -// Stores four single-precision, floating-point values. -// https://msdn.microsoft.com/en-us/library/vstudio/s3h4ay6y(v=vs.100).aspx -FORCE_INLINE void _mm_store_ps(float *p, __m128 a) -{ - vst1q_f32(p, vreinterpretq_f32_m128(a)); -} - -// Store the lower single-precision (32-bit) floating-point element from a into -// 4 contiguous elements in memory. mem_addr must be aligned on a 16-byte -// boundary or a general-protection exception may be generated. -// -// MEM[mem_addr+31:mem_addr] := a[31:0] -// MEM[mem_addr+63:mem_addr+32] := a[31:0] -// MEM[mem_addr+95:mem_addr+64] := a[31:0] -// MEM[mem_addr+127:mem_addr+96] := a[31:0] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store_ps1 -FORCE_INLINE void _mm_store_ps1(float *p, __m128 a) -{ - float32_t a0 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); - vst1q_f32(p, vdupq_n_f32(a0)); -} - -// Store the lower single-precision (32-bit) floating-point element from a into -// 4 contiguous elements in memory. mem_addr must be aligned on a 16-byte -// boundary or a general-protection exception may be generated. -// -// MEM[mem_addr+31:mem_addr] := a[31:0] -// MEM[mem_addr+63:mem_addr+32] := a[31:0] -// MEM[mem_addr+95:mem_addr+64] := a[31:0] -// MEM[mem_addr+127:mem_addr+96] := a[31:0] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store1_ps -#define _mm_store1_ps _mm_store_ps1 - -// Store 4 single-precision (32-bit) floating-point elements from a into memory -// in reverse order. mem_addr must be aligned on a 16-byte boundary or a -// general-protection exception may be generated. -// -// MEM[mem_addr+31:mem_addr] := a[127:96] -// MEM[mem_addr+63:mem_addr+32] := a[95:64] -// MEM[mem_addr+95:mem_addr+64] := a[63:32] -// MEM[mem_addr+127:mem_addr+96] := a[31:0] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storer_ps -FORCE_INLINE void _mm_storer_ps(float *p, __m128 a) -{ - float32x4_t tmp = vrev64q_f32(vreinterpretq_f32_m128(a)); - float32x4_t rev = vextq_f32(tmp, tmp, 2); - vst1q_f32(p, rev); -} - -// Stores four single-precision, floating-point values. -// https://msdn.microsoft.com/en-us/library/44e30x22(v=vs.100).aspx -FORCE_INLINE void _mm_storeu_ps(float *p, __m128 a) -{ - vst1q_f32(p, vreinterpretq_f32_m128(a)); -} - -// Stores four 32-bit integer values as (as a __m128i value) at the address p. -// https://msdn.microsoft.com/en-us/library/vstudio/edk11s13(v=vs.100).aspx -FORCE_INLINE void _mm_store_si128(__m128i *p, __m128i a) -{ - vst1q_s32((int32_t *) p, vreinterpretq_s32_m128i(a)); -} - -// Stores 128-bits of integer data a at the address p. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_si128 -FORCE_INLINE void _mm_storeu_si128(__m128i *p, __m128i a) -{ - vst1q_s32((int32_t *) p, vreinterpretq_s32_m128i(a)); -} - -// Stores 64-bits of integer data a at the address p. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_si64 -FORCE_INLINE void _mm_storeu_si64(void *p, __m128i a) -{ - vst1q_lane_s64((int64_t *) p, vreinterpretq_s64_m128i(a), 0); -} - -// Stores 32-bits of integer data a at the address p. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_si32 -FORCE_INLINE void _mm_storeu_si32(void *p, __m128i a) -{ - vst1q_lane_s32((int32_t *) p, vreinterpretq_s32_m128i(a), 0); -} - -// Stores 16-bits of integer data a at the address p. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_si16 -FORCE_INLINE void _mm_storeu_si16(void *p, __m128i a) -{ - vst1q_lane_s16((int16_t *) p, vreinterpretq_s16_m128i(a), 0); -} - -// Stores the lower single - precision, floating - point value. -// https://msdn.microsoft.com/en-us/library/tzz10fbx(v=vs.100).aspx -FORCE_INLINE void _mm_store_ss(float *p, __m128 a) -{ - vst1q_lane_f32(p, vreinterpretq_f32_m128(a), 0); -} - -// Store 128-bits (composed of 2 packed double-precision (64-bit) floating-point -// elements) from a into memory. mem_addr must be aligned on a 16-byte boundary -// or a general-protection exception may be generated. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store_pd -FORCE_INLINE void _mm_store_pd(double *mem_addr, __m128d a) -{ -#if defined(__aarch64__) - vst1q_f64((float64_t *) mem_addr, vreinterpretq_f64_m128d(a)); -#else - vst1q_f32((float32_t *) mem_addr, vreinterpretq_f32_m128d(a)); -#endif -} - -// Store the upper double-precision (64-bit) floating-point element from a into -// memory. -// -// MEM[mem_addr+63:mem_addr] := a[127:64] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeh_pd -FORCE_INLINE void _mm_storeh_pd(double *mem_addr, __m128d a) -{ -#if defined(__aarch64__) - vst1_f64((float64_t *) mem_addr, vget_high_f64(vreinterpretq_f64_m128d(a))); -#else - vst1_f32((float32_t *) mem_addr, vget_high_f32(vreinterpretq_f32_m128d(a))); -#endif -} - -// Store the lower double-precision (64-bit) floating-point element from a into -// memory. -// -// MEM[mem_addr+63:mem_addr] := a[63:0] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storel_pd -FORCE_INLINE void _mm_storel_pd(double *mem_addr, __m128d a) -{ -#if defined(__aarch64__) - vst1_f64((float64_t *) mem_addr, vget_low_f64(vreinterpretq_f64_m128d(a))); -#else - vst1_f32((float32_t *) mem_addr, vget_low_f32(vreinterpretq_f32_m128d(a))); -#endif -} - -// Store 2 double-precision (64-bit) floating-point elements from a into memory -// in reverse order. mem_addr must be aligned on a 16-byte boundary or a -// general-protection exception may be generated. -// -// MEM[mem_addr+63:mem_addr] := a[127:64] -// MEM[mem_addr+127:mem_addr+64] := a[63:0] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storer_pd -FORCE_INLINE void _mm_storer_pd(double *mem_addr, __m128d a) -{ - float32x4_t f = vreinterpretq_f32_m128d(a); - _mm_store_pd(mem_addr, vreinterpretq_m128d_f32(vextq_f32(f, f, 2))); -} - -// Store the lower double-precision (64-bit) floating-point element from a into -// 2 contiguous elements in memory. mem_addr must be aligned on a 16-byte -// boundary or a general-protection exception may be generated. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store_pd1 -FORCE_INLINE void _mm_store_pd1(double *mem_addr, __m128d a) -{ -#if defined(__aarch64__) - float64x1_t a_low = vget_low_f64(vreinterpretq_f64_m128d(a)); - vst1q_f64((float64_t *) mem_addr, - vreinterpretq_f64_m128d(vcombine_f64(a_low, a_low))); -#else - float32x2_t a_low = vget_low_f32(vreinterpretq_f32_m128d(a)); - vst1q_f32((float32_t *) mem_addr, - vreinterpretq_f32_m128d(vcombine_f32(a_low, a_low))); -#endif -} - -// Store the lower double-precision (64-bit) floating-point element from a into -// memory. mem_addr does not need to be aligned on any particular boundary. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_store_sd -FORCE_INLINE void _mm_store_sd(double *mem_addr, __m128d a) -{ -#if defined(__aarch64__) - vst1_f64((float64_t *) mem_addr, vget_low_f64(vreinterpretq_f64_m128d(a))); -#else - vst1_u64((uint64_t *) mem_addr, vget_low_u64(vreinterpretq_u64_m128d(a))); -#endif -} - -// Store the lower double-precision (64-bit) floating-point element from a into -// 2 contiguous elements in memory. mem_addr must be aligned on a 16-byte -// boundary or a general-protection exception may be generated. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#expand=9,526,5601&text=_mm_store1_pd -#define _mm_store1_pd _mm_store_pd1 - -// Store 128-bits (composed of 2 packed double-precision (64-bit) floating-point -// elements) from a into memory. mem_addr does not need to be aligned on any -// particular boundary. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_pd -FORCE_INLINE void _mm_storeu_pd(double *mem_addr, __m128d a) -{ - _mm_store_pd(mem_addr, a); -} - -// Reads the lower 64 bits of b and stores them into the lower 64 bits of a. -// https://msdn.microsoft.com/en-us/library/hhwf428f%28v=vs.90%29.aspx -FORCE_INLINE void _mm_storel_epi64(__m128i *a, __m128i b) -{ - uint64x1_t hi = vget_high_u64(vreinterpretq_u64_m128i(*a)); - uint64x1_t lo = vget_low_u64(vreinterpretq_u64_m128i(b)); - *a = vreinterpretq_m128i_u64(vcombine_u64(lo, hi)); -} - -// Stores the lower two single-precision floating point values of a to the -// address p. -// -// *p0 := a0 -// *p1 := a1 -// -// https://msdn.microsoft.com/en-us/library/h54t98ks(v=vs.90).aspx -FORCE_INLINE void _mm_storel_pi(__m64 *p, __m128 a) -{ - *p = vreinterpret_m64_f32(vget_low_f32(a)); -} - -// Stores the upper two single-precision, floating-point values of a to the -// address p. -// -// *p0 := a2 -// *p1 := a3 -// -// https://msdn.microsoft.com/en-us/library/a7525fs8(v%3dvs.90).aspx -FORCE_INLINE void _mm_storeh_pi(__m64 *p, __m128 a) -{ - *p = vreinterpret_m64_f32(vget_high_f32(a)); -} - -// Loads a single single-precision, floating-point value, copying it into all -// four words -// https://msdn.microsoft.com/en-us/library/vstudio/5cdkf716(v=vs.100).aspx -FORCE_INLINE __m128 _mm_load1_ps(const float *p) -{ - return vreinterpretq_m128_f32(vld1q_dup_f32(p)); -} - -// Load a single-precision (32-bit) floating-point element from memory into all -// elements of dst. -// -// dst[31:0] := MEM[mem_addr+31:mem_addr] -// dst[63:32] := MEM[mem_addr+31:mem_addr] -// dst[95:64] := MEM[mem_addr+31:mem_addr] -// dst[127:96] := MEM[mem_addr+31:mem_addr] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_ps1 -#define _mm_load_ps1 _mm_load1_ps - -// Sets the lower two single-precision, floating-point values with 64 -// bits of data loaded from the address p; the upper two values are passed -// through from a. -// -// Return Value -// r0 := *p0 -// r1 := *p1 -// r2 := a2 -// r3 := a3 -// -// https://msdn.microsoft.com/en-us/library/s57cyak2(v=vs.100).aspx -FORCE_INLINE __m128 _mm_loadl_pi(__m128 a, __m64 const *p) -{ - return vreinterpretq_m128_f32( - vcombine_f32(vld1_f32((const float32_t *) p), vget_high_f32(a))); -} - -// Load 4 single-precision (32-bit) floating-point elements from memory into dst -// in reverse order. mem_addr must be aligned on a 16-byte boundary or a -// general-protection exception may be generated. -// -// dst[31:0] := MEM[mem_addr+127:mem_addr+96] -// dst[63:32] := MEM[mem_addr+95:mem_addr+64] -// dst[95:64] := MEM[mem_addr+63:mem_addr+32] -// dst[127:96] := MEM[mem_addr+31:mem_addr] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadr_ps -FORCE_INLINE __m128 _mm_loadr_ps(const float *p) -{ - float32x4_t v = vrev64q_f32(vld1q_f32(p)); - return vreinterpretq_m128_f32(vextq_f32(v, v, 2)); -} - -// Sets the upper two single-precision, floating-point values with 64 -// bits of data loaded from the address p; the lower two values are passed -// through from a. -// -// r0 := a0 -// r1 := a1 -// r2 := *p0 -// r3 := *p1 -// -// https://msdn.microsoft.com/en-us/library/w92wta0x(v%3dvs.100).aspx -FORCE_INLINE __m128 _mm_loadh_pi(__m128 a, __m64 const *p) -{ - return vreinterpretq_m128_f32( - vcombine_f32(vget_low_f32(a), vld1_f32((const float32_t *) p))); -} - -// Loads four single-precision, floating-point values. -// https://msdn.microsoft.com/en-us/library/vstudio/zzd50xxt(v=vs.100).aspx -FORCE_INLINE __m128 _mm_load_ps(const float *p) -{ - return vreinterpretq_m128_f32(vld1q_f32(p)); -} - -// Loads four single-precision, floating-point values. -// https://msdn.microsoft.com/en-us/library/x1b16s7z%28v=vs.90%29.aspx -FORCE_INLINE __m128 _mm_loadu_ps(const float *p) -{ - // for neon, alignment doesn't matter, so _mm_load_ps and _mm_loadu_ps are - // equivalent for neon - return vreinterpretq_m128_f32(vld1q_f32(p)); -} - -// Load unaligned 16-bit integer from memory into the first element of dst. -// -// dst[15:0] := MEM[mem_addr+15:mem_addr] -// dst[MAX:16] := 0 -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_si16 -FORCE_INLINE __m128i _mm_loadu_si16(const void *p) -{ - return vreinterpretq_m128i_s16( - vsetq_lane_s16(*(const int16_t *) p, vdupq_n_s16(0), 0)); -} - -// Load unaligned 64-bit integer from memory into the first element of dst. -// -// dst[63:0] := MEM[mem_addr+63:mem_addr] -// dst[MAX:64] := 0 -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_si64 -FORCE_INLINE __m128i _mm_loadu_si64(const void *p) -{ - return vreinterpretq_m128i_s64( - vcombine_s64(vld1_s64((const int64_t *) p), vdup_n_s64(0))); -} - -// Load a double-precision (64-bit) floating-point element from memory into the -// lower of dst, and zero the upper element. mem_addr does not need to be -// aligned on any particular boundary. -// -// dst[63:0] := MEM[mem_addr+63:mem_addr] -// dst[127:64] := 0 -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_sd -FORCE_INLINE __m128d _mm_load_sd(const double *p) -{ -#if defined(__aarch64__) - return vreinterpretq_m128d_f64(vsetq_lane_f64(*p, vdupq_n_f64(0), 0)); -#else - const float *fp = (const float *) p; - float ALIGN_STRUCT(16) data[4] = {fp[0], fp[1], 0, 0}; - return vreinterpretq_m128d_f32(vld1q_f32(data)); -#endif -} - -// Loads two double-precision from 16-byte aligned memory, floating-point -// values. -// -// dst[127:0] := MEM[mem_addr+127:mem_addr] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_pd -FORCE_INLINE __m128d _mm_load_pd(const double *p) -{ -#if defined(__aarch64__) - return vreinterpretq_m128d_f64(vld1q_f64(p)); -#else - const float *fp = (const float *) p; - float ALIGN_STRUCT(16) data[4] = {fp[0], fp[1], fp[2], fp[3]}; - return vreinterpretq_m128d_f32(vld1q_f32(data)); -#endif -} - -// Loads two double-precision from unaligned memory, floating-point values. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_pd -FORCE_INLINE __m128d _mm_loadu_pd(const double *p) -{ - return _mm_load_pd(p); -} - -// Loads an single - precision, floating - point value into the low word and -// clears the upper three words. -// https://msdn.microsoft.com/en-us/library/548bb9h4%28v=vs.90%29.aspx -FORCE_INLINE __m128 _mm_load_ss(const float *p) -{ - return vreinterpretq_m128_f32(vsetq_lane_f32(*p, vdupq_n_f32(0), 0)); -} - -// Load 64-bit integer from memory into the first element of dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadl_epi64 -FORCE_INLINE __m128i _mm_loadl_epi64(__m128i const *p) -{ - /* Load the lower 64 bits of the value pointed to by p into the - * lower 64 bits of the result, zeroing the upper 64 bits of the result. - */ - return vreinterpretq_m128i_s32( - vcombine_s32(vld1_s32((int32_t const *) p), vcreate_s32(0))); -} - -// Load a double-precision (64-bit) floating-point element from memory into the -// lower element of dst, and copy the upper element from a to dst. mem_addr does -// not need to be aligned on any particular boundary. -// -// dst[63:0] := MEM[mem_addr+63:mem_addr] -// dst[127:64] := a[127:64] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadl_pd -FORCE_INLINE __m128d _mm_loadl_pd(__m128d a, const double *p) -{ -#if defined(__aarch64__) - return vreinterpretq_m128d_f64( - vcombine_f64(vld1_f64(p), vget_high_f64(vreinterpretq_f64_m128d(a)))); -#else - return vreinterpretq_m128d_f32( - vcombine_f32(vld1_f32((const float *) p), - vget_high_f32(vreinterpretq_f32_m128d(a)))); -#endif -} - -// Load 2 double-precision (64-bit) floating-point elements from memory into dst -// in reverse order. mem_addr must be aligned on a 16-byte boundary or a -// general-protection exception may be generated. -// -// dst[63:0] := MEM[mem_addr+127:mem_addr+64] -// dst[127:64] := MEM[mem_addr+63:mem_addr] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadr_pd -FORCE_INLINE __m128d _mm_loadr_pd(const double *p) -{ -#if defined(__aarch64__) - float64x2_t v = vld1q_f64(p); - return vreinterpretq_m128d_f64(vextq_f64(v, v, 1)); -#else - int64x2_t v = vld1q_s64((const int64_t *) p); - return vreinterpretq_m128d_s64(vextq_s64(v, v, 1)); -#endif -} - -// Sets the low word to the single-precision, floating-point value of b -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/35hdzazd(v=vs.100) -FORCE_INLINE __m128 _mm_move_ss(__m128 a, __m128 b) -{ - return vreinterpretq_m128_f32( - vsetq_lane_f32(vgetq_lane_f32(vreinterpretq_f32_m128(b), 0), - vreinterpretq_f32_m128(a), 0)); -} - -// Move the lower double-precision (64-bit) floating-point element from b to the -// lower element of dst, and copy the upper element from a to the upper element -// of dst. -// -// dst[63:0] := b[63:0] -// dst[127:64] := a[127:64] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_move_sd -FORCE_INLINE __m128d _mm_move_sd(__m128d a, __m128d b) -{ - return vreinterpretq_m128d_f32( - vcombine_f32(vget_low_f32(vreinterpretq_f32_m128d(b)), - vget_high_f32(vreinterpretq_f32_m128d(a)))); -} - -// Copy the lower 64-bit integer in a to the lower element of dst, and zero the -// upper element. -// -// dst[63:0] := a[63:0] -// dst[127:64] := 0 -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_move_epi64 -FORCE_INLINE __m128i _mm_move_epi64(__m128i a) -{ - return vreinterpretq_m128i_s64( - vsetq_lane_s64(0, vreinterpretq_s64_m128i(a), 1)); -} - -// Return vector of type __m128 with undefined elements. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_undefined_ps -FORCE_INLINE __m128 _mm_undefined_ps(void) -{ -#if defined(__GNUC__) || defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wuninitialized" -#endif - __m128 a; - return a; -#if defined(__GNUC__) || defined(__clang__) -#pragma GCC diagnostic pop -#endif -} - -/* Logic/Binary operations */ - -// Computes the bitwise AND-NOT of the four single-precision, floating-point -// values of a and b. -// -// r0 := ~a0 & b0 -// r1 := ~a1 & b1 -// r2 := ~a2 & b2 -// r3 := ~a3 & b3 -// -// https://msdn.microsoft.com/en-us/library/vstudio/68h7wd02(v=vs.100).aspx -FORCE_INLINE __m128 _mm_andnot_ps(__m128 a, __m128 b) -{ - return vreinterpretq_m128_s32( - vbicq_s32(vreinterpretq_s32_m128(b), - vreinterpretq_s32_m128(a))); // *NOTE* argument swap -} - -// Compute the bitwise NOT of packed double-precision (64-bit) floating-point -// elements in a and then AND with b, and store the results in dst. -// -// FOR j := 0 to 1 -// i := j*64 -// dst[i+63:i] := ((NOT a[i+63:i]) AND b[i+63:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_andnot_pd -FORCE_INLINE __m128d _mm_andnot_pd(__m128d a, __m128d b) -{ - // *NOTE* argument swap - return vreinterpretq_m128d_s64( - vbicq_s64(vreinterpretq_s64_m128d(b), vreinterpretq_s64_m128d(a))); -} - -// Computes the bitwise AND of the 128-bit value in b and the bitwise NOT of the -// 128-bit value in a. -// -// r := (~a) & b -// -// https://msdn.microsoft.com/en-us/library/vstudio/1beaceh8(v=vs.100).aspx -FORCE_INLINE __m128i _mm_andnot_si128(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_s32( - vbicq_s32(vreinterpretq_s32_m128i(b), - vreinterpretq_s32_m128i(a))); // *NOTE* argument swap -} - -// Computes the bitwise AND of the 128-bit value in a and the 128-bit value in -// b. -// -// r := a & b -// -// https://msdn.microsoft.com/en-us/library/vstudio/6d1txsa8(v=vs.100).aspx -FORCE_INLINE __m128i _mm_and_si128(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_s32( - vandq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); -} - -// Computes the bitwise AND of the four single-precision, floating-point values -// of a and b. -// -// r0 := a0 & b0 -// r1 := a1 & b1 -// r2 := a2 & b2 -// r3 := a3 & b3 -// -// https://msdn.microsoft.com/en-us/library/vstudio/73ck1xc5(v=vs.100).aspx -FORCE_INLINE __m128 _mm_and_ps(__m128 a, __m128 b) -{ - return vreinterpretq_m128_s32( - vandq_s32(vreinterpretq_s32_m128(a), vreinterpretq_s32_m128(b))); -} - -// Compute the bitwise AND of packed double-precision (64-bit) floating-point -// elements in a and b, and store the results in dst. -// -// FOR j := 0 to 1 -// i := j*64 -// dst[i+63:i] := a[i+63:i] AND b[i+63:i] -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_and_pd -FORCE_INLINE __m128d _mm_and_pd(__m128d a, __m128d b) -{ - return vreinterpretq_m128d_s64( - vandq_s64(vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b))); -} - -// Computes the bitwise OR of the four single-precision, floating-point values -// of a and b. -// https://msdn.microsoft.com/en-us/library/vstudio/7ctdsyy0(v=vs.100).aspx -FORCE_INLINE __m128 _mm_or_ps(__m128 a, __m128 b) -{ - return vreinterpretq_m128_s32( - vorrq_s32(vreinterpretq_s32_m128(a), vreinterpretq_s32_m128(b))); -} - -// Computes bitwise EXOR (exclusive-or) of the four single-precision, -// floating-point values of a and b. -// https://msdn.microsoft.com/en-us/library/ss6k3wk8(v=vs.100).aspx -FORCE_INLINE __m128 _mm_xor_ps(__m128 a, __m128 b) -{ - return vreinterpretq_m128_s32( - veorq_s32(vreinterpretq_s32_m128(a), vreinterpretq_s32_m128(b))); -} - -// Compute the bitwise XOR of packed double-precision (64-bit) floating-point -// elements in a and b, and store the results in dst. -// -// FOR j := 0 to 1 -// i := j*64 -// dst[i+63:i] := a[i+63:i] XOR b[i+63:i] -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_xor_pd -FORCE_INLINE __m128d _mm_xor_pd(__m128d a, __m128d b) -{ - return vreinterpretq_m128d_s64( - veorq_s64(vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b))); -} - -// Compute the bitwise OR of packed double-precision (64-bit) floating-point -// elements in a and b, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_or_pd -FORCE_INLINE __m128d _mm_or_pd(__m128d a, __m128d b) -{ - return vreinterpretq_m128d_s64( - vorrq_s64(vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b))); -} - -// Computes the bitwise OR of the 128-bit value in a and the 128-bit value in b. -// -// r := a | b -// -// https://msdn.microsoft.com/en-us/library/vstudio/ew8ty0db(v=vs.100).aspx -FORCE_INLINE __m128i _mm_or_si128(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_s32( - vorrq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); -} - -// Computes the bitwise XOR of the 128-bit value in a and the 128-bit value in -// b. https://msdn.microsoft.com/en-us/library/fzt08www(v=vs.100).aspx -FORCE_INLINE __m128i _mm_xor_si128(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_s32( - veorq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); -} - -// Duplicate the low double-precision (64-bit) floating-point element from a, -// and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movedup_pd -FORCE_INLINE __m128d _mm_movedup_pd(__m128d a) -{ -#if (__aarch64__) - return vreinterpretq_m128d_f64( - vdupq_laneq_f64(vreinterpretq_f64_m128d(a), 0)); -#else - return vreinterpretq_m128d_u64( - vdupq_n_u64(vgetq_lane_u64(vreinterpretq_u64_m128d(a), 0))); -#endif -} - -// Duplicate odd-indexed single-precision (32-bit) floating-point elements -// from a, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movehdup_ps -FORCE_INLINE __m128 _mm_movehdup_ps(__m128 a) -{ -#if __has_builtin(__builtin_shufflevector) - return vreinterpretq_m128_f32(__builtin_shufflevector( - vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 1, 1, 3, 3)); -#else - float32_t a1 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 1); - float32_t a3 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 3); - float ALIGN_STRUCT(16) data[4] = {a1, a1, a3, a3}; - return vreinterpretq_m128_f32(vld1q_f32(data)); -#endif -} - -// Duplicate even-indexed single-precision (32-bit) floating-point elements -// from a, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_moveldup_ps -FORCE_INLINE __m128 _mm_moveldup_ps(__m128 a) -{ -#if __has_builtin(__builtin_shufflevector) - return vreinterpretq_m128_f32(__builtin_shufflevector( - vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 0, 0, 2, 2)); -#else - float32_t a0 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); - float32_t a2 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 2); - float ALIGN_STRUCT(16) data[4] = {a0, a0, a2, a2}; - return vreinterpretq_m128_f32(vld1q_f32(data)); -#endif -} - -// Moves the upper two values of B into the lower two values of A. -// -// r3 := a3 -// r2 := a2 -// r1 := b3 -// r0 := b2 -FORCE_INLINE __m128 _mm_movehl_ps(__m128 __A, __m128 __B) -{ - float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(__A)); - float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(__B)); - return vreinterpretq_m128_f32(vcombine_f32(b32, a32)); -} - -// Moves the lower two values of B into the upper two values of A. -// -// r3 := b1 -// r2 := b0 -// r1 := a1 -// r0 := a0 -FORCE_INLINE __m128 _mm_movelh_ps(__m128 __A, __m128 __B) -{ - float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(__A)); - float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(__B)); - return vreinterpretq_m128_f32(vcombine_f32(a10, b10)); -} - -// Create mask from the most significant bit of each 8-bit element in a, and -// store the result in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movemask_pi8 -FORCE_INLINE int _mm_movemask_pi8(__m64 a) -{ - uint8x8_t input = vreinterpret_u8_m64(a); -#if defined(__aarch64__) - static const int8x8_t shift = {0, 1, 2, 3, 4, 5, 6, 7}; - uint8x8_t tmp = vshr_n_u8(input, 7); - return vaddv_u8(vshl_u8(tmp, shift)); -#else - // Refer the implementation of `_mm_movemask_epi8` - uint16x4_t high_bits = vreinterpret_u16_u8(vshr_n_u8(input, 7)); - uint32x2_t paired16 = - vreinterpret_u32_u16(vsra_n_u16(high_bits, high_bits, 7)); - uint8x8_t paired32 = - vreinterpret_u8_u32(vsra_n_u32(paired16, paired16, 14)); - return vget_lane_u8(paired32, 0) | ((int) vget_lane_u8(paired32, 4) << 4); -#endif -} - -// Compute the absolute value of packed signed 32-bit integers in a, and store -// the unsigned results in dst. -// -// FOR j := 0 to 3 -// i := j*32 -// dst[i+31:i] := ABS(a[i+31:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_epi32 -FORCE_INLINE __m128i _mm_abs_epi32(__m128i a) -{ - return vreinterpretq_m128i_s32(vabsq_s32(vreinterpretq_s32_m128i(a))); -} - -// Compute the absolute value of packed signed 16-bit integers in a, and store -// the unsigned results in dst. -// -// FOR j := 0 to 7 -// i := j*16 -// dst[i+15:i] := ABS(a[i+15:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_epi16 -FORCE_INLINE __m128i _mm_abs_epi16(__m128i a) -{ - return vreinterpretq_m128i_s16(vabsq_s16(vreinterpretq_s16_m128i(a))); -} - -// Compute the absolute value of packed signed 8-bit integers in a, and store -// the unsigned results in dst. -// -// FOR j := 0 to 15 -// i := j*8 -// dst[i+7:i] := ABS(a[i+7:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_epi8 -FORCE_INLINE __m128i _mm_abs_epi8(__m128i a) -{ - return vreinterpretq_m128i_s8(vabsq_s8(vreinterpretq_s8_m128i(a))); -} - -// Compute the absolute value of packed signed 32-bit integers in a, and store -// the unsigned results in dst. -// -// FOR j := 0 to 1 -// i := j*32 -// dst[i+31:i] := ABS(a[i+31:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_pi32 -FORCE_INLINE __m64 _mm_abs_pi32(__m64 a) -{ - return vreinterpret_m64_s32(vabs_s32(vreinterpret_s32_m64(a))); -} - -// Compute the absolute value of packed signed 16-bit integers in a, and store -// the unsigned results in dst. -// -// FOR j := 0 to 3 -// i := j*16 -// dst[i+15:i] := ABS(a[i+15:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_pi16 -FORCE_INLINE __m64 _mm_abs_pi16(__m64 a) -{ - return vreinterpret_m64_s16(vabs_s16(vreinterpret_s16_m64(a))); -} - -// Compute the absolute value of packed signed 8-bit integers in a, and store -// the unsigned results in dst. -// -// FOR j := 0 to 7 -// i := j*8 -// dst[i+7:i] := ABS(a[i+7:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_pi8 -FORCE_INLINE __m64 _mm_abs_pi8(__m64 a) -{ - return vreinterpret_m64_s8(vabs_s8(vreinterpret_s8_m64(a))); -} - -// Concatenate 16-byte blocks in a and b into a 32-byte temporary result, shift -// the result right by imm8 bytes, and store the low 16 bytes in dst. -// -// tmp[255:0] := ((a[127:0] << 128)[255:0] OR b[127:0]) >> (imm8*8) -// dst[127:0] := tmp[127:0] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_alignr_epi8 -#define _mm_alignr_epi8(a, b, imm) \ - __extension__({ \ - __m128i ret; \ - if (unlikely((imm) >= 32)) { \ - ret = _mm_setzero_si128(); \ - } else { \ - uint8x16_t tmp_low, tmp_high; \ - if (imm >= 16) { \ - const int idx = imm - 16; \ - tmp_low = vreinterpretq_u8_m128i(a); \ - tmp_high = vdupq_n_u8(0); \ - ret = \ - vreinterpretq_m128i_u8(vextq_u8(tmp_low, tmp_high, idx)); \ - } else { \ - const int idx = imm; \ - tmp_low = vreinterpretq_u8_m128i(b); \ - tmp_high = vreinterpretq_u8_m128i(a); \ - ret = \ - vreinterpretq_m128i_u8(vextq_u8(tmp_low, tmp_high, idx)); \ - } \ - } \ - ret; \ - }) - -// Concatenate 8-byte blocks in a and b into a 16-byte temporary result, shift -// the result right by imm8 bytes, and store the low 8 bytes in dst. -// -// tmp[127:0] := ((a[63:0] << 64)[127:0] OR b[63:0]) >> (imm8*8) -// dst[63:0] := tmp[63:0] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_alignr_pi8 -#define _mm_alignr_pi8(a, b, imm) \ - __extension__({ \ - __m64 ret; \ - if (unlikely((imm) >= 16)) { \ - ret = vreinterpret_m64_s8(vdup_n_s8(0)); \ - } else { \ - uint8x8_t tmp_low, tmp_high; \ - if (imm >= 8) { \ - const int idx = imm - 8; \ - tmp_low = vreinterpret_u8_m64(a); \ - tmp_high = vdup_n_u8(0); \ - ret = vreinterpret_m64_u8(vext_u8(tmp_low, tmp_high, idx)); \ - } else { \ - const int idx = imm; \ - tmp_low = vreinterpret_u8_m64(b); \ - tmp_high = vreinterpret_u8_m64(a); \ - ret = vreinterpret_m64_u8(vext_u8(tmp_low, tmp_high, idx)); \ - } \ - } \ - ret; \ - }) +} fpcr_bitfield; // Takes the upper 64 bits of a and places it in the low end of the result // Takes the lower 64 bits of b and places it into the high end of the result. @@ -1908,6 +677,255 @@ FORCE_INLINE __m128 _mm_shuffle_ps_2032(__m128 a, __m128 b) return vreinterpretq_m128_f32(vcombine_f32(a32, b20)); } +// Kahan summation for accurate summation of floating-point numbers. +// http://blog.zachbjornson.com/2019/08/11/fast-float-summation.html +FORCE_INLINE void _sse2neon_kadd_f32(float *sum, float *c, float y) +{ + y -= *c; + float t = *sum + y; + *c = (t - *sum) - y; + *sum = t; +} + +#if defined(__ARM_FEATURE_CRYPTO) && \ + (defined(__aarch64__) || __has_builtin(__builtin_arm_crypto_vmullp64)) +// Wraps vmull_p64 +FORCE_INLINE uint64x2_t _sse2neon_vmull_p64(uint64x1_t _a, uint64x1_t _b) +{ + poly64_t a = vget_lane_p64(vreinterpret_p64_u64(_a), 0); + poly64_t b = vget_lane_p64(vreinterpret_p64_u64(_b), 0); + return vreinterpretq_u64_p128(vmull_p64(a, b)); +} +#else // ARMv7 polyfill +// ARMv7/some A64 lacks vmull_p64, but it has vmull_p8. +// +// vmull_p8 calculates 8 8-bit->16-bit polynomial multiplies, but we need a +// 64-bit->128-bit polynomial multiply. +// +// It needs some work and is somewhat slow, but it is still faster than all +// known scalar methods. +// +// Algorithm adapted to C from +// https://www.workofard.com/2017/07/ghash-for-low-end-cores/, which is adapted +// from "Fast Software Polynomial Multiplication on ARM Processors Using the +// NEON Engine" by Danilo Camara, Conrado Gouvea, Julio Lopez and Ricardo Dahab +// (https://hal.inria.fr/hal-01506572) +static uint64x2_t _sse2neon_vmull_p64(uint64x1_t _a, uint64x1_t _b) +{ + poly8x8_t a = vreinterpret_p8_u64(_a); + poly8x8_t b = vreinterpret_p8_u64(_b); + + // Masks + uint8x16_t k48_32 = vcombine_u8(vcreate_u8(0x0000ffffffffffff), + vcreate_u8(0x00000000ffffffff)); + uint8x16_t k16_00 = vcombine_u8(vcreate_u8(0x000000000000ffff), + vcreate_u8(0x0000000000000000)); + + // Do the multiplies, rotating with vext to get all combinations + uint8x16_t d = vreinterpretq_u8_p16(vmull_p8(a, b)); // D = A0 * B0 + uint8x16_t e = + vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 1))); // E = A0 * B1 + uint8x16_t f = + vreinterpretq_u8_p16(vmull_p8(vext_p8(a, a, 1), b)); // F = A1 * B0 + uint8x16_t g = + vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 2))); // G = A0 * B2 + uint8x16_t h = + vreinterpretq_u8_p16(vmull_p8(vext_p8(a, a, 2), b)); // H = A2 * B0 + uint8x16_t i = + vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 3))); // I = A0 * B3 + uint8x16_t j = + vreinterpretq_u8_p16(vmull_p8(vext_p8(a, a, 3), b)); // J = A3 * B0 + uint8x16_t k = + vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 4))); // L = A0 * B4 + + // Add cross products + uint8x16_t l = veorq_u8(e, f); // L = E + F + uint8x16_t m = veorq_u8(g, h); // M = G + H + uint8x16_t n = veorq_u8(i, j); // N = I + J + + // Interleave. Using vzip1 and vzip2 prevents Clang from emitting TBL + // instructions. +#if defined(__aarch64__) + uint8x16_t lm_p0 = vreinterpretq_u8_u64( + vzip1q_u64(vreinterpretq_u64_u8(l), vreinterpretq_u64_u8(m))); + uint8x16_t lm_p1 = vreinterpretq_u8_u64( + vzip2q_u64(vreinterpretq_u64_u8(l), vreinterpretq_u64_u8(m))); + uint8x16_t nk_p0 = vreinterpretq_u8_u64( + vzip1q_u64(vreinterpretq_u64_u8(n), vreinterpretq_u64_u8(k))); + uint8x16_t nk_p1 = vreinterpretq_u8_u64( + vzip2q_u64(vreinterpretq_u64_u8(n), vreinterpretq_u64_u8(k))); +#else + uint8x16_t lm_p0 = vcombine_u8(vget_low_u8(l), vget_low_u8(m)); + uint8x16_t lm_p1 = vcombine_u8(vget_high_u8(l), vget_high_u8(m)); + uint8x16_t nk_p0 = vcombine_u8(vget_low_u8(n), vget_low_u8(k)); + uint8x16_t nk_p1 = vcombine_u8(vget_high_u8(n), vget_high_u8(k)); +#endif + // t0 = (L) (P0 + P1) << 8 + // t1 = (M) (P2 + P3) << 16 + uint8x16_t t0t1_tmp = veorq_u8(lm_p0, lm_p1); + uint8x16_t t0t1_h = vandq_u8(lm_p1, k48_32); + uint8x16_t t0t1_l = veorq_u8(t0t1_tmp, t0t1_h); + + // t2 = (N) (P4 + P5) << 24 + // t3 = (K) (P6 + P7) << 32 + uint8x16_t t2t3_tmp = veorq_u8(nk_p0, nk_p1); + uint8x16_t t2t3_h = vandq_u8(nk_p1, k16_00); + uint8x16_t t2t3_l = veorq_u8(t2t3_tmp, t2t3_h); + + // De-interleave +#if defined(__aarch64__) + uint8x16_t t0 = vreinterpretq_u8_u64( + vuzp1q_u64(vreinterpretq_u64_u8(t0t1_l), vreinterpretq_u64_u8(t0t1_h))); + uint8x16_t t1 = vreinterpretq_u8_u64( + vuzp2q_u64(vreinterpretq_u64_u8(t0t1_l), vreinterpretq_u64_u8(t0t1_h))); + uint8x16_t t2 = vreinterpretq_u8_u64( + vuzp1q_u64(vreinterpretq_u64_u8(t2t3_l), vreinterpretq_u64_u8(t2t3_h))); + uint8x16_t t3 = vreinterpretq_u8_u64( + vuzp2q_u64(vreinterpretq_u64_u8(t2t3_l), vreinterpretq_u64_u8(t2t3_h))); +#else + uint8x16_t t1 = vcombine_u8(vget_high_u8(t0t1_l), vget_high_u8(t0t1_h)); + uint8x16_t t0 = vcombine_u8(vget_low_u8(t0t1_l), vget_low_u8(t0t1_h)); + uint8x16_t t3 = vcombine_u8(vget_high_u8(t2t3_l), vget_high_u8(t2t3_h)); + uint8x16_t t2 = vcombine_u8(vget_low_u8(t2t3_l), vget_low_u8(t2t3_h)); +#endif + // Shift the cross products + uint8x16_t t0_shift = vextq_u8(t0, t0, 15); // t0 << 8 + uint8x16_t t1_shift = vextq_u8(t1, t1, 14); // t1 << 16 + uint8x16_t t2_shift = vextq_u8(t2, t2, 13); // t2 << 24 + uint8x16_t t3_shift = vextq_u8(t3, t3, 12); // t3 << 32 + + // Accumulate the products + uint8x16_t cross1 = veorq_u8(t0_shift, t1_shift); + uint8x16_t cross2 = veorq_u8(t2_shift, t3_shift); + uint8x16_t mix = veorq_u8(d, cross1); + uint8x16_t r = veorq_u8(mix, cross2); + return vreinterpretq_u64_u8(r); +} +#endif // ARMv7 polyfill + +// C equivalent: +// __m128i _mm_shuffle_epi32_default(__m128i a, +// __constrange(0, 255) int imm) { +// __m128i ret; +// ret[0] = a[imm & 0x3]; ret[1] = a[(imm >> 2) & 0x3]; +// ret[2] = a[(imm >> 4) & 0x03]; ret[3] = a[(imm >> 6) & 0x03]; +// return ret; +// } +#define _mm_shuffle_epi32_default(a, imm) \ + __extension__({ \ + int32x4_t ret; \ + ret = vmovq_n_s32( \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm) & (0x3))); \ + ret = vsetq_lane_s32( \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 2) & 0x3), \ + ret, 1); \ + ret = vsetq_lane_s32( \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 4) & 0x3), \ + ret, 2); \ + ret = vsetq_lane_s32( \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 6) & 0x3), \ + ret, 3); \ + vreinterpretq_m128i_s32(ret); \ + }) + +// Takes the upper 64 bits of a and places it in the low end of the result +// Takes the lower 64 bits of a and places it into the high end of the result. +FORCE_INLINE __m128i _mm_shuffle_epi_1032(__m128i a) +{ + int32x2_t a32 = vget_high_s32(vreinterpretq_s32_m128i(a)); + int32x2_t a10 = vget_low_s32(vreinterpretq_s32_m128i(a)); + return vreinterpretq_m128i_s32(vcombine_s32(a32, a10)); +} + +// takes the lower two 32-bit values from a and swaps them and places in low end +// of result takes the higher two 32 bit values from a and swaps them and places +// in high end of result. +FORCE_INLINE __m128i _mm_shuffle_epi_2301(__m128i a) +{ + int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); + int32x2_t a23 = vrev64_s32(vget_high_s32(vreinterpretq_s32_m128i(a))); + return vreinterpretq_m128i_s32(vcombine_s32(a01, a23)); +} + +// rotates the least significant 32 bits into the most significant 32 bits, and +// shifts the rest down +FORCE_INLINE __m128i _mm_shuffle_epi_0321(__m128i a) +{ + return vreinterpretq_m128i_s32( + vextq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(a), 1)); +} + +// rotates the most significant 32 bits into the least significant 32 bits, and +// shifts the rest up +FORCE_INLINE __m128i _mm_shuffle_epi_2103(__m128i a) +{ + return vreinterpretq_m128i_s32( + vextq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(a), 3)); +} + +// gets the lower 64 bits of a, and places it in the upper 64 bits +// gets the lower 64 bits of a and places it in the lower 64 bits +FORCE_INLINE __m128i _mm_shuffle_epi_1010(__m128i a) +{ + int32x2_t a10 = vget_low_s32(vreinterpretq_s32_m128i(a)); + return vreinterpretq_m128i_s32(vcombine_s32(a10, a10)); +} + +// gets the lower 64 bits of a, swaps the 0 and 1 elements, and places it in the +// lower 64 bits gets the lower 64 bits of a, and places it in the upper 64 bits +FORCE_INLINE __m128i _mm_shuffle_epi_1001(__m128i a) +{ + int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); + int32x2_t a10 = vget_low_s32(vreinterpretq_s32_m128i(a)); + return vreinterpretq_m128i_s32(vcombine_s32(a01, a10)); +} + +// gets the lower 64 bits of a, swaps the 0 and 1 elements and places it in the +// upper 64 bits gets the lower 64 bits of a, swaps the 0 and 1 elements, and +// places it in the lower 64 bits +FORCE_INLINE __m128i _mm_shuffle_epi_0101(__m128i a) +{ + int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); + return vreinterpretq_m128i_s32(vcombine_s32(a01, a01)); +} + +FORCE_INLINE __m128i _mm_shuffle_epi_2211(__m128i a) +{ + int32x2_t a11 = vdup_lane_s32(vget_low_s32(vreinterpretq_s32_m128i(a)), 1); + int32x2_t a22 = vdup_lane_s32(vget_high_s32(vreinterpretq_s32_m128i(a)), 0); + return vreinterpretq_m128i_s32(vcombine_s32(a11, a22)); +} + +FORCE_INLINE __m128i _mm_shuffle_epi_0122(__m128i a) +{ + int32x2_t a22 = vdup_lane_s32(vget_high_s32(vreinterpretq_s32_m128i(a)), 0); + int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); + return vreinterpretq_m128i_s32(vcombine_s32(a22, a01)); +} + +FORCE_INLINE __m128i _mm_shuffle_epi_3332(__m128i a) +{ + int32x2_t a32 = vget_high_s32(vreinterpretq_s32_m128i(a)); + int32x2_t a33 = vdup_lane_s32(vget_high_s32(vreinterpretq_s32_m128i(a)), 1); + return vreinterpretq_m128i_s32(vcombine_s32(a32, a33)); +} + +// FORCE_INLINE __m128i _mm_shuffle_epi32_splat(__m128i a, __constrange(0,255) +// int imm) +#if defined(__aarch64__) +#define _mm_shuffle_epi32_splat(a, imm) \ + __extension__({ \ + vreinterpretq_m128i_s32( \ + vdupq_laneq_s32(vreinterpretq_s32_m128i(a), (imm))); \ + }) +#else +#define _mm_shuffle_epi32_splat(a, imm) \ + __extension__({ \ + vreinterpretq_m128i_s32( \ + vdupq_n_s32(vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm)))); \ + }) +#endif + // NEON does not support a general purpose permute intrinsic // Selects four specific single-precision, floating-point values from a and b, // based on the mask i. @@ -1939,6 +957,1595 @@ FORCE_INLINE __m128 _mm_shuffle_ps_2032(__m128 a, __m128 b) vreinterpretq_m128_f32(ret); \ }) +// Shuffles the lower 4 signed or unsigned 16-bit integers in a as specified +// by imm. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/y41dkk37(v=vs.100) +// FORCE_INLINE __m128i _mm_shufflelo_epi16_function(__m128i a, +// __constrange(0,255) int +// imm) +#define _mm_shufflelo_epi16_function(a, imm) \ + __extension__({ \ + int16x8_t ret = vreinterpretq_s16_m128i(a); \ + int16x4_t lowBits = vget_low_s16(ret); \ + ret = vsetq_lane_s16(vget_lane_s16(lowBits, (imm) & (0x3)), ret, 0); \ + ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 2) & 0x3), ret, \ + 1); \ + ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 4) & 0x3), ret, \ + 2); \ + ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 6) & 0x3), ret, \ + 3); \ + vreinterpretq_m128i_s16(ret); \ + }) + +// Shuffles the upper 4 signed or unsigned 16-bit integers in a as specified +// by imm. +// https://msdn.microsoft.com/en-us/library/13ywktbs(v=vs.100).aspx +// FORCE_INLINE __m128i _mm_shufflehi_epi16_function(__m128i a, +// __constrange(0,255) int +// imm) +#define _mm_shufflehi_epi16_function(a, imm) \ + __extension__({ \ + int16x8_t ret = vreinterpretq_s16_m128i(a); \ + int16x4_t highBits = vget_high_s16(ret); \ + ret = vsetq_lane_s16(vget_lane_s16(highBits, (imm) & (0x3)), ret, 4); \ + ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 2) & 0x3), ret, \ + 5); \ + ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 4) & 0x3), ret, \ + 6); \ + ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 6) & 0x3), ret, \ + 7); \ + vreinterpretq_m128i_s16(ret); \ + }) + +/* MMX */ + +//_mm_empty is a no-op on arm +FORCE_INLINE void _mm_empty(void) {} + +/* SSE */ + +// Adds the four single-precision, floating-point values of a and b. +// +// r0 := a0 + b0 +// r1 := a1 + b1 +// r2 := a2 + b2 +// r3 := a3 + b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/c9848chc(v=vs.100).aspx +FORCE_INLINE __m128 _mm_add_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_f32( + vaddq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// adds the scalar single-precision floating point values of a and b. +// https://msdn.microsoft.com/en-us/library/be94x2y6(v=vs.100).aspx +FORCE_INLINE __m128 _mm_add_ss(__m128 a, __m128 b) +{ + float32_t b0 = vgetq_lane_f32(vreinterpretq_f32_m128(b), 0); + float32x4_t value = vsetq_lane_f32(b0, vdupq_n_f32(0), 0); + // the upper values in the result must be the remnants of . + return vreinterpretq_m128_f32(vaddq_f32(a, value)); +} + +// Computes the bitwise AND of the four single-precision, floating-point values +// of a and b. +// +// r0 := a0 & b0 +// r1 := a1 & b1 +// r2 := a2 & b2 +// r3 := a3 & b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/73ck1xc5(v=vs.100).aspx +FORCE_INLINE __m128 _mm_and_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_s32( + vandq_s32(vreinterpretq_s32_m128(a), vreinterpretq_s32_m128(b))); +} + +// Computes the bitwise AND-NOT of the four single-precision, floating-point +// values of a and b. +// +// r0 := ~a0 & b0 +// r1 := ~a1 & b1 +// r2 := ~a2 & b2 +// r3 := ~a3 & b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/68h7wd02(v=vs.100).aspx +FORCE_INLINE __m128 _mm_andnot_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_s32( + vbicq_s32(vreinterpretq_s32_m128(b), + vreinterpretq_s32_m128(a))); // *NOTE* argument swap +} + +// Average packed unsigned 16-bit integers in a and b, and store the results in +// dst. +// +// FOR j := 0 to 3 +// i := j*16 +// dst[i+15:i] := (a[i+15:i] + b[i+15:i] + 1) >> 1 +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_avg_pu16 +FORCE_INLINE __m64 _mm_avg_pu16(__m64 a, __m64 b) +{ + return vreinterpret_m64_u16( + vrhadd_u16(vreinterpret_u16_m64(a), vreinterpret_u16_m64(b))); +} + +// Average packed unsigned 8-bit integers in a and b, and store the results in +// dst. +// +// FOR j := 0 to 7 +// i := j*8 +// dst[i+7:i] := (a[i+7:i] + b[i+7:i] + 1) >> 1 +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_avg_pu8 +FORCE_INLINE __m64 _mm_avg_pu8(__m64 a, __m64 b) +{ + return vreinterpret_m64_u8( + vrhadd_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))); +} + +// Compares for equality. +// https://msdn.microsoft.com/en-us/library/vstudio/36aectz5(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmpeq_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32( + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Compares for equality. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/k423z28e(v=vs.100) +FORCE_INLINE __m128 _mm_cmpeq_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmpeq_ps(a, b)); +} + +// Compares for greater than or equal. +// https://msdn.microsoft.com/en-us/library/vstudio/fs813y2t(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmpge_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32( + vcgeq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Compares for greater than or equal. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/kesh3ddc(v=vs.100) +FORCE_INLINE __m128 _mm_cmpge_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmpge_ps(a, b)); +} + +// Compares for greater than. +// +// r0 := (a0 > b0) ? 0xffffffff : 0x0 +// r1 := (a1 > b1) ? 0xffffffff : 0x0 +// r2 := (a2 > b2) ? 0xffffffff : 0x0 +// r3 := (a3 > b3) ? 0xffffffff : 0x0 +// +// https://msdn.microsoft.com/en-us/library/vstudio/11dy102s(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmpgt_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32( + vcgtq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Compares for greater than. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/1xyyyy9e(v=vs.100) +FORCE_INLINE __m128 _mm_cmpgt_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmpgt_ps(a, b)); +} + +// Compares for less than or equal. +// +// r0 := (a0 <= b0) ? 0xffffffff : 0x0 +// r1 := (a1 <= b1) ? 0xffffffff : 0x0 +// r2 := (a2 <= b2) ? 0xffffffff : 0x0 +// r3 := (a3 <= b3) ? 0xffffffff : 0x0 +// +// https://msdn.microsoft.com/en-us/library/vstudio/1s75w83z(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmple_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32( + vcleq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Compares for less than or equal. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/a7x0hbhw(v=vs.100) +FORCE_INLINE __m128 _mm_cmple_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmple_ps(a, b)); +} + +// Compares for less than +// https://msdn.microsoft.com/en-us/library/vstudio/f330yhc8(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmplt_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32( + vcltq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Compares for less than +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/fy94wye7(v=vs.100) +FORCE_INLINE __m128 _mm_cmplt_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmplt_ps(a, b)); +} + +// Compares for inequality. +// https://msdn.microsoft.com/en-us/library/sf44thbx(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cmpneq_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32(vmvnq_u32( + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)))); +} + +// Compares for inequality. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/ekya8fh4(v=vs.100) +FORCE_INLINE __m128 _mm_cmpneq_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmpneq_ps(a, b)); +} + +// Compares for not greater than or equal. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/wsexys62(v=vs.100) +FORCE_INLINE __m128 _mm_cmpnge_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32(vmvnq_u32( + vcgeq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)))); +} + +// Compares for not greater than or equal. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/fk2y80s8(v=vs.100) +FORCE_INLINE __m128 _mm_cmpnge_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmpnge_ps(a, b)); +} + +// Compares for not greater than. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/d0xh7w0s(v=vs.100) +FORCE_INLINE __m128 _mm_cmpngt_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32(vmvnq_u32( + vcgtq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)))); +} + +// Compares for not greater than. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/z7x9ydwh(v=vs.100) +FORCE_INLINE __m128 _mm_cmpngt_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmpngt_ps(a, b)); +} + +// Compares for not less than or equal. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/6a330kxw(v=vs.100) +FORCE_INLINE __m128 _mm_cmpnle_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32(vmvnq_u32( + vcleq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)))); +} + +// Compares for not less than or equal. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/z7x9ydwh(v=vs.100) +FORCE_INLINE __m128 _mm_cmpnle_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmpnle_ps(a, b)); +} + +// Compares for not less than. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/4686bbdw(v=vs.100) +FORCE_INLINE __m128 _mm_cmpnlt_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_u32(vmvnq_u32( + vcltq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)))); +} + +// Compares for not less than. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/56b9z2wf(v=vs.100) +FORCE_INLINE __m128 _mm_cmpnlt_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmpnlt_ps(a, b)); +} + +// Compares the four 32-bit floats in a and b to check if any values are NaN. +// Ordered compare between each value returns true for "orderable" and false for +// "not orderable" (NaN). +// https://msdn.microsoft.com/en-us/library/vstudio/0h9w00fx(v=vs.100).aspx see +// also: +// http://stackoverflow.com/questions/8627331/what-does-ordered-unordered-comparison-mean +// http://stackoverflow.com/questions/29349621/neon-isnanval-intrinsics +FORCE_INLINE __m128 _mm_cmpord_ps(__m128 a, __m128 b) +{ + // Note: NEON does not have ordered compare builtin + // Need to compare a eq a and b eq b to check for NaN + // Do AND of results to get final + uint32x4_t ceqaa = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t ceqbb = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_u32(vandq_u32(ceqaa, ceqbb)); +} + +// Compares for ordered. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/343t62da(v=vs.100) +FORCE_INLINE __m128 _mm_cmpord_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmpord_ps(a, b)); +} + +// Compares for unordered. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/khy6fk1t(v=vs.100) +FORCE_INLINE __m128 _mm_cmpunord_ps(__m128 a, __m128 b) +{ + uint32x4_t f32a = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); + uint32x4_t f32b = + vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_u32(vmvnq_u32(vandq_u32(f32a, f32b))); +} + +// Compares for unordered. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/2as2387b(v=vs.100) +FORCE_INLINE __m128 _mm_cmpunord_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_cmpunord_ps(a, b)); +} + +// Compares the lower single-precision floating point scalar values of a and b +// using an equality operation. : +// https://msdn.microsoft.com/en-us/library/93yx2h2b(v=vs.100).aspx +FORCE_INLINE int _mm_comieq_ss(__m128 a, __m128 b) +{ + uint32x4_t a_eq_b = + vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return vgetq_lane_u32(a_eq_b, 0) & 0x1; +} + +// Compares the lower single-precision floating point scalar values of a and b +// using a greater than or equal operation. : +// https://msdn.microsoft.com/en-us/library/8t80des6(v=vs.100).aspx +FORCE_INLINE int _mm_comige_ss(__m128 a, __m128 b) +{ + uint32x4_t a_ge_b = + vcgeq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return vgetq_lane_u32(a_ge_b, 0) & 0x1; +} + +// Compares the lower single-precision floating point scalar values of a and b +// using a greater than operation. : +// https://msdn.microsoft.com/en-us/library/b0738e0t(v=vs.100).aspx +FORCE_INLINE int _mm_comigt_ss(__m128 a, __m128 b) +{ + uint32x4_t a_gt_b = + vcgtq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return vgetq_lane_u32(a_gt_b, 0) & 0x1; +} + +// Compares the lower single-precision floating point scalar values of a and b +// using a less than or equal operation. : +// https://msdn.microsoft.com/en-us/library/1w4t7c57(v=vs.90).aspx +FORCE_INLINE int _mm_comile_ss(__m128 a, __m128 b) +{ + uint32x4_t a_le_b = + vcleq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return vgetq_lane_u32(a_le_b, 0) & 0x1; +} + +// Compares the lower single-precision floating point scalar values of a and b +// using a less than operation. : +// https://msdn.microsoft.com/en-us/library/2kwe606b(v=vs.90).aspx Important +// note!! The documentation on MSDN is incorrect! If either of the values is a +// NAN the docs say you will get a one, but in fact, it will return a zero!! +FORCE_INLINE int _mm_comilt_ss(__m128 a, __m128 b) +{ + uint32x4_t a_lt_b = + vcltq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); + return vgetq_lane_u32(a_lt_b, 0) & 0x1; +} + +// Compares the lower single-precision floating point scalar values of a and b +// using an inequality operation. : +// https://msdn.microsoft.com/en-us/library/bafh5e0a(v=vs.90).aspx +FORCE_INLINE int _mm_comineq_ss(__m128 a, __m128 b) +{ + return !_mm_comieq_ss(a, b); +} + +// Convert packed signed 32-bit integers in b to packed single-precision +// (32-bit) floating-point elements, store the results in the lower 2 elements +// of dst, and copy the upper 2 packed elements from a to the upper elements of +// dst. +// +// dst[31:0] := Convert_Int32_To_FP32(b[31:0]) +// dst[63:32] := Convert_Int32_To_FP32(b[63:32]) +// dst[95:64] := a[95:64] +// dst[127:96] := a[127:96] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_pi2ps +FORCE_INLINE __m128 _mm_cvt_pi2ps(__m128 a, __m64 b) +{ + return vreinterpretq_m128_f32( + vcombine_f32(vcvt_f32_s32(vreinterpret_s32_m64(b)), + vget_high_f32(vreinterpretq_f32_m128(a)))); +} + +// Convert packed single-precision (32-bit) floating-point elements in a to +// packed 32-bit integers, and store the results in dst. +// +// FOR j := 0 to 1 +// i := 32*j +// dst[i+31:i] := Convert_FP32_To_Int32(a[i+31:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_ps2pi +FORCE_INLINE __m64 _mm_cvt_ps2pi(__m128 a) +{ +#if defined(__aarch64__) || defined(__ARM_FEATURE_DIRECTED_ROUNDING) + return vreinterpret_m64_s32( + vget_low_s32(vcvtnq_s32_f32(vrndiq_f32(vreinterpretq_f32_m128(a))))); +#else + return vreinterpret_m64_s32(vcvt_s32_f32(vget_low_f32( + vreinterpretq_f32_m128(_mm_round_ps(a, _MM_FROUND_CUR_DIRECTION))))); +#endif +} + +// Convert the signed 32-bit integer b to a single-precision (32-bit) +// floating-point element, store the result in the lower element of dst, and +// copy the upper 3 packed elements from a to the upper elements of dst. +// +// dst[31:0] := Convert_Int32_To_FP32(b[31:0]) +// dst[127:32] := a[127:32] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_si2ss +FORCE_INLINE __m128 _mm_cvt_si2ss(__m128 a, int b) +{ + return vreinterpretq_m128_f32( + vsetq_lane_f32((float) b, vreinterpretq_f32_m128(a), 0)); +} + +// Convert the lower single-precision (32-bit) floating-point element in a to a +// 32-bit integer, and store the result in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_ss2si +FORCE_INLINE int _mm_cvt_ss2si(__m128 a) +{ +#if defined(__aarch64__) || defined(__ARM_FEATURE_DIRECTED_ROUNDING) + return vgetq_lane_s32(vcvtnq_s32_f32(vrndiq_f32(vreinterpretq_f32_m128(a))), + 0); +#else + float32_t data = vgetq_lane_f32( + vreinterpretq_f32_m128(_mm_round_ps(a, _MM_FROUND_CUR_DIRECTION)), 0); + return (int32_t) data; +#endif +} + +// Convert packed 16-bit integers in a to packed single-precision (32-bit) +// floating-point elements, and store the results in dst. +// +// FOR j := 0 to 3 +// i := j*16 +// m := j*32 +// dst[m+31:m] := Convert_Int16_To_FP32(a[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi16_ps +FORCE_INLINE __m128 _mm_cvtpi16_ps(__m64 a) +{ + return vreinterpretq_m128_f32( + vcvtq_f32_s32(vmovl_s16(vreinterpret_s16_m64(a)))); +} + +// Convert packed 32-bit integers in b to packed single-precision (32-bit) +// floating-point elements, store the results in the lower 2 elements of dst, +// and copy the upper 2 packed elements from a to the upper elements of dst. +// +// dst[31:0] := Convert_Int32_To_FP32(b[31:0]) +// dst[63:32] := Convert_Int32_To_FP32(b[63:32]) +// dst[95:64] := a[95:64] +// dst[127:96] := a[127:96] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi32_ps +FORCE_INLINE __m128 _mm_cvtpi32_ps(__m128 a, __m64 b) +{ + return vreinterpretq_m128_f32( + vcombine_f32(vcvt_f32_s32(vreinterpret_s32_m64(b)), + vget_high_f32(vreinterpretq_f32_m128(a)))); +} + +// Convert packed signed 32-bit integers in a to packed single-precision +// (32-bit) floating-point elements, store the results in the lower 2 elements +// of dst, then convert the packed signed 32-bit integers in b to +// single-precision (32-bit) floating-point element, and store the results in +// the upper 2 elements of dst. +// +// dst[31:0] := Convert_Int32_To_FP32(a[31:0]) +// dst[63:32] := Convert_Int32_To_FP32(a[63:32]) +// dst[95:64] := Convert_Int32_To_FP32(b[31:0]) +// dst[127:96] := Convert_Int32_To_FP32(b[63:32]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi32x2_ps +FORCE_INLINE __m128 _mm_cvtpi32x2_ps(__m64 a, __m64 b) +{ + return vreinterpretq_m128_f32(vcvtq_f32_s32( + vcombine_s32(vreinterpret_s32_m64(a), vreinterpret_s32_m64(b)))); +} + +// Convert the lower packed 8-bit integers in a to packed single-precision +// (32-bit) floating-point elements, and store the results in dst. +// +// FOR j := 0 to 3 +// i := j*8 +// m := j*32 +// dst[m+31:m] := Convert_Int8_To_FP32(a[i+7:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi8_ps +FORCE_INLINE __m128 _mm_cvtpi8_ps(__m64 a) +{ + return vreinterpretq_m128_f32(vcvtq_f32_s32( + vmovl_s16(vget_low_s16(vmovl_s8(vreinterpret_s8_m64(a)))))); +} + +// Convert packed single-precision (32-bit) floating-point elements in a to +// packed 16-bit integers, and store the results in dst. Note: this intrinsic +// will generate 0x7FFF, rather than 0x8000, for input values between 0x7FFF and +// 0x7FFFFFFF. +// +// FOR j := 0 to 3 +// i := 16*j +// k := 32*j +// IF a[k+31:k] >= FP32(0x7FFF) && a[k+31:k] <= FP32(0x7FFFFFFF) +// dst[i+15:i] := 0x7FFF +// ELSE +// dst[i+15:i] := Convert_FP32_To_Int16(a[k+31:k]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtps_pi16 +FORCE_INLINE __m64 _mm_cvtps_pi16(__m128 a) +{ + const __m128 i16Min = _mm_set_ps1((float) INT16_MIN); + const __m128 i16Max = _mm_set_ps1((float) INT16_MAX); + const __m128 i32Max = _mm_set_ps1((float) INT32_MAX); + const __m128i maxMask = _mm_castps_si128( + _mm_and_ps(_mm_cmpge_ps(a, i16Max), _mm_cmple_ps(a, i32Max))); + const __m128i betweenMask = _mm_castps_si128( + _mm_and_ps(_mm_cmpgt_ps(a, i16Min), _mm_cmplt_ps(a, i16Max))); + const __m128i minMask = _mm_cmpeq_epi32(_mm_or_si128(maxMask, betweenMask), + _mm_setzero_si128()); + __m128i max = _mm_and_si128(maxMask, _mm_set1_epi32(INT16_MAX)); + __m128i min = _mm_and_si128(minMask, _mm_set1_epi32(INT16_MIN)); + __m128i cvt = _mm_and_si128(betweenMask, _mm_cvtps_epi32(a)); + __m128i res32 = _mm_or_si128(_mm_or_si128(max, min), cvt); + return vreinterpret_m64_s16(vmovn_s32(vreinterpretq_s32_m128i(res32))); +} + +// Convert packed single-precision (32-bit) floating-point elements in a to +// packed 32-bit integers, and store the results in dst. +// +// FOR j := 0 to 1 +// i := 32*j +// dst[i+31:i] := Convert_FP32_To_Int32(a[i+31:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtps_pi32 +#define _mm_cvtps_pi32(a) _mm_cvt_ps2pi(a) + +// Convert packed single-precision (32-bit) floating-point elements in a to +// packed 8-bit integers, and store the results in lower 4 elements of dst. +// Note: this intrinsic will generate 0x7F, rather than 0x80, for input values +// between 0x7F and 0x7FFFFFFF. +// +// FOR j := 0 to 3 +// i := 8*j +// k := 32*j +// IF a[k+31:k] >= FP32(0x7F) && a[k+31:k] <= FP32(0x7FFFFFFF) +// dst[i+7:i] := 0x7F +// ELSE +// dst[i+7:i] := Convert_FP32_To_Int8(a[k+31:k]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtps_pi8 +FORCE_INLINE __m64 _mm_cvtps_pi8(__m128 a) +{ + const __m128 i8Min = _mm_set_ps1((float) INT8_MIN); + const __m128 i8Max = _mm_set_ps1((float) INT8_MAX); + const __m128 i32Max = _mm_set_ps1((float) INT32_MAX); + const __m128i maxMask = _mm_castps_si128( + _mm_and_ps(_mm_cmpge_ps(a, i8Max), _mm_cmple_ps(a, i32Max))); + const __m128i betweenMask = _mm_castps_si128( + _mm_and_ps(_mm_cmpgt_ps(a, i8Min), _mm_cmplt_ps(a, i8Max))); + const __m128i minMask = _mm_cmpeq_epi32(_mm_or_si128(maxMask, betweenMask), + _mm_setzero_si128()); + __m128i max = _mm_and_si128(maxMask, _mm_set1_epi32(INT8_MAX)); + __m128i min = _mm_and_si128(minMask, _mm_set1_epi32(INT8_MIN)); + __m128i cvt = _mm_and_si128(betweenMask, _mm_cvtps_epi32(a)); + __m128i res32 = _mm_or_si128(_mm_or_si128(max, min), cvt); + int16x4_t res16 = vmovn_s32(vreinterpretq_s32_m128i(res32)); + int8x8_t res8 = vmovn_s16(vcombine_s16(res16, res16)); + static const uint32_t bitMask[2] = {0xFFFFFFFF, 0}; + int8x8_t mask = vreinterpret_s8_u32(vld1_u32(bitMask)); + + return vreinterpret_m64_s8(vorr_s8(vand_s8(mask, res8), vdup_n_s8(0))); +} + +// Convert packed unsigned 16-bit integers in a to packed single-precision +// (32-bit) floating-point elements, and store the results in dst. +// +// FOR j := 0 to 3 +// i := j*16 +// m := j*32 +// dst[m+31:m] := Convert_UInt16_To_FP32(a[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpu16_ps +FORCE_INLINE __m128 _mm_cvtpu16_ps(__m64 a) +{ + return vreinterpretq_m128_f32( + vcvtq_f32_u32(vmovl_u16(vreinterpret_u16_m64(a)))); +} + +// Convert the lower packed unsigned 8-bit integers in a to packed +// single-precision (32-bit) floating-point elements, and store the results in +// dst. +// +// FOR j := 0 to 3 +// i := j*8 +// m := j*32 +// dst[m+31:m] := Convert_UInt8_To_FP32(a[i+7:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpu8_ps +FORCE_INLINE __m128 _mm_cvtpu8_ps(__m64 a) +{ + return vreinterpretq_m128_f32(vcvtq_f32_u32( + vmovl_u16(vget_low_u16(vmovl_u8(vreinterpret_u8_m64(a)))))); +} + +// Convert the signed 32-bit integer b to a single-precision (32-bit) +// floating-point element, store the result in the lower element of dst, and +// copy the upper 3 packed elements from a to the upper elements of dst. +// +// dst[31:0] := Convert_Int32_To_FP32(b[31:0]) +// dst[127:32] := a[127:32] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi32_ss +#define _mm_cvtsi32_ss(a, b) _mm_cvt_si2ss(a, b) + +// Convert the signed 64-bit integer b to a single-precision (32-bit) +// floating-point element, store the result in the lower element of dst, and +// copy the upper 3 packed elements from a to the upper elements of dst. +// +// dst[31:0] := Convert_Int64_To_FP32(b[63:0]) +// dst[127:32] := a[127:32] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi64_ss +FORCE_INLINE __m128 _mm_cvtsi64_ss(__m128 a, int64_t b) +{ + return vreinterpretq_m128_f32( + vsetq_lane_f32((float) b, vreinterpretq_f32_m128(a), 0)); +} + +// Copy the lower single-precision (32-bit) floating-point element of a to dst. +// +// dst[31:0] := a[31:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_f32 +FORCE_INLINE float _mm_cvtss_f32(__m128 a) +{ + return vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); +} + +// Convert the lower single-precision (32-bit) floating-point element in a to a +// 32-bit integer, and store the result in dst. +// +// dst[31:0] := Convert_FP32_To_Int32(a[31:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_si32 +#define _mm_cvtss_si32(a) _mm_cvt_ss2si(a) + +// Convert the lower single-precision (32-bit) floating-point element in a to a +// 64-bit integer, and store the result in dst. +// +// dst[63:0] := Convert_FP32_To_Int64(a[31:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_si64 +FORCE_INLINE int64_t _mm_cvtss_si64(__m128 a) +{ +#if defined(__aarch64__) || defined(__ARM_FEATURE_DIRECTED_ROUNDING) + return (int64_t) vgetq_lane_f32(vrndiq_f32(vreinterpretq_f32_m128(a)), 0); +#else + float32_t data = vgetq_lane_f32( + vreinterpretq_f32_m128(_mm_round_ps(a, _MM_FROUND_CUR_DIRECTION)), 0); + return (int64_t) data; +#endif +} + +// Convert packed single-precision (32-bit) floating-point elements in a to +// packed 32-bit integers with truncation, and store the results in dst. +// +// FOR j := 0 to 1 +// i := 32*j +// dst[i+31:i] := Convert_FP32_To_Int32_Truncate(a[i+31:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtt_ps2pi +FORCE_INLINE __m64 _mm_cvtt_ps2pi(__m128 a) +{ + return vreinterpret_m64_s32( + vget_low_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a)))); +} + +// Convert the lower single-precision (32-bit) floating-point element in a to a +// 32-bit integer with truncation, and store the result in dst. +// +// dst[31:0] := Convert_FP32_To_Int32_Truncate(a[31:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtt_ss2si +FORCE_INLINE int _mm_cvtt_ss2si(__m128 a) +{ + return vgetq_lane_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a)), 0); +} + +// Convert packed single-precision (32-bit) floating-point elements in a to +// packed 32-bit integers with truncation, and store the results in dst. +// +// FOR j := 0 to 1 +// i := 32*j +// dst[i+31:i] := Convert_FP32_To_Int32_Truncate(a[i+31:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttps_pi32 +#define _mm_cvttps_pi32(a) _mm_cvtt_ps2pi(a) + +// Convert the lower single-precision (32-bit) floating-point element in a to a +// 32-bit integer with truncation, and store the result in dst. +// +// dst[31:0] := Convert_FP32_To_Int32_Truncate(a[31:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttss_si32 +#define _mm_cvttss_si32(a) _mm_cvtt_ss2si(a) + +// Convert the lower single-precision (32-bit) floating-point element in a to a +// 64-bit integer with truncation, and store the result in dst. +// +// dst[63:0] := Convert_FP32_To_Int64_Truncate(a[31:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttss_si64 +FORCE_INLINE int64_t _mm_cvttss_si64(__m128 a) +{ + return (int64_t) vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); +} + +// Divides the four single-precision, floating-point values of a and b. +// +// r0 := a0 / b0 +// r1 := a1 / b1 +// r2 := a2 / b2 +// r3 := a3 / b3 +// +// https://msdn.microsoft.com/en-us/library/edaw8147(v=vs.100).aspx +FORCE_INLINE __m128 _mm_div_ps(__m128 a, __m128 b) +{ +#if defined(__aarch64__) && !SSE2NEON_PRECISE_DIV + return vreinterpretq_m128_f32( + vdivq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#else + float32x4_t recip = vrecpeq_f32(vreinterpretq_f32_m128(b)); + recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(b))); +#if SSE2NEON_PRECISE_DIV + // Additional Netwon-Raphson iteration for accuracy + recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(b))); +#endif + return vreinterpretq_m128_f32(vmulq_f32(vreinterpretq_f32_m128(a), recip)); +#endif +} + +// Divides the scalar single-precision floating point value of a by b. +// https://msdn.microsoft.com/en-us/library/4y73xa49(v=vs.100).aspx +FORCE_INLINE __m128 _mm_div_ss(__m128 a, __m128 b) +{ + float32_t value = + vgetq_lane_f32(vreinterpretq_f32_m128(_mm_div_ps(a, b)), 0); + return vreinterpretq_m128_f32( + vsetq_lane_f32(value, vreinterpretq_f32_m128(a), 0)); +} + +// Extract a 16-bit integer from a, selected with imm8, and store the result in +// the lower element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_extract_pi16 +#define _mm_extract_pi16(a, imm) \ + (int32_t) vget_lane_u16(vreinterpret_u16_m64(a), (imm)) + +// Free aligned memory that was allocated with _mm_malloc. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_free +FORCE_INLINE void _mm_free(void *addr) +{ + free(addr); +} + +// Macro: Get the flush zero bits from the MXCSR control and status register. +// The flush zero may contain any of the following flags: _MM_FLUSH_ZERO_ON or +// _MM_FLUSH_ZERO_OFF +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_MM_GET_FLUSH_ZERO_MODE +FORCE_INLINE unsigned int _sse2neon_mm_get_flush_zero_mode() +{ + union { + fpcr_bitfield field; +#if defined(__aarch64__) + uint64_t value; +#else + uint32_t value; +#endif + } r; + +#if defined(__aarch64__) + __asm__ __volatile__("mrs %0, FPCR" : "=r"(r.value)); /* read */ +#else + __asm__ __volatile__("vmrs %0, FPSCR" : "=r"(r.value)); /* read */ +#endif + + return r.field.bit24 ? _MM_FLUSH_ZERO_ON : _MM_FLUSH_ZERO_OFF; +} + +// Macro: Get the rounding mode bits from the MXCSR control and status register. +// The rounding mode may contain any of the following flags: _MM_ROUND_NEAREST, +// _MM_ROUND_DOWN, _MM_ROUND_UP, _MM_ROUND_TOWARD_ZERO +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_MM_GET_ROUNDING_MODE +FORCE_INLINE unsigned int _MM_GET_ROUNDING_MODE() +{ + union { + fpcr_bitfield field; +#if defined(__aarch64__) + uint64_t value; +#else + uint32_t value; +#endif + } r; + +#if defined(__aarch64__) + __asm__ __volatile__("mrs %0, FPCR" : "=r"(r.value)); /* read */ +#else + __asm__ __volatile__("vmrs %0, FPSCR" : "=r"(r.value)); /* read */ +#endif + + if (r.field.bit22) { + return r.field.bit23 ? _MM_ROUND_TOWARD_ZERO : _MM_ROUND_UP; + } else { + return r.field.bit23 ? _MM_ROUND_DOWN : _MM_ROUND_NEAREST; + } +} + +// Copy a to dst, and insert the 16-bit integer i into dst at the location +// specified by imm8. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_insert_pi16 +#define _mm_insert_pi16(a, b, imm) \ + __extension__({ \ + vreinterpret_m64_s16( \ + vset_lane_s16((b), vreinterpret_s16_m64(a), (imm))); \ + }) + +// Loads four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/vstudio/zzd50xxt(v=vs.100).aspx +FORCE_INLINE __m128 _mm_load_ps(const float *p) +{ + return vreinterpretq_m128_f32(vld1q_f32(p)); +} + +// Load a single-precision (32-bit) floating-point element from memory into all +// elements of dst. +// +// dst[31:0] := MEM[mem_addr+31:mem_addr] +// dst[63:32] := MEM[mem_addr+31:mem_addr] +// dst[95:64] := MEM[mem_addr+31:mem_addr] +// dst[127:96] := MEM[mem_addr+31:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_ps1 +#define _mm_load_ps1 _mm_load1_ps + +// Loads an single - precision, floating - point value into the low word and +// clears the upper three words. +// https://msdn.microsoft.com/en-us/library/548bb9h4%28v=vs.90%29.aspx +FORCE_INLINE __m128 _mm_load_ss(const float *p) +{ + return vreinterpretq_m128_f32(vsetq_lane_f32(*p, vdupq_n_f32(0), 0)); +} + +// Loads a single single-precision, floating-point value, copying it into all +// four words +// https://msdn.microsoft.com/en-us/library/vstudio/5cdkf716(v=vs.100).aspx +FORCE_INLINE __m128 _mm_load1_ps(const float *p) +{ + return vreinterpretq_m128_f32(vld1q_dup_f32(p)); +} + +// Sets the upper two single-precision, floating-point values with 64 +// bits of data loaded from the address p; the lower two values are passed +// through from a. +// +// r0 := a0 +// r1 := a1 +// r2 := *p0 +// r3 := *p1 +// +// https://msdn.microsoft.com/en-us/library/w92wta0x(v%3dvs.100).aspx +FORCE_INLINE __m128 _mm_loadh_pi(__m128 a, __m64 const *p) +{ + return vreinterpretq_m128_f32( + vcombine_f32(vget_low_f32(a), vld1_f32((const float32_t *) p))); +} + +// Sets the lower two single-precision, floating-point values with 64 +// bits of data loaded from the address p; the upper two values are passed +// through from a. +// +// Return Value +// r0 := *p0 +// r1 := *p1 +// r2 := a2 +// r3 := a3 +// +// https://msdn.microsoft.com/en-us/library/s57cyak2(v=vs.100).aspx +FORCE_INLINE __m128 _mm_loadl_pi(__m128 a, __m64 const *p) +{ + return vreinterpretq_m128_f32( + vcombine_f32(vld1_f32((const float32_t *) p), vget_high_f32(a))); +} + +// Load 4 single-precision (32-bit) floating-point elements from memory into dst +// in reverse order. mem_addr must be aligned on a 16-byte boundary or a +// general-protection exception may be generated. +// +// dst[31:0] := MEM[mem_addr+127:mem_addr+96] +// dst[63:32] := MEM[mem_addr+95:mem_addr+64] +// dst[95:64] := MEM[mem_addr+63:mem_addr+32] +// dst[127:96] := MEM[mem_addr+31:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadr_ps +FORCE_INLINE __m128 _mm_loadr_ps(const float *p) +{ + float32x4_t v = vrev64q_f32(vld1q_f32(p)); + return vreinterpretq_m128_f32(vextq_f32(v, v, 2)); +} + +// Loads four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/x1b16s7z%28v=vs.90%29.aspx +FORCE_INLINE __m128 _mm_loadu_ps(const float *p) +{ + // for neon, alignment doesn't matter, so _mm_load_ps and _mm_loadu_ps are + // equivalent for neon + return vreinterpretq_m128_f32(vld1q_f32(p)); +} + +// Load unaligned 16-bit integer from memory into the first element of dst. +// +// dst[15:0] := MEM[mem_addr+15:mem_addr] +// dst[MAX:16] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_si16 +FORCE_INLINE __m128i _mm_loadu_si16(const void *p) +{ + return vreinterpretq_m128i_s16( + vsetq_lane_s16(*(const int16_t *) p, vdupq_n_s16(0), 0)); +} + +// Load unaligned 64-bit integer from memory into the first element of dst. +// +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[MAX:64] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_si64 +FORCE_INLINE __m128i _mm_loadu_si64(const void *p) +{ + return vreinterpretq_m128i_s64( + vcombine_s64(vld1_s64((const int64_t *) p), vdup_n_s64(0))); +} + +// Allocate aligned blocks of memory. +// https://software.intel.com/en-us/ +// cpp-compiler-developer-guide-and-reference-allocating-and-freeing-aligned-memory-blocks +FORCE_INLINE void *_mm_malloc(size_t size, size_t align) +{ + void *ptr; + if (align == 1) + return malloc(size); + if (align == 2 || (sizeof(void *) == 8 && align == 4)) + align = sizeof(void *); + if (!posix_memalign(&ptr, align, size)) + return ptr; + return NULL; +} + +// Conditionally store 8-bit integer elements from a into memory using mask +// (elements are not stored when the highest bit is not set in the corresponding +// element) and a non-temporal memory hint. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_maskmove_si64 +FORCE_INLINE void _mm_maskmove_si64(__m64 a, __m64 mask, char *mem_addr) +{ + int8x8_t shr_mask = vshr_n_s8(vreinterpret_s8_m64(mask), 7); + __m128 b = _mm_load_ps((const float *) mem_addr); + int8x8_t masked = + vbsl_s8(vreinterpret_u8_s8(shr_mask), vreinterpret_s8_m64(a), + vreinterpret_s8_u64(vget_low_u64(vreinterpretq_u64_m128(b)))); + vst1_s8((int8_t *) mem_addr, masked); +} + +// Conditionally store 8-bit integer elements from a into memory using mask +// (elements are not stored when the highest bit is not set in the corresponding +// element) and a non-temporal memory hint. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_maskmovq +#define _m_maskmovq(a, mask, mem_addr) _mm_maskmove_si64(a, mask, mem_addr) + +// Compare packed signed 16-bit integers in a and b, and store packed maximum +// values in dst. +// +// FOR j := 0 to 3 +// i := j*16 +// dst[i+15:i] := MAX(a[i+15:i], b[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pi16 +FORCE_INLINE __m64 _mm_max_pi16(__m64 a, __m64 b) +{ + return vreinterpret_m64_s16( + vmax_s16(vreinterpret_s16_m64(a), vreinterpret_s16_m64(b))); +} + +// Computes the maximums of the four single-precision, floating-point values of +// a and b. +// https://msdn.microsoft.com/en-us/library/vstudio/ff5d607a(v=vs.100).aspx +FORCE_INLINE __m128 _mm_max_ps(__m128 a, __m128 b) +{ +#if SSE2NEON_PRECISE_MINMAX + float32x4_t _a = vreinterpretq_f32_m128(a); + float32x4_t _b = vreinterpretq_f32_m128(b); + return vreinterpretq_m128_f32(vbslq_f32(vcgtq_f32(_a, _b), _a, _b)); +#else + return vreinterpretq_m128_f32( + vmaxq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#endif +} + +// Compare packed unsigned 8-bit integers in a and b, and store packed maximum +// values in dst. +// +// FOR j := 0 to 7 +// i := j*8 +// dst[i+7:i] := MAX(a[i+7:i], b[i+7:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pu8 +FORCE_INLINE __m64 _mm_max_pu8(__m64 a, __m64 b) +{ + return vreinterpret_m64_u8( + vmax_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))); +} + +// Computes the maximum of the two lower scalar single-precision floating point +// values of a and b. +// https://msdn.microsoft.com/en-us/library/s6db5esz(v=vs.100).aspx +FORCE_INLINE __m128 _mm_max_ss(__m128 a, __m128 b) +{ + float32_t value = vgetq_lane_f32(_mm_max_ps(a, b), 0); + return vreinterpretq_m128_f32( + vsetq_lane_f32(value, vreinterpretq_f32_m128(a), 0)); +} + +// Compare packed signed 16-bit integers in a and b, and store packed minimum +// values in dst. +// +// FOR j := 0 to 3 +// i := j*16 +// dst[i+15:i] := MIN(a[i+15:i], b[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pi16 +FORCE_INLINE __m64 _mm_min_pi16(__m64 a, __m64 b) +{ + return vreinterpret_m64_s16( + vmin_s16(vreinterpret_s16_m64(a), vreinterpret_s16_m64(b))); +} + +// Computes the minima of the four single-precision, floating-point values of a +// and b. +// https://msdn.microsoft.com/en-us/library/vstudio/wh13kadz(v=vs.100).aspx +FORCE_INLINE __m128 _mm_min_ps(__m128 a, __m128 b) +{ +#if SSE2NEON_PRECISE_MINMAX + float32x4_t _a = vreinterpretq_f32_m128(a); + float32x4_t _b = vreinterpretq_f32_m128(b); + return vreinterpretq_m128_f32(vbslq_f32(vcltq_f32(_a, _b), _a, _b)); +#else + return vreinterpretq_m128_f32( + vminq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#endif +} + +// Compare packed unsigned 8-bit integers in a and b, and store packed minimum +// values in dst. +// +// FOR j := 0 to 7 +// i := j*8 +// dst[i+7:i] := MIN(a[i+7:i], b[i+7:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pu8 +FORCE_INLINE __m64 _mm_min_pu8(__m64 a, __m64 b) +{ + return vreinterpret_m64_u8( + vmin_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))); +} + +// Computes the minimum of the two lower scalar single-precision floating point +// values of a and b. +// https://msdn.microsoft.com/en-us/library/0a9y7xaa(v=vs.100).aspx +FORCE_INLINE __m128 _mm_min_ss(__m128 a, __m128 b) +{ + float32_t value = vgetq_lane_f32(_mm_min_ps(a, b), 0); + return vreinterpretq_m128_f32( + vsetq_lane_f32(value, vreinterpretq_f32_m128(a), 0)); +} + +// Sets the low word to the single-precision, floating-point value of b +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/35hdzazd(v=vs.100) +FORCE_INLINE __m128 _mm_move_ss(__m128 a, __m128 b) +{ + return vreinterpretq_m128_f32( + vsetq_lane_f32(vgetq_lane_f32(vreinterpretq_f32_m128(b), 0), + vreinterpretq_f32_m128(a), 0)); +} + +// Moves the upper two values of B into the lower two values of A. +// +// r3 := a3 +// r2 := a2 +// r1 := b3 +// r0 := b2 +FORCE_INLINE __m128 _mm_movehl_ps(__m128 __A, __m128 __B) +{ + float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(__A)); + float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(__B)); + return vreinterpretq_m128_f32(vcombine_f32(b32, a32)); +} + +// Moves the lower two values of B into the upper two values of A. +// +// r3 := b1 +// r2 := b0 +// r1 := a1 +// r0 := a0 +FORCE_INLINE __m128 _mm_movelh_ps(__m128 __A, __m128 __B) +{ + float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(__A)); + float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(__B)); + return vreinterpretq_m128_f32(vcombine_f32(a10, b10)); +} + +// Create mask from the most significant bit of each 8-bit element in a, and +// store the result in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movemask_pi8 +FORCE_INLINE int _mm_movemask_pi8(__m64 a) +{ + uint8x8_t input = vreinterpret_u8_m64(a); +#if defined(__aarch64__) + static const int8x8_t shift = {0, 1, 2, 3, 4, 5, 6, 7}; + uint8x8_t tmp = vshr_n_u8(input, 7); + return vaddv_u8(vshl_u8(tmp, shift)); +#else + // Refer the implementation of `_mm_movemask_epi8` + uint16x4_t high_bits = vreinterpret_u16_u8(vshr_n_u8(input, 7)); + uint32x2_t paired16 = + vreinterpret_u32_u16(vsra_n_u16(high_bits, high_bits, 7)); + uint8x8_t paired32 = + vreinterpret_u8_u32(vsra_n_u32(paired16, paired16, 14)); + return vget_lane_u8(paired32, 0) | ((int) vget_lane_u8(paired32, 4) << 4); +#endif +} + +// NEON does not provide this method +// Creates a 4-bit mask from the most significant bits of the four +// single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/vstudio/4490ys29(v=vs.100).aspx +FORCE_INLINE int _mm_movemask_ps(__m128 a) +{ + uint32x4_t input = vreinterpretq_u32_m128(a); +#if defined(__aarch64__) + static const int32x4_t shift = {0, 1, 2, 3}; + uint32x4_t tmp = vshrq_n_u32(input, 31); + return vaddvq_u32(vshlq_u32(tmp, shift)); +#else + // Uses the exact same method as _mm_movemask_epi8, see that for details. + // Shift out everything but the sign bits with a 32-bit unsigned shift + // right. + uint64x2_t high_bits = vreinterpretq_u64_u32(vshrq_n_u32(input, 31)); + // Merge the two pairs together with a 64-bit unsigned shift right + add. + uint8x16_t paired = + vreinterpretq_u8_u64(vsraq_n_u64(high_bits, high_bits, 31)); + // Extract the result. + return vgetq_lane_u8(paired, 0) | (vgetq_lane_u8(paired, 8) << 2); +#endif +} + +// Multiplies the four single-precision, floating-point values of a and b. +// +// r0 := a0 * b0 +// r1 := a1 * b1 +// r2 := a2 * b2 +// r3 := a3 * b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/22kbk6t9(v=vs.100).aspx +FORCE_INLINE __m128 _mm_mul_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_f32( + vmulq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Multiply the lower single-precision (32-bit) floating-point element in a and +// b, store the result in the lower element of dst, and copy the upper 3 packed +// elements from a to the upper elements of dst. +// +// dst[31:0] := a[31:0] * b[31:0] +// dst[127:32] := a[127:32] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mul_ss +FORCE_INLINE __m128 _mm_mul_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_mul_ps(a, b)); +} + +// Multiply the packed unsigned 16-bit integers in a and b, producing +// intermediate 32-bit integers, and store the high 16 bits of the intermediate +// integers in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mulhi_pu16 +FORCE_INLINE __m64 _mm_mulhi_pu16(__m64 a, __m64 b) +{ + return vreinterpret_m64_u16(vshrn_n_u32( + vmull_u16(vreinterpret_u16_m64(a), vreinterpret_u16_m64(b)), 16)); +} + +// Computes the bitwise OR of the four single-precision, floating-point values +// of a and b. +// https://msdn.microsoft.com/en-us/library/vstudio/7ctdsyy0(v=vs.100).aspx +FORCE_INLINE __m128 _mm_or_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_s32( + vorrq_s32(vreinterpretq_s32_m128(a), vreinterpretq_s32_m128(b))); +} + +// Average packed unsigned 8-bit integers in a and b, and store the results in +// dst. +// +// FOR j := 0 to 7 +// i := j*8 +// dst[i+7:i] := (a[i+7:i] + b[i+7:i] + 1) >> 1 +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pavgb +#define _m_pavgb(a, b) _mm_avg_pu8(a, b) + +// Average packed unsigned 16-bit integers in a and b, and store the results in +// dst. +// +// FOR j := 0 to 3 +// i := j*16 +// dst[i+15:i] := (a[i+15:i] + b[i+15:i] + 1) >> 1 +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pavgw +#define _m_pavgw(a, b) _mm_avg_pu16(a, b) + +// Extract a 16-bit integer from a, selected with imm8, and store the result in +// the lower element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pextrw +#define _m_pextrw(a, imm) _mm_extract_pi16(a, imm) + +// Copy a to dst, and insert the 16-bit integer i into dst at the location +// specified by imm8. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=m_pinsrw +#define _m_pinsrw(a, i, imm) _mm_insert_pi16(a, i, imm) + +// Compare packed signed 16-bit integers in a and b, and store packed maximum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pmaxsw +#define _m_pmaxsw(a, b) _mm_max_pi16(a, b) + +// Compare packed unsigned 8-bit integers in a and b, and store packed maximum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pmaxub +#define _m_pmaxub(a, b) _mm_max_pu8(a, b) + +// Compare packed signed 16-bit integers in a and b, and store packed minimum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pminsw +#define _m_pminsw(a, b) _mm_min_pi16(a, b) + +// Compare packed unsigned 8-bit integers in a and b, and store packed minimum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pminub +#define _m_pminub(a, b) _mm_min_pu8(a, b) + +// Create mask from the most significant bit of each 8-bit element in a, and +// store the result in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pmovmskb +#define _m_pmovmskb(a) _mm_movemask_pi8(a) + +// Multiply the packed unsigned 16-bit integers in a and b, producing +// intermediate 32-bit integers, and store the high 16 bits of the intermediate +// integers in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pmulhuw +#define _m_pmulhuw(a, b) _mm_mulhi_pu16(a, b) + +// Loads one cache line of data from address p to a location closer to the +// processor. https://msdn.microsoft.com/en-us/library/84szxsww(v=vs.100).aspx +FORCE_INLINE void _mm_prefetch(const void *p, int i) +{ + (void) i; + __builtin_prefetch(p); +} + +// Compute the absolute differences of packed unsigned 8-bit integers in a and +// b, then horizontally sum each consecutive 8 differences to produce four +// unsigned 16-bit integers, and pack these unsigned 16-bit integers in the low +// 16 bits of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=m_psadbw +#define _m_psadbw(a, b) _mm_sad_pu8(a, b) + +// Shuffle 16-bit integers in a using the control in imm8, and store the results +// in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pshufw +#define _m_pshufw(a, imm) _mm_shuffle_pi16(a, imm) + +// Compute the approximate reciprocal of packed single-precision (32-bit) +// floating-point elements in a, and store the results in dst. The maximum +// relative error for this approximation is less than 1.5*2^-12. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_rcp_ps +FORCE_INLINE __m128 _mm_rcp_ps(__m128 in) +{ + float32x4_t recip = vrecpeq_f32(vreinterpretq_f32_m128(in)); + recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(in))); +#if SSE2NEON_PRECISE_DIV + // Additional Netwon-Raphson iteration for accuracy + recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(in))); +#endif + return vreinterpretq_m128_f32(recip); +} + +// Compute the approximate reciprocal of the lower single-precision (32-bit) +// floating-point element in a, store the result in the lower element of dst, +// and copy the upper 3 packed elements from a to the upper elements of dst. The +// maximum relative error for this approximation is less than 1.5*2^-12. +// +// dst[31:0] := (1.0 / a[31:0]) +// dst[127:32] := a[127:32] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_rcp_ss +FORCE_INLINE __m128 _mm_rcp_ss(__m128 a) +{ + return _mm_move_ss(a, _mm_rcp_ps(a)); +} + +// Computes the approximations of the reciprocal square roots of the four +// single-precision floating point values of in. +// The current precision is 1% error. +// https://msdn.microsoft.com/en-us/library/22hfsh53(v=vs.100).aspx +FORCE_INLINE __m128 _mm_rsqrt_ps(__m128 in) +{ + float32x4_t out = vrsqrteq_f32(vreinterpretq_f32_m128(in)); +#if SSE2NEON_PRECISE_SQRT + // Additional Netwon-Raphson iteration for accuracy + out = vmulq_f32( + out, vrsqrtsq_f32(vmulq_f32(vreinterpretq_f32_m128(in), out), out)); + out = vmulq_f32( + out, vrsqrtsq_f32(vmulq_f32(vreinterpretq_f32_m128(in), out), out)); +#endif + return vreinterpretq_m128_f32(out); +} + +// Compute the approximate reciprocal square root of the lower single-precision +// (32-bit) floating-point element in a, store the result in the lower element +// of dst, and copy the upper 3 packed elements from a to the upper elements of +// dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_rsqrt_ss +FORCE_INLINE __m128 _mm_rsqrt_ss(__m128 in) +{ + return vsetq_lane_f32(vgetq_lane_f32(_mm_rsqrt_ps(in), 0), in, 0); +} + +// Compute the absolute differences of packed unsigned 8-bit integers in a and +// b, then horizontally sum each consecutive 8 differences to produce four +// unsigned 16-bit integers, and pack these unsigned 16-bit integers in the low +// 16 bits of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sad_pu8 +FORCE_INLINE __m64 _mm_sad_pu8(__m64 a, __m64 b) +{ + uint64x1_t t = vpaddl_u32(vpaddl_u16( + vpaddl_u8(vabd_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))))); + return vreinterpret_m64_u16( + vset_lane_u16(vget_lane_u64(t, 0), vdup_n_u16(0), 0)); +} + +// Macro: Set the flush zero bits of the MXCSR control and status register to +// the value in unsigned 32-bit integer a. The flush zero may contain any of the +// following flags: _MM_FLUSH_ZERO_ON or _MM_FLUSH_ZERO_OFF +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_MM_SET_FLUSH_ZERO_MODE +FORCE_INLINE void _sse2neon_mm_set_flush_zero_mode(unsigned int flag) +{ + // AArch32 Advanced SIMD arithmetic always uses the Flush-to-zero setting, + // regardless of the value of the FZ bit. + union { + fpcr_bitfield field; +#if defined(__aarch64__) + uint64_t value; +#else + uint32_t value; +#endif + } r; + +#if defined(__aarch64__) + __asm__ __volatile__("mrs %0, FPCR" : "=r"(r.value)); /* read */ +#else + __asm__ __volatile__("vmrs %0, FPSCR" : "=r"(r.value)); /* read */ +#endif + + r.field.bit24 = (flag & _MM_FLUSH_ZERO_MASK) == _MM_FLUSH_ZERO_ON; + +#if defined(__aarch64__) + __asm__ __volatile__("msr FPCR, %0" ::"r"(r)); /* write */ +#else + __asm__ __volatile__("vmsr FPSCR, %0" ::"r"(r)); /* write */ +#endif +} + +// Sets the four single-precision, floating-point values to the four inputs. +// https://msdn.microsoft.com/en-us/library/vstudio/afh0zf75(v=vs.100).aspx +FORCE_INLINE __m128 _mm_set_ps(float w, float z, float y, float x) +{ + float ALIGN_STRUCT(16) data[4] = {x, y, z, w}; + return vreinterpretq_m128_f32(vld1q_f32(data)); +} + +// Sets the four single-precision, floating-point values to w. +// https://msdn.microsoft.com/en-us/library/vstudio/2x1se8ha(v=vs.100).aspx +FORCE_INLINE __m128 _mm_set_ps1(float _w) +{ + return vreinterpretq_m128_f32(vdupq_n_f32(_w)); +} + +// Macro: Set the rounding mode bits of the MXCSR control and status register to +// the value in unsigned 32-bit integer a. The rounding mode may contain any of +// the following flags: _MM_ROUND_NEAREST, _MM_ROUND_DOWN, _MM_ROUND_UP, +// _MM_ROUND_TOWARD_ZERO +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_MM_SET_ROUNDING_MODE +FORCE_INLINE void _MM_SET_ROUNDING_MODE(int rounding) +{ + union { + fpcr_bitfield field; +#if defined(__aarch64__) + uint64_t value; +#else + uint32_t value; +#endif + } r; + +#if defined(__aarch64__) + __asm__ __volatile__("mrs %0, FPCR" : "=r"(r.value)); /* read */ +#else + __asm__ __volatile__("vmrs %0, FPSCR" : "=r"(r.value)); /* read */ +#endif + + switch (rounding) { + case _MM_ROUND_TOWARD_ZERO: + r.field.bit22 = 1; + r.field.bit23 = 1; + break; + case _MM_ROUND_DOWN: + r.field.bit22 = 0; + r.field.bit23 = 1; + break; + case _MM_ROUND_UP: + r.field.bit22 = 1; + r.field.bit23 = 0; + break; + default: //_MM_ROUND_NEAREST + r.field.bit22 = 0; + r.field.bit23 = 0; + } + +#if defined(__aarch64__) + __asm__ __volatile__("msr FPCR, %0" ::"r"(r)); /* write */ +#else + __asm__ __volatile__("vmsr FPSCR, %0" ::"r"(r)); /* write */ +#endif +} + +// Copy single-precision (32-bit) floating-point element a to the lower element +// of dst, and zero the upper 3 elements. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_ss +FORCE_INLINE __m128 _mm_set_ss(float a) +{ + float ALIGN_STRUCT(16) data[4] = {a, 0, 0, 0}; + return vreinterpretq_m128_f32(vld1q_f32(data)); +} + +// Sets the four single-precision, floating-point values to w. +// +// r0 := r1 := r2 := r3 := w +// +// https://msdn.microsoft.com/en-us/library/vstudio/2x1se8ha(v=vs.100).aspx +FORCE_INLINE __m128 _mm_set1_ps(float _w) +{ + return vreinterpretq_m128_f32(vdupq_n_f32(_w)); +} + +// FIXME: _mm_setcsr() implementation supports changing the rounding mode only. +FORCE_INLINE void _mm_setcsr(unsigned int a) +{ + _MM_SET_ROUNDING_MODE(a); +} + +// FIXME: _mm_getcsr() implementation supports reading the rounding mode only. +FORCE_INLINE unsigned int _mm_getcsr() +{ + return _MM_GET_ROUNDING_MODE(); +} + +// Sets the four single-precision, floating-point values to the four inputs in +// reverse order. +// https://msdn.microsoft.com/en-us/library/vstudio/d2172ct3(v=vs.100).aspx +FORCE_INLINE __m128 _mm_setr_ps(float w, float z, float y, float x) +{ + float ALIGN_STRUCT(16) data[4] = {w, z, y, x}; + return vreinterpretq_m128_f32(vld1q_f32(data)); +} + +// Clears the four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/vstudio/tk1t2tbz(v=vs.100).aspx +FORCE_INLINE __m128 _mm_setzero_ps(void) +{ + return vreinterpretq_m128_f32(vdupq_n_f32(0)); +} + +// Shuffle 16-bit integers in a using the control in imm8, and store the results +// in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_shuffle_pi16 +#if __has_builtin(__builtin_shufflevector) +#define _mm_shuffle_pi16(a, imm) \ + __extension__({ \ + vreinterpret_m64_s16(__builtin_shufflevector( \ + vreinterpret_s16_m64(a), vreinterpret_s16_m64(a), (imm & 0x3), \ + ((imm >> 2) & 0x3), ((imm >> 4) & 0x3), ((imm >> 6) & 0x3))); \ + }) +#else +#define _mm_shuffle_pi16(a, imm) \ + __extension__({ \ + int16x4_t ret; \ + ret = \ + vmov_n_s16(vget_lane_s16(vreinterpret_s16_m64(a), (imm) & (0x3))); \ + ret = vset_lane_s16( \ + vget_lane_s16(vreinterpret_s16_m64(a), ((imm) >> 2) & 0x3), ret, \ + 1); \ + ret = vset_lane_s16( \ + vget_lane_s16(vreinterpret_s16_m64(a), ((imm) >> 4) & 0x3), ret, \ + 2); \ + ret = vset_lane_s16( \ + vget_lane_s16(vreinterpret_s16_m64(a), ((imm) >> 6) & 0x3), ret, \ + 3); \ + vreinterpret_m64_s16(ret); \ + }) +#endif + +// Guarantees that every preceding store is globally visible before any +// subsequent store. +// https://msdn.microsoft.com/en-us/library/5h2w73d1%28v=vs.90%29.aspx +FORCE_INLINE void _mm_sfence(void) +{ + __sync_synchronize(); +} + // FORCE_INLINE __m128 _mm_shuffle_ps(__m128 a, __m128 b, __constrange(0,255) // int imm) #if __has_builtin(__builtin_shufflevector) @@ -2015,737 +2622,2127 @@ FORCE_INLINE __m128 _mm_shuffle_ps_2032(__m128 a, __m128 b) }) #endif -// Takes the upper 64 bits of a and places it in the low end of the result -// Takes the lower 64 bits of a and places it into the high end of the result. -FORCE_INLINE __m128i _mm_shuffle_epi_1032(__m128i a) +// Computes the approximations of square roots of the four single-precision, +// floating-point values of a. First computes reciprocal square roots and then +// reciprocals of the four values. +// +// r0 := sqrt(a0) +// r1 := sqrt(a1) +// r2 := sqrt(a2) +// r3 := sqrt(a3) +// +// https://msdn.microsoft.com/en-us/library/vstudio/8z67bwwk(v=vs.100).aspx +FORCE_INLINE __m128 _mm_sqrt_ps(__m128 in) { - int32x2_t a32 = vget_high_s32(vreinterpretq_s32_m128i(a)); - int32x2_t a10 = vget_low_s32(vreinterpretq_s32_m128i(a)); - return vreinterpretq_m128i_s32(vcombine_s32(a32, a10)); -} +#if SSE2NEON_PRECISE_SQRT + float32x4_t recip = vrsqrteq_f32(vreinterpretq_f32_m128(in)); -// takes the lower two 32-bit values from a and swaps them and places in low end -// of result takes the higher two 32 bit values from a and swaps them and places -// in high end of result. -FORCE_INLINE __m128i _mm_shuffle_epi_2301(__m128i a) -{ - int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); - int32x2_t a23 = vrev64_s32(vget_high_s32(vreinterpretq_s32_m128i(a))); - return vreinterpretq_m128i_s32(vcombine_s32(a01, a23)); -} + // Test for vrsqrteq_f32(0) -> positive infinity case. + // Change to zero, so that s * 1/sqrt(s) result is zero too. + const uint32x4_t pos_inf = vdupq_n_u32(0x7F800000); + const uint32x4_t div_by_zero = + vceqq_u32(pos_inf, vreinterpretq_u32_f32(recip)); + recip = vreinterpretq_f32_u32( + vandq_u32(vmvnq_u32(div_by_zero), vreinterpretq_u32_f32(recip))); -// rotates the least significant 32 bits into the most signficant 32 bits, and -// shifts the rest down -FORCE_INLINE __m128i _mm_shuffle_epi_0321(__m128i a) -{ - return vreinterpretq_m128i_s32( - vextq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(a), 1)); -} + // Additional Netwon-Raphson iteration for accuracy + recip = vmulq_f32( + vrsqrtsq_f32(vmulq_f32(recip, recip), vreinterpretq_f32_m128(in)), + recip); + recip = vmulq_f32( + vrsqrtsq_f32(vmulq_f32(recip, recip), vreinterpretq_f32_m128(in)), + recip); -// rotates the most significant 32 bits into the least signficant 32 bits, and -// shifts the rest up -FORCE_INLINE __m128i _mm_shuffle_epi_2103(__m128i a) -{ - return vreinterpretq_m128i_s32( - vextq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(a), 3)); -} - -// gets the lower 64 bits of a, and places it in the upper 64 bits -// gets the lower 64 bits of a and places it in the lower 64 bits -FORCE_INLINE __m128i _mm_shuffle_epi_1010(__m128i a) -{ - int32x2_t a10 = vget_low_s32(vreinterpretq_s32_m128i(a)); - return vreinterpretq_m128i_s32(vcombine_s32(a10, a10)); -} - -// gets the lower 64 bits of a, swaps the 0 and 1 elements, and places it in the -// lower 64 bits gets the lower 64 bits of a, and places it in the upper 64 bits -FORCE_INLINE __m128i _mm_shuffle_epi_1001(__m128i a) -{ - int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); - int32x2_t a10 = vget_low_s32(vreinterpretq_s32_m128i(a)); - return vreinterpretq_m128i_s32(vcombine_s32(a01, a10)); -} - -// gets the lower 64 bits of a, swaps the 0 and 1 elements and places it in the -// upper 64 bits gets the lower 64 bits of a, swaps the 0 and 1 elements, and -// places it in the lower 64 bits -FORCE_INLINE __m128i _mm_shuffle_epi_0101(__m128i a) -{ - int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); - return vreinterpretq_m128i_s32(vcombine_s32(a01, a01)); -} - -FORCE_INLINE __m128i _mm_shuffle_epi_2211(__m128i a) -{ - int32x2_t a11 = vdup_lane_s32(vget_low_s32(vreinterpretq_s32_m128i(a)), 1); - int32x2_t a22 = vdup_lane_s32(vget_high_s32(vreinterpretq_s32_m128i(a)), 0); - return vreinterpretq_m128i_s32(vcombine_s32(a11, a22)); -} - -FORCE_INLINE __m128i _mm_shuffle_epi_0122(__m128i a) -{ - int32x2_t a22 = vdup_lane_s32(vget_high_s32(vreinterpretq_s32_m128i(a)), 0); - int32x2_t a01 = vrev64_s32(vget_low_s32(vreinterpretq_s32_m128i(a))); - return vreinterpretq_m128i_s32(vcombine_s32(a22, a01)); -} - -FORCE_INLINE __m128i _mm_shuffle_epi_3332(__m128i a) -{ - int32x2_t a32 = vget_high_s32(vreinterpretq_s32_m128i(a)); - int32x2_t a33 = vdup_lane_s32(vget_high_s32(vreinterpretq_s32_m128i(a)), 1); - return vreinterpretq_m128i_s32(vcombine_s32(a32, a33)); -} - -// Shuffle packed 8-bit integers in a according to shuffle control mask in the -// corresponding 8-bit element of b, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_shuffle_epi8 -FORCE_INLINE __m128i _mm_shuffle_epi8(__m128i a, __m128i b) -{ - int8x16_t tbl = vreinterpretq_s8_m128i(a); // input a - uint8x16_t idx = vreinterpretq_u8_m128i(b); // input b - uint8x16_t idx_masked = - vandq_u8(idx, vdupq_n_u8(0x8F)); // avoid using meaningless bits -#if defined(__aarch64__) - return vreinterpretq_m128i_s8(vqtbl1q_s8(tbl, idx_masked)); -#elif defined(__GNUC__) - int8x16_t ret; - // %e and %f represent the even and odd D registers - // respectively. - __asm__ __volatile__( - "vtbl.8 %e[ret], {%e[tbl], %f[tbl]}, %e[idx]\n" - "vtbl.8 %f[ret], {%e[tbl], %f[tbl]}, %f[idx]\n" - : [ret] "=&w"(ret) - : [tbl] "w"(tbl), [idx] "w"(idx_masked)); - return vreinterpretq_m128i_s8(ret); + // sqrt(s) = s * 1/sqrt(s) + return vreinterpretq_m128_f32(vmulq_f32(vreinterpretq_f32_m128(in), recip)); +#elif defined(__aarch64__) + return vreinterpretq_m128_f32(vsqrtq_f32(vreinterpretq_f32_m128(in))); #else - // use this line if testing on aarch64 - int8x8x2_t a_split = {vget_low_s8(tbl), vget_high_s8(tbl)}; + float32x4_t recipsq = vrsqrteq_f32(vreinterpretq_f32_m128(in)); + float32x4_t sq = vrecpeq_f32(recipsq); + return vreinterpretq_m128_f32(sq); +#endif +} + +// Computes the approximation of the square root of the scalar single-precision +// floating point value of in. +// https://msdn.microsoft.com/en-us/library/ahfsc22d(v=vs.100).aspx +FORCE_INLINE __m128 _mm_sqrt_ss(__m128 in) +{ + float32_t value = + vgetq_lane_f32(vreinterpretq_f32_m128(_mm_sqrt_ps(in)), 0); + return vreinterpretq_m128_f32( + vsetq_lane_f32(value, vreinterpretq_f32_m128(in), 0)); +} + +// Stores four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/vstudio/s3h4ay6y(v=vs.100).aspx +FORCE_INLINE void _mm_store_ps(float *p, __m128 a) +{ + vst1q_f32(p, vreinterpretq_f32_m128(a)); +} + +// Store the lower single-precision (32-bit) floating-point element from a into +// 4 contiguous elements in memory. mem_addr must be aligned on a 16-byte +// boundary or a general-protection exception may be generated. +// +// MEM[mem_addr+31:mem_addr] := a[31:0] +// MEM[mem_addr+63:mem_addr+32] := a[31:0] +// MEM[mem_addr+95:mem_addr+64] := a[31:0] +// MEM[mem_addr+127:mem_addr+96] := a[31:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store_ps1 +FORCE_INLINE void _mm_store_ps1(float *p, __m128 a) +{ + float32_t a0 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); + vst1q_f32(p, vdupq_n_f32(a0)); +} + +// Stores the lower single - precision, floating - point value. +// https://msdn.microsoft.com/en-us/library/tzz10fbx(v=vs.100).aspx +FORCE_INLINE void _mm_store_ss(float *p, __m128 a) +{ + vst1q_lane_f32(p, vreinterpretq_f32_m128(a), 0); +} + +// Store the lower single-precision (32-bit) floating-point element from a into +// 4 contiguous elements in memory. mem_addr must be aligned on a 16-byte +// boundary or a general-protection exception may be generated. +// +// MEM[mem_addr+31:mem_addr] := a[31:0] +// MEM[mem_addr+63:mem_addr+32] := a[31:0] +// MEM[mem_addr+95:mem_addr+64] := a[31:0] +// MEM[mem_addr+127:mem_addr+96] := a[31:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store1_ps +#define _mm_store1_ps _mm_store_ps1 + +// Stores the upper two single-precision, floating-point values of a to the +// address p. +// +// *p0 := a2 +// *p1 := a3 +// +// https://msdn.microsoft.com/en-us/library/a7525fs8(v%3dvs.90).aspx +FORCE_INLINE void _mm_storeh_pi(__m64 *p, __m128 a) +{ + *p = vreinterpret_m64_f32(vget_high_f32(a)); +} + +// Stores the lower two single-precision floating point values of a to the +// address p. +// +// *p0 := a0 +// *p1 := a1 +// +// https://msdn.microsoft.com/en-us/library/h54t98ks(v=vs.90).aspx +FORCE_INLINE void _mm_storel_pi(__m64 *p, __m128 a) +{ + *p = vreinterpret_m64_f32(vget_low_f32(a)); +} + +// Store 4 single-precision (32-bit) floating-point elements from a into memory +// in reverse order. mem_addr must be aligned on a 16-byte boundary or a +// general-protection exception may be generated. +// +// MEM[mem_addr+31:mem_addr] := a[127:96] +// MEM[mem_addr+63:mem_addr+32] := a[95:64] +// MEM[mem_addr+95:mem_addr+64] := a[63:32] +// MEM[mem_addr+127:mem_addr+96] := a[31:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storer_ps +FORCE_INLINE void _mm_storer_ps(float *p, __m128 a) +{ + float32x4_t tmp = vrev64q_f32(vreinterpretq_f32_m128(a)); + float32x4_t rev = vextq_f32(tmp, tmp, 2); + vst1q_f32(p, rev); +} + +// Stores four single-precision, floating-point values. +// https://msdn.microsoft.com/en-us/library/44e30x22(v=vs.100).aspx +FORCE_INLINE void _mm_storeu_ps(float *p, __m128 a) +{ + vst1q_f32(p, vreinterpretq_f32_m128(a)); +} + +// Stores 16-bits of integer data a at the address p. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_si16 +FORCE_INLINE void _mm_storeu_si16(void *p, __m128i a) +{ + vst1q_lane_s16((int16_t *) p, vreinterpretq_s16_m128i(a), 0); +} + +// Stores 64-bits of integer data a at the address p. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_si64 +FORCE_INLINE void _mm_storeu_si64(void *p, __m128i a) +{ + vst1q_lane_s64((int64_t *) p, vreinterpretq_s64_m128i(a), 0); +} + +// Store 64-bits of integer data from a into memory using a non-temporal memory +// hint. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_pi +FORCE_INLINE void _mm_stream_pi(__m64 *p, __m64 a) +{ + vst1_s64((int64_t *) p, vreinterpret_s64_m64(a)); +} + +// Store 128-bits (composed of 4 packed single-precision (32-bit) floating- +// point elements) from a into memory using a non-temporal memory hint. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_ps +FORCE_INLINE void _mm_stream_ps(float *p, __m128 a) +{ +#if __has_builtin(__builtin_nontemporal_store) + __builtin_nontemporal_store(a, (float32x4_t *) p); +#else + vst1q_f32(p, vreinterpretq_f32_m128(a)); +#endif +} + +// Subtracts the four single-precision, floating-point values of a and b. +// +// r0 := a0 - b0 +// r1 := a1 - b1 +// r2 := a2 - b2 +// r3 := a3 - b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/1zad2k61(v=vs.100).aspx +FORCE_INLINE __m128 _mm_sub_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_f32( + vsubq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +} + +// Subtract the lower single-precision (32-bit) floating-point element in b from +// the lower single-precision (32-bit) floating-point element in a, store the +// result in the lower element of dst, and copy the upper 3 packed elements from +// a to the upper elements of dst. +// +// dst[31:0] := a[31:0] - b[31:0] +// dst[127:32] := a[127:32] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_ss +FORCE_INLINE __m128 _mm_sub_ss(__m128 a, __m128 b) +{ + return _mm_move_ss(a, _mm_sub_ps(a, b)); +} + +// Macro: Transpose the 4x4 matrix formed by the 4 rows of single-precision +// (32-bit) floating-point elements in row0, row1, row2, and row3, and store the +// transposed matrix in these vectors (row0 now contains column 0, etc.). +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=MM_TRANSPOSE4_PS +#define _MM_TRANSPOSE4_PS(row0, row1, row2, row3) \ + do { \ + float32x4x2_t ROW01 = vtrnq_f32(row0, row1); \ + float32x4x2_t ROW23 = vtrnq_f32(row2, row3); \ + row0 = vcombine_f32(vget_low_f32(ROW01.val[0]), \ + vget_low_f32(ROW23.val[0])); \ + row1 = vcombine_f32(vget_low_f32(ROW01.val[1]), \ + vget_low_f32(ROW23.val[1])); \ + row2 = vcombine_f32(vget_high_f32(ROW01.val[0]), \ + vget_high_f32(ROW23.val[0])); \ + row3 = vcombine_f32(vget_high_f32(ROW01.val[1]), \ + vget_high_f32(ROW23.val[1])); \ + } while (0) + +// according to the documentation, these intrinsics behave the same as the +// non-'u' versions. We'll just alias them here. +#define _mm_ucomieq_ss _mm_comieq_ss +#define _mm_ucomige_ss _mm_comige_ss +#define _mm_ucomigt_ss _mm_comigt_ss +#define _mm_ucomile_ss _mm_comile_ss +#define _mm_ucomilt_ss _mm_comilt_ss +#define _mm_ucomineq_ss _mm_comineq_ss + +// Return vector of type __m128i with undefined elements. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_undefined_si128 +FORCE_INLINE __m128i _mm_undefined_si128(void) +{ +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wuninitialized" +#endif + __m128i a; + return a; +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif +} + +// Return vector of type __m128 with undefined elements. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_undefined_ps +FORCE_INLINE __m128 _mm_undefined_ps(void) +{ +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wuninitialized" +#endif + __m128 a; + return a; +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif +} + +// Selects and interleaves the upper two single-precision, floating-point values +// from a and b. +// +// r0 := a2 +// r1 := b2 +// r2 := a3 +// r3 := b3 +// +// https://msdn.microsoft.com/en-us/library/skccxx7d%28v=vs.90%29.aspx +FORCE_INLINE __m128 _mm_unpackhi_ps(__m128 a, __m128 b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128_f32( + vzip2q_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#else + float32x2_t a1 = vget_high_f32(vreinterpretq_f32_m128(a)); + float32x2_t b1 = vget_high_f32(vreinterpretq_f32_m128(b)); + float32x2x2_t result = vzip_f32(a1, b1); + return vreinterpretq_m128_f32(vcombine_f32(result.val[0], result.val[1])); +#endif +} + +// Selects and interleaves the lower two single-precision, floating-point values +// from a and b. +// +// r0 := a0 +// r1 := b0 +// r2 := a1 +// r3 := b1 +// +// https://msdn.microsoft.com/en-us/library/25st103b%28v=vs.90%29.aspx +FORCE_INLINE __m128 _mm_unpacklo_ps(__m128 a, __m128 b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128_f32( + vzip1q_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#else + float32x2_t a1 = vget_low_f32(vreinterpretq_f32_m128(a)); + float32x2_t b1 = vget_low_f32(vreinterpretq_f32_m128(b)); + float32x2x2_t result = vzip_f32(a1, b1); + return vreinterpretq_m128_f32(vcombine_f32(result.val[0], result.val[1])); +#endif +} + +// Computes bitwise EXOR (exclusive-or) of the four single-precision, +// floating-point values of a and b. +// https://msdn.microsoft.com/en-us/library/ss6k3wk8(v=vs.100).aspx +FORCE_INLINE __m128 _mm_xor_ps(__m128 a, __m128 b) +{ + return vreinterpretq_m128_s32( + veorq_s32(vreinterpretq_s32_m128(a), vreinterpretq_s32_m128(b))); +} + +/* SSE2 */ + +// Adds the 8 signed or unsigned 16-bit integers in a to the 8 signed or +// unsigned 16-bit integers in b. +// https://msdn.microsoft.com/en-us/library/fceha5k4(v=vs.100).aspx +FORCE_INLINE __m128i _mm_add_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vaddq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Adds the 4 signed or unsigned 32-bit integers in a to the 4 signed or +// unsigned 32-bit integers in b. +// +// r0 := a0 + b0 +// r1 := a1 + b1 +// r2 := a2 + b2 +// r3 := a3 + b3 +// +// https://msdn.microsoft.com/en-us/library/vstudio/09xs4fkk(v=vs.100).aspx +FORCE_INLINE __m128i _mm_add_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vaddq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Adds the 4 signed or unsigned 64-bit integers in a to the 4 signed or +// unsigned 32-bit integers in b. +// https://msdn.microsoft.com/en-us/library/vstudio/09xs4fkk(v=vs.100).aspx +FORCE_INLINE __m128i _mm_add_epi64(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s64( + vaddq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b))); +} + +// Adds the 16 signed or unsigned 8-bit integers in a to the 16 signed or +// unsigned 8-bit integers in b. +// https://technet.microsoft.com/en-us/subscriptions/yc7tcyzs(v=vs.90) +FORCE_INLINE __m128i _mm_add_epi8(__m128i a, __m128i b) +{ return vreinterpretq_m128i_s8( - vcombine_s8(vtbl2_s8(a_split, vget_low_u8(idx_masked)), - vtbl2_s8(a_split, vget_high_u8(idx_masked)))); + vaddq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Add packed double-precision (64-bit) floating-point elements in a and b, and +// store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_add_pd +FORCE_INLINE __m128d _mm_add_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vaddq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + double *da = (double *) &a; + double *db = (double *) &b; + double c[2]; + c[0] = da[0] + db[0]; + c[1] = da[1] + db[1]; + return vld1q_f32((float32_t *) c); #endif } -// C equivalent: -// __m128i _mm_shuffle_epi32_default(__m128i a, -// __constrange(0, 255) int imm) { -// __m128i ret; -// ret[0] = a[imm & 0x3]; ret[1] = a[(imm >> 2) & 0x3]; -// ret[2] = a[(imm >> 4) & 0x03]; ret[3] = a[(imm >> 6) & 0x03]; -// return ret; -// } -#define _mm_shuffle_epi32_default(a, imm) \ - __extension__({ \ - int32x4_t ret; \ - ret = vmovq_n_s32( \ - vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm) & (0x3))); \ - ret = vsetq_lane_s32( \ - vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 2) & 0x3), \ - ret, 1); \ - ret = vsetq_lane_s32( \ - vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 4) & 0x3), \ - ret, 2); \ - ret = vsetq_lane_s32( \ - vgetq_lane_s32(vreinterpretq_s32_m128i(a), ((imm) >> 6) & 0x3), \ - ret, 3); \ - vreinterpretq_m128i_s32(ret); \ - }) - -// FORCE_INLINE __m128i _mm_shuffle_epi32_splat(__m128i a, __constrange(0,255) -// int imm) +// Add the lower double-precision (64-bit) floating-point element in a and b, +// store the result in the lower element of dst, and copy the upper element from +// a to the upper element of dst. +// +// dst[63:0] := a[63:0] + b[63:0] +// dst[127:64] := a[127:64] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_add_sd +FORCE_INLINE __m128d _mm_add_sd(__m128d a, __m128d b) +{ #if defined(__aarch64__) -#define _mm_shuffle_epi32_splat(a, imm) \ - __extension__({ \ - vreinterpretq_m128i_s32( \ - vdupq_laneq_s32(vreinterpretq_s32_m128i(a), (imm))); \ - }) + return _mm_move_sd(a, _mm_add_pd(a, b)); #else -#define _mm_shuffle_epi32_splat(a, imm) \ - __extension__({ \ - vreinterpretq_m128i_s32( \ - vdupq_n_s32(vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm)))); \ - }) + double *da = (double *) &a; + double *db = (double *) &b; + double c[2]; + c[0] = da[0] + db[0]; + c[1] = da[1]; + return vld1q_f32((float32_t *) c); #endif +} -// Shuffles the 4 signed or unsigned 32-bit integers in a as specified by imm. -// https://msdn.microsoft.com/en-us/library/56f67xbk%28v=vs.90%29.aspx -// FORCE_INLINE __m128i _mm_shuffle_epi32(__m128i a, -// __constrange(0,255) int imm) -#if __has_builtin(__builtin_shufflevector) -#define _mm_shuffle_epi32(a, imm) \ - __extension__({ \ - int32x4_t _input = vreinterpretq_s32_m128i(a); \ - int32x4_t _shuf = __builtin_shufflevector( \ - _input, _input, (imm) & (0x3), ((imm) >> 2) & 0x3, \ - ((imm) >> 4) & 0x3, ((imm) >> 6) & 0x3); \ - vreinterpretq_m128i_s32(_shuf); \ - }) -#else // generic -#define _mm_shuffle_epi32(a, imm) \ - __extension__({ \ - __m128i ret; \ - switch (imm) { \ - case _MM_SHUFFLE(1, 0, 3, 2): \ - ret = _mm_shuffle_epi_1032((a)); \ - break; \ - case _MM_SHUFFLE(2, 3, 0, 1): \ - ret = _mm_shuffle_epi_2301((a)); \ - break; \ - case _MM_SHUFFLE(0, 3, 2, 1): \ - ret = _mm_shuffle_epi_0321((a)); \ - break; \ - case _MM_SHUFFLE(2, 1, 0, 3): \ - ret = _mm_shuffle_epi_2103((a)); \ - break; \ - case _MM_SHUFFLE(1, 0, 1, 0): \ - ret = _mm_shuffle_epi_1010((a)); \ - break; \ - case _MM_SHUFFLE(1, 0, 0, 1): \ - ret = _mm_shuffle_epi_1001((a)); \ - break; \ - case _MM_SHUFFLE(0, 1, 0, 1): \ - ret = _mm_shuffle_epi_0101((a)); \ - break; \ - case _MM_SHUFFLE(2, 2, 1, 1): \ - ret = _mm_shuffle_epi_2211((a)); \ - break; \ - case _MM_SHUFFLE(0, 1, 2, 2): \ - ret = _mm_shuffle_epi_0122((a)); \ - break; \ - case _MM_SHUFFLE(3, 3, 3, 2): \ - ret = _mm_shuffle_epi_3332((a)); \ - break; \ - case _MM_SHUFFLE(0, 0, 0, 0): \ - ret = _mm_shuffle_epi32_splat((a), 0); \ - break; \ - case _MM_SHUFFLE(1, 1, 1, 1): \ - ret = _mm_shuffle_epi32_splat((a), 1); \ - break; \ - case _MM_SHUFFLE(2, 2, 2, 2): \ - ret = _mm_shuffle_epi32_splat((a), 2); \ - break; \ - case _MM_SHUFFLE(3, 3, 3, 3): \ - ret = _mm_shuffle_epi32_splat((a), 3); \ - break; \ - default: \ - ret = _mm_shuffle_epi32_default((a), (imm)); \ - break; \ - } \ - ret; \ - }) -#endif - -// Shuffles the lower 4 signed or unsigned 16-bit integers in a as specified -// by imm. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/y41dkk37(v=vs.100) -// FORCE_INLINE __m128i _mm_shufflelo_epi16_function(__m128i a, -// __constrange(0,255) int -// imm) -#define _mm_shufflelo_epi16_function(a, imm) \ - __extension__({ \ - int16x8_t ret = vreinterpretq_s16_m128i(a); \ - int16x4_t lowBits = vget_low_s16(ret); \ - ret = vsetq_lane_s16(vget_lane_s16(lowBits, (imm) & (0x3)), ret, 0); \ - ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 2) & 0x3), ret, \ - 1); \ - ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 4) & 0x3), ret, \ - 2); \ - ret = vsetq_lane_s16(vget_lane_s16(lowBits, ((imm) >> 6) & 0x3), ret, \ - 3); \ - vreinterpretq_m128i_s16(ret); \ - }) - -// FORCE_INLINE __m128i _mm_shufflelo_epi16(__m128i a, -// __constrange(0,255) int imm) -#if __has_builtin(__builtin_shufflevector) -#define _mm_shufflelo_epi16(a, imm) \ - __extension__({ \ - int16x8_t _input = vreinterpretq_s16_m128i(a); \ - int16x8_t _shuf = __builtin_shufflevector( \ - _input, _input, ((imm) & (0x3)), (((imm) >> 2) & 0x3), \ - (((imm) >> 4) & 0x3), (((imm) >> 6) & 0x3), 4, 5, 6, 7); \ - vreinterpretq_m128i_s16(_shuf); \ - }) -#else // generic -#define _mm_shufflelo_epi16(a, imm) _mm_shufflelo_epi16_function((a), (imm)) -#endif - -// Shuffles the upper 4 signed or unsigned 16-bit integers in a as specified -// by imm. -// https://msdn.microsoft.com/en-us/library/13ywktbs(v=vs.100).aspx -// FORCE_INLINE __m128i _mm_shufflehi_epi16_function(__m128i a, -// __constrange(0,255) int -// imm) -#define _mm_shufflehi_epi16_function(a, imm) \ - __extension__({ \ - int16x8_t ret = vreinterpretq_s16_m128i(a); \ - int16x4_t highBits = vget_high_s16(ret); \ - ret = vsetq_lane_s16(vget_lane_s16(highBits, (imm) & (0x3)), ret, 4); \ - ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 2) & 0x3), ret, \ - 5); \ - ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 4) & 0x3), ret, \ - 6); \ - ret = vsetq_lane_s16(vget_lane_s16(highBits, ((imm) >> 6) & 0x3), ret, \ - 7); \ - vreinterpretq_m128i_s16(ret); \ - }) - -// FORCE_INLINE __m128i _mm_shufflehi_epi16(__m128i a, -// __constrange(0,255) int imm) -#if __has_builtin(__builtin_shufflevector) -#define _mm_shufflehi_epi16(a, imm) \ - __extension__({ \ - int16x8_t _input = vreinterpretq_s16_m128i(a); \ - int16x8_t _shuf = __builtin_shufflevector( \ - _input, _input, 0, 1, 2, 3, ((imm) & (0x3)) + 4, \ - (((imm) >> 2) & 0x3) + 4, (((imm) >> 4) & 0x3) + 4, \ - (((imm) >> 6) & 0x3) + 4); \ - vreinterpretq_m128i_s16(_shuf); \ - }) -#else // generic -#define _mm_shufflehi_epi16(a, imm) _mm_shufflehi_epi16_function((a), (imm)) -#endif - -// Shuffle double-precision (64-bit) floating-point elements using the control -// in imm8, and store the results in dst. +// Add 64-bit integers a and b, and store the result in dst. // -// dst[63:0] := (imm8[0] == 0) ? a[63:0] : a[127:64] -// dst[127:64] := (imm8[1] == 0) ? b[63:0] : b[127:64] +// dst[63:0] := a[63:0] + b[63:0] // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_shuffle_pd -#if __has_builtin(__builtin_shufflevector) -#define _mm_shuffle_pd(a, b, imm8) \ - vreinterpretq_m128d_s64(__builtin_shufflevector( \ - vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b), imm8 & 0x1, \ - ((imm8 & 0x2) >> 1) + 2)) -#else -#define _mm_shuffle_pd(a, b, imm8) \ - _mm_castsi128_pd(_mm_set_epi64x( \ - vgetq_lane_s64(vreinterpretq_s64_m128d(b), (imm8 & 0x2) >> 1), \ - vgetq_lane_s64(vreinterpretq_s64_m128d(a), imm8 & 0x1))) -#endif +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_add_si64 +FORCE_INLINE __m64 _mm_add_si64(__m64 a, __m64 b) +{ + return vreinterpret_m64_s64( + vadd_s64(vreinterpret_s64_m64(a), vreinterpret_s64_m64(b))); +} -// Blend packed 16-bit integers from a and b using control mask imm8, and store -// the results in dst. +// Adds the 8 signed 16-bit integers in a to the 8 signed 16-bit integers in b +// and saturates. // -// FOR j := 0 to 7 -// i := j*16 -// IF imm8[j] -// dst[i+15:i] := b[i+15:i] -// ELSE -// dst[i+15:i] := a[i+15:i] -// FI -// ENDFOR -// FORCE_INLINE __m128i _mm_blend_epi16(__m128i a, __m128i b, -// __constrange(0,255) int imm) -#define _mm_blend_epi16(a, b, imm) \ - __extension__({ \ - const uint16_t _mask[8] = {((imm) & (1 << 0)) ? (uint16_t) -1 : 0x0, \ - ((imm) & (1 << 1)) ? (uint16_t) -1 : 0x0, \ - ((imm) & (1 << 2)) ? (uint16_t) -1 : 0x0, \ - ((imm) & (1 << 3)) ? (uint16_t) -1 : 0x0, \ - ((imm) & (1 << 4)) ? (uint16_t) -1 : 0x0, \ - ((imm) & (1 << 5)) ? (uint16_t) -1 : 0x0, \ - ((imm) & (1 << 6)) ? (uint16_t) -1 : 0x0, \ - ((imm) & (1 << 7)) ? (uint16_t) -1 : 0x0}; \ - uint16x8_t _mask_vec = vld1q_u16(_mask); \ - uint16x8_t _a = vreinterpretq_u16_m128i(a); \ - uint16x8_t _b = vreinterpretq_u16_m128i(b); \ - vreinterpretq_m128i_u16(vbslq_u16(_mask_vec, _b, _a)); \ - }) +// r0 := SignedSaturate(a0 + b0) +// r1 := SignedSaturate(a1 + b1) +// ... +// r7 := SignedSaturate(a7 + b7) +// +// https://msdn.microsoft.com/en-us/library/1a306ef8(v=vs.100).aspx +FORCE_INLINE __m128i _mm_adds_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vqaddq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} -// Blend packed double-precision (64-bit) floating-point elements from a and b -// using control mask imm8, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_blend_pd -#define _mm_blend_pd(a, b, imm) \ - __extension__({ \ - const uint64_t _mask[2] = { \ - ((imm) & (1 << 0)) ? ~UINT64_C(0) : UINT64_C(0), \ - ((imm) & (1 << 1)) ? ~UINT64_C(0) : UINT64_C(0)}; \ - uint64x2_t _mask_vec = vld1q_u64(_mask); \ - uint64x2_t _a = vreinterpretq_u64_m128d(a); \ - uint64x2_t _b = vreinterpretq_u64_m128d(b); \ - vreinterpretq_m128d_u64(vbslq_u64(_mask_vec, _b, _a)); \ - }) - -// Blend packed 8-bit integers from a and b using mask, and store the results in -// dst. +// Add packed signed 8-bit integers in a and b using saturation, and store the +// results in dst. // // FOR j := 0 to 15 -// i := j*8 -// IF mask[i+7] -// dst[i+7:i] := b[i+7:i] -// ELSE -// dst[i+7:i] := a[i+7:i] -// FI -// ENDFOR -FORCE_INLINE __m128i _mm_blendv_epi8(__m128i _a, __m128i _b, __m128i _mask) -{ - // Use a signed shift right to create a mask with the sign bit - uint8x16_t mask = - vreinterpretq_u8_s8(vshrq_n_s8(vreinterpretq_s8_m128i(_mask), 7)); - uint8x16_t a = vreinterpretq_u8_m128i(_a); - uint8x16_t b = vreinterpretq_u8_m128i(_b); - return vreinterpretq_m128i_u8(vbslq_u8(mask, b, a)); -} - -/* Shifts */ - - -// Shift packed 16-bit integers in a right by imm while shifting in sign -// bits, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srai_epi16 -FORCE_INLINE __m128i _mm_srai_epi16(__m128i a, int imm) -{ - const int count = (imm & ~15) ? 15 : imm; - return (__m128i) vshlq_s16((int16x8_t) a, vdupq_n_s16(-count)); -} - -// Shifts the 8 signed or unsigned 16-bit integers in a left by count bits while -// shifting in zeros. -// -// r0 := a0 << count -// r1 := a1 << count -// ... -// r7 := a7 << count -// -// https://msdn.microsoft.com/en-us/library/es73bcsy(v=vs.90).aspx -#define _mm_slli_epi16(a, imm) \ - __extension__({ \ - __m128i ret; \ - if (unlikely((imm)) <= 0) { \ - ret = a; \ - } \ - if (unlikely((imm) > 15)) { \ - ret = _mm_setzero_si128(); \ - } else { \ - ret = vreinterpretq_m128i_s16( \ - vshlq_n_s16(vreinterpretq_s16_m128i(a), (imm))); \ - } \ - ret; \ - }) - -// Shifts the 4 signed or unsigned 32-bit integers in a left by count bits while -// shifting in zeros. : -// https://msdn.microsoft.com/en-us/library/z2k3bbtb%28v=vs.90%29.aspx -// FORCE_INLINE __m128i _mm_slli_epi32(__m128i a, __constrange(0,255) int imm) -FORCE_INLINE __m128i _mm_slli_epi32(__m128i a, int imm) -{ - if (unlikely(imm <= 0)) /* TODO: add constant range macro: [0, 255] */ - return a; - if (unlikely(imm > 31)) - return _mm_setzero_si128(); - return vreinterpretq_m128i_s32( - vshlq_s32(vreinterpretq_s32_m128i(a), vdupq_n_s32(imm))); -} - -// Shift packed 64-bit integers in a left by imm8 while shifting in zeros, and -// store the results in dst. -FORCE_INLINE __m128i _mm_slli_epi64(__m128i a, int imm) -{ - if (unlikely(imm <= 0)) /* TODO: add constant range macro: [0, 255] */ - return a; - if (unlikely(imm > 63)) - return _mm_setzero_si128(); - return vreinterpretq_m128i_s64( - vshlq_s64(vreinterpretq_s64_m128i(a), vdupq_n_s64(imm))); -} - -// Shift packed 16-bit integers in a right by imm8 while shifting in zeros, and -// store the results in dst. -// -// FOR j := 0 to 7 -// i := j*16 -// IF imm8[7:0] > 15 -// dst[i+15:i] := 0 -// ELSE -// dst[i+15:i] := ZeroExtend16(a[i+15:i] >> imm8[7:0]) -// FI +// i := j*8 +// dst[i+7:i] := Saturate8( a[i+7:i] + b[i+7:i] ) // ENDFOR // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srli_epi16 -#define _mm_srli_epi16(a, imm) \ - __extension__({ \ - __m128i ret; \ - if (unlikely(imm) == 0) { \ - ret = a; \ - } \ - if (likely(0 < (imm) && (imm) < 16)) { \ - ret = vreinterpretq_m128i_u16( \ - vshlq_u16(vreinterpretq_u16_m128i(a), vdupq_n_s16(-imm))); \ - } else { \ - ret = _mm_setzero_si128(); \ - } \ - ret; \ - }) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_adds_epi8 +FORCE_INLINE __m128i _mm_adds_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s8( + vqaddq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} -// Shift packed 32-bit integers in a right by imm8 while shifting in zeros, and -// store the results in dst. -// -// FOR j := 0 to 3 -// i := j*32 -// IF imm8[7:0] > 31 -// dst[i+31:i] := 0 -// ELSE -// dst[i+31:i] := ZeroExtend32(a[i+31:i] >> imm8[7:0]) -// FI -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srli_epi32 -// FORCE_INLINE __m128i _mm_srli_epi32(__m128i a, __constrange(0,255) int imm) -#define _mm_srli_epi32(a, imm) \ - __extension__({ \ - __m128i ret; \ - if (unlikely((imm) == 0)) { \ - ret = a; \ - } \ - if (likely(0 < (imm) && (imm) < 32)) { \ - ret = vreinterpretq_m128i_u32( \ - vshlq_u32(vreinterpretq_u32_m128i(a), vdupq_n_s32(-imm))); \ - } else { \ - ret = _mm_setzero_si128(); \ - } \ - ret; \ - }) +// Add packed unsigned 16-bit integers in a and b using saturation, and store +// the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_adds_epu16 +FORCE_INLINE __m128i _mm_adds_epu16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vqaddq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); +} -// Shift packed 64-bit integers in a right by imm8 while shifting in zeros, and -// store the results in dst. +// Adds the 16 unsigned 8-bit integers in a to the 16 unsigned 8-bit integers in +// b and saturates.. +// https://msdn.microsoft.com/en-us/library/9hahyddy(v=vs.100).aspx +FORCE_INLINE __m128i _mm_adds_epu8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vqaddq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); +} + +// Compute the bitwise AND of packed double-precision (64-bit) floating-point +// elements in a and b, and store the results in dst. // // FOR j := 0 to 1 // i := j*64 -// IF imm8[7:0] > 63 -// dst[i+63:i] := 0 -// ELSE -// dst[i+63:i] := ZeroExtend64(a[i+63:i] >> imm8[7:0]) -// FI +// dst[i+63:i] := a[i+63:i] AND b[i+63:i] // ENDFOR // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srli_epi64 -#define _mm_srli_epi64(a, imm) \ - __extension__({ \ - __m128i ret; \ - if (unlikely((imm) == 0)) { \ - ret = a; \ - } \ - if (likely(0 < (imm) && (imm) < 64)) { \ - ret = vreinterpretq_m128i_u64( \ - vshlq_u64(vreinterpretq_u64_m128i(a), vdupq_n_s64(-imm))); \ - } else { \ - ret = _mm_setzero_si128(); \ - } \ - ret; \ - }) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_and_pd +FORCE_INLINE __m128d _mm_and_pd(__m128d a, __m128d b) +{ + return vreinterpretq_m128d_s64( + vandq_s64(vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b))); +} -// Shift packed 32-bit integers in a right by imm8 while shifting in sign bits, -// and store the results in dst. +// Computes the bitwise AND of the 128-bit value in a and the 128-bit value in +// b. // -// FOR j := 0 to 3 -// i := j*32 -// IF imm8[7:0] > 31 -// dst[i+31:i] := (a[i+31] ? 0xFFFFFFFF : 0x0) -// ELSE -// dst[i+31:i] := SignExtend32(a[i+31:i] >> imm8[7:0]) -// FI +// r := a & b +// +// https://msdn.microsoft.com/en-us/library/vstudio/6d1txsa8(v=vs.100).aspx +FORCE_INLINE __m128i _mm_and_si128(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vandq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Compute the bitwise NOT of packed double-precision (64-bit) floating-point +// elements in a and then AND with b, and store the results in dst. +// +// FOR j := 0 to 1 +// i := j*64 +// dst[i+63:i] := ((NOT a[i+63:i]) AND b[i+63:i]) // ENDFOR // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srai_epi32 -// FORCE_INLINE __m128i _mm_srai_epi32(__m128i a, __constrange(0,255) int imm) -#define _mm_srai_epi32(a, imm) \ - __extension__({ \ - __m128i ret; \ - if (unlikely((imm) == 0)) { \ - ret = a; \ - } \ - if (likely(0 < (imm) && (imm) < 32)) { \ - ret = vreinterpretq_m128i_s32( \ - vshlq_s32(vreinterpretq_s32_m128i(a), vdupq_n_s32(-imm))); \ - } else { \ - ret = vreinterpretq_m128i_s32( \ - vshrq_n_s32(vreinterpretq_s32_m128i(a), 31)); \ - } \ - ret; \ - }) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_andnot_pd +FORCE_INLINE __m128d _mm_andnot_pd(__m128d a, __m128d b) +{ + // *NOTE* argument swap + return vreinterpretq_m128d_s64( + vbicq_s64(vreinterpretq_s64_m128d(b), vreinterpretq_s64_m128d(a))); +} -// Shifts the 128 - bit value in a right by imm bytes while shifting in -// zeros.imm must be an immediate. +// Computes the bitwise AND of the 128-bit value in b and the bitwise NOT of the +// 128-bit value in a. // -// r := srl(a, imm*8) +// r := (~a) & b // -// https://msdn.microsoft.com/en-us/library/305w28yz(v=vs.100).aspx -// FORCE_INLINE _mm_srli_si128(__m128i a, __constrange(0,255) int imm) -#define _mm_srli_si128(a, imm) \ - __extension__({ \ - __m128i ret; \ - if (unlikely((imm) <= 0)) { \ - ret = a; \ - } \ - if (unlikely((imm) > 15)) { \ - ret = _mm_setzero_si128(); \ - } else { \ - ret = vreinterpretq_m128i_s8( \ - vextq_s8(vreinterpretq_s8_m128i(a), vdupq_n_s8(0), (imm))); \ - } \ - ret; \ - }) +// https://msdn.microsoft.com/en-us/library/vstudio/1beaceh8(v=vs.100).aspx +FORCE_INLINE __m128i _mm_andnot_si128(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vbicq_s32(vreinterpretq_s32_m128i(b), + vreinterpretq_s32_m128i(a))); // *NOTE* argument swap +} -// Shifts the 128-bit value in a left by imm bytes while shifting in zeros. imm -// must be an immediate. +// Computes the average of the 8 unsigned 16-bit integers in a and the 8 +// unsigned 16-bit integers in b and rounds. // -// r := a << (imm * 8) +// r0 := (a0 + b0) / 2 +// r1 := (a1 + b1) / 2 +// ... +// r7 := (a7 + b7) / 2 // -// https://msdn.microsoft.com/en-us/library/34d3k2kt(v=vs.100).aspx -// FORCE_INLINE __m128i _mm_slli_si128(__m128i a, __constrange(0,255) int imm) -#define _mm_slli_si128(a, imm) \ - __extension__({ \ - __m128i ret; \ - if (unlikely((imm) <= 0)) { \ - ret = a; \ - } \ - if (unlikely((imm) > 15)) { \ - ret = _mm_setzero_si128(); \ - } else { \ - ret = vreinterpretq_m128i_s8(vextq_s8( \ - vdupq_n_s8(0), vreinterpretq_s8_m128i(a), 16 - (imm))); \ - } \ - ret; \ - }) +// https://msdn.microsoft.com/en-us/library/vstudio/y13ca3c8(v=vs.90).aspx +FORCE_INLINE __m128i _mm_avg_epu16(__m128i a, __m128i b) +{ + return (__m128i) vrhaddq_u16(vreinterpretq_u16_m128i(a), + vreinterpretq_u16_m128i(b)); +} -// Compute the square root of packed double-precision (64-bit) floating-point -// elements in a, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sqrt_pd -FORCE_INLINE __m128d _mm_sqrt_pd(__m128d a) +// Computes the average of the 16 unsigned 8-bit integers in a and the 16 +// unsigned 8-bit integers in b and rounds. +// +// r0 := (a0 + b0) / 2 +// r1 := (a1 + b1) / 2 +// ... +// r15 := (a15 + b15) / 2 +// +// https://msdn.microsoft.com/en-us/library/vstudio/8zwh554a(v%3dvs.90).aspx +FORCE_INLINE __m128i _mm_avg_epu8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vrhaddq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); +} + +// Shift a left by imm8 bytes while shifting in zeros, and store the results in +// dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_bslli_si128 +#define _mm_bslli_si128(a, imm) _mm_slli_si128(a, imm) + +// Shift a right by imm8 bytes while shifting in zeros, and store the results in +// dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_bsrli_si128 +#define _mm_bsrli_si128(a, imm) _mm_srli_si128(a, imm) + +// Cast vector of type __m128d to type __m128. This intrinsic is only used for +// compilation and does not generate any instructions, thus it has zero latency. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castpd_ps +FORCE_INLINE __m128 _mm_castpd_ps(__m128d a) +{ + return vreinterpretq_m128_s64(vreinterpretq_s64_m128d(a)); +} + +// Cast vector of type __m128d to type __m128i. This intrinsic is only used for +// compilation and does not generate any instructions, thus it has zero latency. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castpd_si128 +FORCE_INLINE __m128i _mm_castpd_si128(__m128d a) +{ + return vreinterpretq_m128i_s64(vreinterpretq_s64_m128d(a)); +} + +// Cast vector of type __m128 to type __m128d. This intrinsic is only used for +// compilation and does not generate any instructions, thus it has zero latency. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castps_pd +FORCE_INLINE __m128d _mm_castps_pd(__m128 a) +{ + return vreinterpretq_m128d_s32(vreinterpretq_s32_m128(a)); +} + +// Applies a type cast to reinterpret four 32-bit floating point values passed +// in as a 128-bit parameter as packed 32-bit integers. +// https://msdn.microsoft.com/en-us/library/bb514099.aspx +FORCE_INLINE __m128i _mm_castps_si128(__m128 a) +{ + return vreinterpretq_m128i_s32(vreinterpretq_s32_m128(a)); +} + +// Cast vector of type __m128i to type __m128d. This intrinsic is only used for +// compilation and does not generate any instructions, thus it has zero latency. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castsi128_pd +FORCE_INLINE __m128d _mm_castsi128_pd(__m128i a) { #if defined(__aarch64__) - return vreinterpretq_m128d_f64(vsqrtq_f64(vreinterpretq_f64_m128d(a))); + return vreinterpretq_m128d_f64(vreinterpretq_f64_m128i(a)); #else - double a0 = sqrt(((double *) &a)[0]); - double a1 = sqrt(((double *) &a)[1]); + return vreinterpretq_m128d_f32(vreinterpretq_f32_m128i(a)); +#endif +} + +// Applies a type cast to reinterpret four 32-bit integers passed in as a +// 128-bit parameter as packed 32-bit floating point values. +// https://msdn.microsoft.com/en-us/library/bb514029.aspx +FORCE_INLINE __m128 _mm_castsi128_ps(__m128i a) +{ + return vreinterpretq_m128_s32(vreinterpretq_s32_m128i(a)); +} + +// Cache line containing p is flushed and invalidated from all caches in the +// coherency domain. : +// https://msdn.microsoft.com/en-us/library/ba08y07y(v=vs.100).aspx +FORCE_INLINE void _mm_clflush(void const *p) +{ + (void) p; + // no corollary for Neon? +} + +// Compares the 8 signed or unsigned 16-bit integers in a and the 8 signed or +// unsigned 16-bit integers in b for equality. +// https://msdn.microsoft.com/en-us/library/2ay060te(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmpeq_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vceqq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Compare packed 32-bit integers in a and b for equality, and store the results +// in dst +FORCE_INLINE __m128i _mm_cmpeq_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u32( + vceqq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Compares the 16 signed or unsigned 8-bit integers in a and the 16 signed or +// unsigned 8-bit integers in b for equality. +// https://msdn.microsoft.com/en-us/library/windows/desktop/bz5xk21a(v=vs.90).aspx +FORCE_INLINE __m128i _mm_cmpeq_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vceqq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Compare packed double-precision (64-bit) floating-point elements in a and b +// for equality, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpeq_pd +FORCE_INLINE __m128d _mm_cmpeq_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_u64( + vceqq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + // (a == b) -> (a_lo == b_lo) && (a_hi == b_hi) + uint32x4_t cmp = + vceqq_u32(vreinterpretq_u32_m128d(a), vreinterpretq_u32_m128d(b)); + uint32x4_t swapped = vrev64q_u32(cmp); + return vreinterpretq_m128d_u32(vandq_u32(cmp, swapped)); +#endif +} + +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b for equality, store the result in the lower element of dst, and copy the +// upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpeq_sd +FORCE_INLINE __m128d _mm_cmpeq_sd(__m128d a, __m128d b) +{ + return _mm_move_sd(a, _mm_cmpeq_pd(a, b)); +} + +// Compare packed double-precision (64-bit) floating-point elements in a and b +// for greater-than-or-equal, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpge_pd +FORCE_INLINE __m128d _mm_cmpge_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_u64( + vcgeq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = (*(double *) &a0) >= (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0); + d[1] = (*(double *) &a1) >= (*(double *) &b1) ? ~UINT64_C(0) : UINT64_C(0); + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif +} + +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b for greater-than-or-equal, store the result in the lower element of dst, +// and copy the upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpge_sd +FORCE_INLINE __m128d _mm_cmpge_sd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return _mm_move_sd(a, _mm_cmpge_pd(a, b)); +#else + // expand "_mm_cmpge_pd()" to reduce unnecessary operations + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = (*(double *) &a0) >= (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0); + d[1] = a1; + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif +} + +// Compares the 8 signed 16-bit integers in a and the 8 signed 16-bit integers +// in b for greater than. +// +// r0 := (a0 > b0) ? 0xffff : 0x0 +// r1 := (a1 > b1) ? 0xffff : 0x0 +// ... +// r7 := (a7 > b7) ? 0xffff : 0x0 +// +// https://technet.microsoft.com/en-us/library/xd43yfsa(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmpgt_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vcgtq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Compares the 4 signed 32-bit integers in a and the 4 signed 32-bit integers +// in b for greater than. +// https://msdn.microsoft.com/en-us/library/vstudio/1s9f2z0y(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmpgt_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u32( + vcgtq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Compares the 16 signed 8-bit integers in a and the 16 signed 8-bit integers +// in b for greater than. +// +// r0 := (a0 > b0) ? 0xff : 0x0 +// r1 := (a1 > b1) ? 0xff : 0x0 +// ... +// r15 := (a15 > b15) ? 0xff : 0x0 +// +// https://msdn.microsoft.com/zh-tw/library/wf45zt2b(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmpgt_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vcgtq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Compare packed double-precision (64-bit) floating-point elements in a and b +// for greater-than, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpgt_pd +FORCE_INLINE __m128d _mm_cmpgt_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_u64( + vcgtq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = (*(double *) &a0) > (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0); + d[1] = (*(double *) &a1) > (*(double *) &b1) ? ~UINT64_C(0) : UINT64_C(0); + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif +} + +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b for greater-than, store the result in the lower element of dst, and copy +// the upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpgt_sd +FORCE_INLINE __m128d _mm_cmpgt_sd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return _mm_move_sd(a, _mm_cmpgt_pd(a, b)); +#else + // expand "_mm_cmpge_pd()" to reduce unnecessary operations + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = (*(double *) &a0) > (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0); + d[1] = a1; + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif +} + +// Compare packed double-precision (64-bit) floating-point elements in a and b +// for less-than-or-equal, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmple_pd +FORCE_INLINE __m128d _mm_cmple_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_u64( + vcleq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = (*(double *) &a0) <= (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0); + d[1] = (*(double *) &a1) <= (*(double *) &b1) ? ~UINT64_C(0) : UINT64_C(0); + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif +} + +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b for less-than-or-equal, store the result in the lower element of dst, and +// copy the upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmple_sd +FORCE_INLINE __m128d _mm_cmple_sd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return _mm_move_sd(a, _mm_cmple_pd(a, b)); +#else + // expand "_mm_cmpge_pd()" to reduce unnecessary operations + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = (*(double *) &a0) <= (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0); + d[1] = a1; + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif +} + +// Compares the 8 signed 16-bit integers in a and the 8 signed 16-bit integers +// in b for less than. +// +// r0 := (a0 < b0) ? 0xffff : 0x0 +// r1 := (a1 < b1) ? 0xffff : 0x0 +// ... +// r7 := (a7 < b7) ? 0xffff : 0x0 +// +// https://technet.microsoft.com/en-us/library/t863edb2(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmplt_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vcltq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + + +// Compares the 4 signed 32-bit integers in a and the 4 signed 32-bit integers +// in b for less than. +// https://msdn.microsoft.com/en-us/library/vstudio/4ak0bf5d(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cmplt_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u32( + vcltq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Compares the 16 signed 8-bit integers in a and the 16 signed 8-bit integers +// in b for lesser than. +// https://msdn.microsoft.com/en-us/library/windows/desktop/9s46csht(v=vs.90).aspx +FORCE_INLINE __m128i _mm_cmplt_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vcltq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} + +// Compare packed double-precision (64-bit) floating-point elements in a and b +// for less-than, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmplt_pd +FORCE_INLINE __m128d _mm_cmplt_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_u64( + vcltq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = (*(double *) &a0) < (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0); + d[1] = (*(double *) &a1) < (*(double *) &b1) ? ~UINT64_C(0) : UINT64_C(0); + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif +} + +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b for less-than, store the result in the lower element of dst, and copy the +// upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmplt_sd +FORCE_INLINE __m128d _mm_cmplt_sd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return _mm_move_sd(a, _mm_cmplt_pd(a, b)); +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = (*(double *) &a0) < (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0); + d[1] = a1; + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif +} + +// Compare packed double-precision (64-bit) floating-point elements in a and b +// for not-equal, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpneq_pd +FORCE_INLINE __m128d _mm_cmpneq_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_s32(vmvnq_s32(vreinterpretq_s32_u64( + vceqq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))))); +#else + // (a == b) -> (a_lo == b_lo) && (a_hi == b_hi) + uint32x4_t cmp = + vceqq_u32(vreinterpretq_u32_m128d(a), vreinterpretq_u32_m128d(b)); + uint32x4_t swapped = vrev64q_u32(cmp); + return vreinterpretq_m128d_u32(vmvnq_u32(vandq_u32(cmp, swapped))); +#endif +} + +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b for not-equal, store the result in the lower element of dst, and copy the +// upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpneq_sd +FORCE_INLINE __m128d _mm_cmpneq_sd(__m128d a, __m128d b) +{ + return _mm_move_sd(a, _mm_cmpneq_pd(a, b)); +} + +// Compare packed double-precision (64-bit) floating-point elements in a and b +// for not-greater-than-or-equal, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpnge_pd +FORCE_INLINE __m128d _mm_cmpnge_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_u64(veorq_u64( + vcgeq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)), + vdupq_n_u64(UINT64_MAX))); +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = + !((*(double *) &a0) >= (*(double *) &b0)) ? ~UINT64_C(0) : UINT64_C(0); + d[1] = + !((*(double *) &a1) >= (*(double *) &b1)) ? ~UINT64_C(0) : UINT64_C(0); + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif +} + +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b for not-greater-than-or-equal, store the result in the lower element of +// dst, and copy the upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpnge_sd +FORCE_INLINE __m128d _mm_cmpnge_sd(__m128d a, __m128d b) +{ + return _mm_move_sd(a, _mm_cmpnge_pd(a, b)); +} + +// Compare packed double-precision (64-bit) floating-point elements in a and b +// for not-greater-than, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_cmpngt_pd +FORCE_INLINE __m128d _mm_cmpngt_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_u64(veorq_u64( + vcgtq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)), + vdupq_n_u64(UINT64_MAX))); +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = + !((*(double *) &a0) > (*(double *) &b0)) ? ~UINT64_C(0) : UINT64_C(0); + d[1] = + !((*(double *) &a1) > (*(double *) &b1)) ? ~UINT64_C(0) : UINT64_C(0); + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif +} + +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b for not-greater-than, store the result in the lower element of dst, and +// copy the upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpngt_sd +FORCE_INLINE __m128d _mm_cmpngt_sd(__m128d a, __m128d b) +{ + return _mm_move_sd(a, _mm_cmpngt_pd(a, b)); +} + +// Compare packed double-precision (64-bit) floating-point elements in a and b +// for not-less-than-or-equal, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpnle_pd +FORCE_INLINE __m128d _mm_cmpnle_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_u64(veorq_u64( + vcleq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)), + vdupq_n_u64(UINT64_MAX))); +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = + !((*(double *) &a0) <= (*(double *) &b0)) ? ~UINT64_C(0) : UINT64_C(0); + d[1] = + !((*(double *) &a1) <= (*(double *) &b1)) ? ~UINT64_C(0) : UINT64_C(0); + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif +} + +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b for not-less-than-or-equal, store the result in the lower element of dst, +// and copy the upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpnle_sd +FORCE_INLINE __m128d _mm_cmpnle_sd(__m128d a, __m128d b) +{ + return _mm_move_sd(a, _mm_cmpnle_pd(a, b)); +} + +// Compare packed double-precision (64-bit) floating-point elements in a and b +// for not-less-than, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpnlt_pd +FORCE_INLINE __m128d _mm_cmpnlt_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_u64(veorq_u64( + vcltq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)), + vdupq_n_u64(UINT64_MAX))); +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = + !((*(double *) &a0) < (*(double *) &b0)) ? ~UINT64_C(0) : UINT64_C(0); + d[1] = + !((*(double *) &a1) < (*(double *) &b1)) ? ~UINT64_C(0) : UINT64_C(0); + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif +} + +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b for not-less-than, store the result in the lower element of dst, and copy +// the upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpnlt_sd +FORCE_INLINE __m128d _mm_cmpnlt_sd(__m128d a, __m128d b) +{ + return _mm_move_sd(a, _mm_cmpnlt_pd(a, b)); +} + +// Compare packed double-precision (64-bit) floating-point elements in a and b +// to see if neither is NaN, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpord_pd +FORCE_INLINE __m128d _mm_cmpord_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + // Excluding NaNs, any two floating point numbers can be compared. + uint64x2_t not_nan_a = + vceqq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(a)); + uint64x2_t not_nan_b = + vceqq_f64(vreinterpretq_f64_m128d(b), vreinterpretq_f64_m128d(b)); + return vreinterpretq_m128d_u64(vandq_u64(not_nan_a, not_nan_b)); +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = ((*(double *) &a0) == (*(double *) &a0) && + (*(double *) &b0) == (*(double *) &b0)) + ? ~UINT64_C(0) + : UINT64_C(0); + d[1] = ((*(double *) &a1) == (*(double *) &a1) && + (*(double *) &b1) == (*(double *) &b1)) + ? ~UINT64_C(0) + : UINT64_C(0); + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif +} + +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b to see if neither is NaN, store the result in the lower element of dst, and +// copy the upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpord_sd +FORCE_INLINE __m128d _mm_cmpord_sd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return _mm_move_sd(a, _mm_cmpord_pd(a, b)); +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t d[2]; + d[0] = ((*(double *) &a0) == (*(double *) &a0) && + (*(double *) &b0) == (*(double *) &b0)) + ? ~UINT64_C(0) + : UINT64_C(0); + d[1] = a1; + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif +} + +// Compare packed double-precision (64-bit) floating-point elements in a and b +// to see if either is NaN, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpunord_pd +FORCE_INLINE __m128d _mm_cmpunord_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + // Two NaNs are not equal in comparison operation. + uint64x2_t not_nan_a = + vceqq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(a)); + uint64x2_t not_nan_b = + vceqq_f64(vreinterpretq_f64_m128d(b), vreinterpretq_f64_m128d(b)); + return vreinterpretq_m128d_s32( + vmvnq_s32(vreinterpretq_s32_u64(vandq_u64(not_nan_a, not_nan_b)))); +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = ((*(double *) &a0) == (*(double *) &a0) && + (*(double *) &b0) == (*(double *) &b0)) + ? UINT64_C(0) + : ~UINT64_C(0); + d[1] = ((*(double *) &a1) == (*(double *) &a1) && + (*(double *) &b1) == (*(double *) &b1)) + ? UINT64_C(0) + : ~UINT64_C(0); + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif +} + +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b to see if either is NaN, store the result in the lower element of dst, and +// copy the upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpunord_sd +FORCE_INLINE __m128d _mm_cmpunord_sd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return _mm_move_sd(a, _mm_cmpunord_pd(a, b)); +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t d[2]; + d[0] = ((*(double *) &a0) == (*(double *) &a0) && + (*(double *) &b0) == (*(double *) &b0)) + ? UINT64_C(0) + : ~UINT64_C(0); + d[1] = a1; + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif +} + +// Compare the lower double-precision (64-bit) floating-point element in a and b +// for greater-than-or-equal, and return the boolean result (0 or 1). +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comige_sd +FORCE_INLINE int _mm_comige_sd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vgetq_lane_u64(vcgeq_f64(a, b), 0) & 0x1; +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + + return (*(double *) &a0 >= *(double *) &b0); +#endif +} + +// Compare the lower double-precision (64-bit) floating-point element in a and b +// for greater-than, and return the boolean result (0 or 1). +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comigt_sd +FORCE_INLINE int _mm_comigt_sd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vgetq_lane_u64(vcgtq_f64(a, b), 0) & 0x1; +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + + return (*(double *) &a0 > *(double *) &b0); +#endif +} + +// Compare the lower double-precision (64-bit) floating-point element in a and b +// for less-than-or-equal, and return the boolean result (0 or 1). +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comile_sd +FORCE_INLINE int _mm_comile_sd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vgetq_lane_u64(vcleq_f64(a, b), 0) & 0x1; +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + + return (*(double *) &a0 <= *(double *) &b0); +#endif +} + +// Compare the lower double-precision (64-bit) floating-point element in a and b +// for less-than, and return the boolean result (0 or 1). +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comilt_sd +FORCE_INLINE int _mm_comilt_sd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vgetq_lane_u64(vcltq_f64(a, b), 0) & 0x1; +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + + return (*(double *) &a0 < *(double *) &b0); +#endif +} + +// Compare the lower double-precision (64-bit) floating-point element in a and b +// for equality, and return the boolean result (0 or 1). +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comieq_sd +FORCE_INLINE int _mm_comieq_sd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vgetq_lane_u64(vceqq_f64(a, b), 0) & 0x1; +#else + uint32x4_t a_not_nan = + vceqq_u32(vreinterpretq_u32_m128d(a), vreinterpretq_u32_m128d(a)); + uint32x4_t b_not_nan = + vceqq_u32(vreinterpretq_u32_m128d(b), vreinterpretq_u32_m128d(b)); + uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); + uint32x4_t a_eq_b = + vceqq_u32(vreinterpretq_u32_m128d(a), vreinterpretq_u32_m128d(b)); + uint64x2_t and_results = vandq_u64(vreinterpretq_u64_u32(a_and_b_not_nan), + vreinterpretq_u64_u32(a_eq_b)); + return vgetq_lane_u64(and_results, 0) & 0x1; +#endif +} + +// Compare the lower double-precision (64-bit) floating-point element in a and b +// for not-equal, and return the boolean result (0 or 1). +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comineq_sd +FORCE_INLINE int _mm_comineq_sd(__m128d a, __m128d b) +{ + return !_mm_comieq_sd(a, b); +} + +// Convert packed signed 32-bit integers in a to packed double-precision +// (64-bit) floating-point elements, and store the results in dst. +// +// FOR j := 0 to 1 +// i := j*32 +// m := j*64 +// dst[m+63:m] := Convert_Int32_To_FP64(a[i+31:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtepi32_pd +FORCE_INLINE __m128d _mm_cvtepi32_pd(__m128i a) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vcvtq_f64_s64(vmovl_s32(vget_low_s32(vreinterpretq_s32_m128i(a))))); +#else + double a0 = (double) vgetq_lane_s32(vreinterpretq_s32_m128i(a), 0); + double a1 = (double) vgetq_lane_s32(vreinterpretq_s32_m128i(a), 1); return _mm_set_pd(a1, a0); #endif } -// Compute the square root of the lower double-precision (64-bit) floating-point -// element in b, store the result in the lower element of dst, and copy the -// upper element from a to the upper element of dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sqrt_sd -FORCE_INLINE __m128d _mm_sqrt_sd(__m128d a, __m128d b) +// Converts the four signed 32-bit integer values of a to single-precision, +// floating-point values +// https://msdn.microsoft.com/en-us/library/vstudio/36bwxcx5(v=vs.100).aspx +FORCE_INLINE __m128 _mm_cvtepi32_ps(__m128i a) +{ + return vreinterpretq_m128_f32(vcvtq_f32_s32(vreinterpretq_s32_m128i(a))); +} + +// Convert packed double-precision (64-bit) floating-point elements in a to +// packed 32-bit integers, and store the results in dst. +// +// FOR j := 0 to 1 +// i := 32*j +// k := 64*j +// dst[i+31:i] := Convert_FP64_To_Int32(a[k+63:k]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpd_epi32 +FORCE_INLINE __m128i _mm_cvtpd_epi32(__m128d a) +{ + __m128d rnd = _mm_round_pd(a, _MM_FROUND_CUR_DIRECTION); + double d0 = ((double *) &rnd)[0]; + double d1 = ((double *) &rnd)[1]; + return _mm_set_epi32(0, 0, (int32_t) d1, (int32_t) d0); +} + +// Convert packed double-precision (64-bit) floating-point elements in a to +// packed 32-bit integers, and store the results in dst. +// +// FOR j := 0 to 1 +// i := 32*j +// k := 64*j +// dst[i+31:i] := Convert_FP64_To_Int32(a[k+63:k]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpd_pi32 +FORCE_INLINE __m64 _mm_cvtpd_pi32(__m128d a) +{ + __m128d rnd = _mm_round_pd(a, _MM_FROUND_CUR_DIRECTION); + double d0 = ((double *) &rnd)[0]; + double d1 = ((double *) &rnd)[1]; + int32_t ALIGN_STRUCT(16) data[2] = {(int32_t) d0, (int32_t) d1}; + return vreinterpret_m64_s32(vld1_s32(data)); +} + +// Convert packed double-precision (64-bit) floating-point elements in a to +// packed single-precision (32-bit) floating-point elements, and store the +// results in dst. +// +// FOR j := 0 to 1 +// i := 32*j +// k := 64*j +// dst[i+31:i] := Convert_FP64_To_FP32(a[k+64:k]) +// ENDFOR +// dst[127:64] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpd_ps +FORCE_INLINE __m128 _mm_cvtpd_ps(__m128d a) { #if defined(__aarch64__) - return _mm_move_sd(a, _mm_sqrt_pd(b)); + float32x2_t tmp = vcvt_f32_f64(vreinterpretq_f64_m128d(a)); + return vreinterpretq_m128_f32(vcombine_f32(tmp, vdup_n_f32(0))); #else - return _mm_set_pd(((double *) &a)[1], sqrt(((double *) &b)[0])); + float a0 = (float) ((double *) &a)[0]; + float a1 = (float) ((double *) &a)[1]; + return _mm_set_ps(0, 0, a1, a0); #endif } -// Shifts the 8 signed or unsigned 16-bit integers in a left by count bits while -// shifting in zeros. +// Convert packed signed 32-bit integers in a to packed double-precision +// (64-bit) floating-point elements, and store the results in dst. // -// r0 := a0 << count -// r1 := a1 << count -// ... -// r7 := a7 << count +// FOR j := 0 to 1 +// i := j*32 +// m := j*64 +// dst[m+63:m] := Convert_Int32_To_FP64(a[i+31:i]) +// ENDFOR // -// https://msdn.microsoft.com/en-us/library/c79w388h(v%3dvs.90).aspx -FORCE_INLINE __m128i _mm_sll_epi16(__m128i a, __m128i count) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi32_pd +FORCE_INLINE __m128d _mm_cvtpi32_pd(__m64 a) { - uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); - if (unlikely(c > 15)) - return _mm_setzero_si128(); - - int16x8_t vc = vdupq_n_s16((int16_t) c); - return vreinterpretq_m128i_s16(vshlq_s16(vreinterpretq_s16_m128i(a), vc)); +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vcvtq_f64_s64(vmovl_s32(vreinterpret_s32_m64(a)))); +#else + double a0 = (double) vget_lane_s32(vreinterpret_s32_m64(a), 0); + double a1 = (double) vget_lane_s32(vreinterpret_s32_m64(a), 1); + return _mm_set_pd(a1, a0); +#endif } -// Shifts the 4 signed or unsigned 32-bit integers in a left by count bits while -// shifting in zeros. +// Converts the four single-precision, floating-point values of a to signed +// 32-bit integer values. // -// r0 := a0 << count -// r1 := a1 << count -// r2 := a2 << count -// r3 := a3 << count +// r0 := (int) a0 +// r1 := (int) a1 +// r2 := (int) a2 +// r3 := (int) a3 // -// https://msdn.microsoft.com/en-us/library/6fe5a6s9(v%3dvs.90).aspx -FORCE_INLINE __m128i _mm_sll_epi32(__m128i a, __m128i count) +// https://msdn.microsoft.com/en-us/library/vstudio/xdc42k5e(v=vs.100).aspx +// *NOTE*. The default rounding mode on SSE is 'round to even', which ARMv7-A +// does not support! It is supported on ARMv8-A however. +FORCE_INLINE __m128i _mm_cvtps_epi32(__m128 a) { - uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); - if (unlikely(c > 31)) - return _mm_setzero_si128(); - - int32x4_t vc = vdupq_n_s32((int32_t) c); - return vreinterpretq_m128i_s32(vshlq_s32(vreinterpretq_s32_m128i(a), vc)); +#if defined(__aarch64__) || defined(__ARM_FEATURE_DIRECTED_ROUNDING) + switch (_MM_GET_ROUNDING_MODE()) { + case _MM_ROUND_NEAREST: + return vreinterpretq_m128i_s32(vcvtnq_s32_f32(a)); + case _MM_ROUND_DOWN: + return vreinterpretq_m128i_s32(vcvtmq_s32_f32(a)); + case _MM_ROUND_UP: + return vreinterpretq_m128i_s32(vcvtpq_s32_f32(a)); + default: // _MM_ROUND_TOWARD_ZERO + return vreinterpretq_m128i_s32(vcvtq_s32_f32(a)); + } +#else + float *f = (float *) &a; + switch (_MM_GET_ROUNDING_MODE()) { + case _MM_ROUND_NEAREST: { + uint32x4_t signmask = vdupq_n_u32(0x80000000); + float32x4_t half = vbslq_f32(signmask, vreinterpretq_f32_m128(a), + vdupq_n_f32(0.5f)); /* +/- 0.5 */ + int32x4_t r_normal = vcvtq_s32_f32(vaddq_f32( + vreinterpretq_f32_m128(a), half)); /* round to integer: [a + 0.5]*/ + int32x4_t r_trunc = vcvtq_s32_f32( + vreinterpretq_f32_m128(a)); /* truncate to integer: [a] */ + int32x4_t plusone = vreinterpretq_s32_u32(vshrq_n_u32( + vreinterpretq_u32_s32(vnegq_s32(r_trunc)), 31)); /* 1 or 0 */ + int32x4_t r_even = vbicq_s32(vaddq_s32(r_trunc, plusone), + vdupq_n_s32(1)); /* ([a] + {0,1}) & ~1 */ + float32x4_t delta = vsubq_f32( + vreinterpretq_f32_m128(a), + vcvtq_f32_s32(r_trunc)); /* compute delta: delta = (a - [a]) */ + uint32x4_t is_delta_half = + vceqq_f32(delta, half); /* delta == +/- 0.5 */ + return vreinterpretq_m128i_s32( + vbslq_s32(is_delta_half, r_even, r_normal)); + } + case _MM_ROUND_DOWN: + return _mm_set_epi32(floorf(f[3]), floorf(f[2]), floorf(f[1]), + floorf(f[0])); + case _MM_ROUND_UP: + return _mm_set_epi32(ceilf(f[3]), ceilf(f[2]), ceilf(f[1]), + ceilf(f[0])); + default: // _MM_ROUND_TOWARD_ZERO + return _mm_set_epi32((int32_t) f[3], (int32_t) f[2], (int32_t) f[1], + (int32_t) f[0]); + } +#endif } -// Shifts the 2 signed or unsigned 64-bit integers in a left by count bits while -// shifting in zeros. +// Convert packed single-precision (32-bit) floating-point elements in a to +// packed double-precision (64-bit) floating-point elements, and store the +// results in dst. // -// r0 := a0 << count -// r1 := a1 << count +// FOR j := 0 to 1 +// i := 64*j +// k := 32*j +// dst[i+63:i] := Convert_FP32_To_FP64(a[k+31:k]) +// ENDFOR // -// https://msdn.microsoft.com/en-us/library/6ta9dffd(v%3dvs.90).aspx -FORCE_INLINE __m128i _mm_sll_epi64(__m128i a, __m128i count) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtps_pd +FORCE_INLINE __m128d _mm_cvtps_pd(__m128 a) { - uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); - if (unlikely(c > 63)) - return _mm_setzero_si128(); - - int64x2_t vc = vdupq_n_s64((int64_t) c); - return vreinterpretq_m128i_s64(vshlq_s64(vreinterpretq_s64_m128i(a), vc)); +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vcvt_f64_f32(vget_low_f32(vreinterpretq_f32_m128(a)))); +#else + double a0 = (double) vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); + double a1 = (double) vgetq_lane_f32(vreinterpretq_f32_m128(a), 1); + return _mm_set_pd(a1, a0); +#endif } -// Shifts the 8 signed or unsigned 16-bit integers in a right by count bits -// while shifting in zeros. +// Copy the lower double-precision (64-bit) floating-point element of a to dst. // -// r0 := srl(a0, count) -// r1 := srl(a1, count) -// ... -// r7 := srl(a7, count) +// dst[63:0] := a[63:0] // -// https://msdn.microsoft.com/en-us/library/wd5ax830(v%3dvs.90).aspx -FORCE_INLINE __m128i _mm_srl_epi16(__m128i a, __m128i count) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsd_f64 +FORCE_INLINE double _mm_cvtsd_f64(__m128d a) { - uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); - if (unlikely(c > 15)) - return _mm_setzero_si128(); - - int16x8_t vc = vdupq_n_s16(-(int16_t) c); - return vreinterpretq_m128i_u16(vshlq_u16(vreinterpretq_u16_m128i(a), vc)); +#if defined(__aarch64__) + return (double) vgetq_lane_f64(vreinterpretq_f64_m128d(a), 0); +#else + return ((double *) &a)[0]; +#endif } -// Shifts the 4 signed or unsigned 32-bit integers in a right by count bits -// while shifting in zeros. +// Convert the lower double-precision (64-bit) floating-point element in a to a +// 32-bit integer, and store the result in dst. // -// r0 := srl(a0, count) -// r1 := srl(a1, count) -// r2 := srl(a2, count) -// r3 := srl(a3, count) +// dst[31:0] := Convert_FP64_To_Int32(a[63:0]) // -// https://msdn.microsoft.com/en-us/library/a9cbttf4(v%3dvs.90).aspx -FORCE_INLINE __m128i _mm_srl_epi32(__m128i a, __m128i count) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsd_si32 +FORCE_INLINE int32_t _mm_cvtsd_si32(__m128d a) { - uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); - if (unlikely(c > 31)) - return _mm_setzero_si128(); - - int32x4_t vc = vdupq_n_s32(-(int32_t) c); - return vreinterpretq_m128i_u32(vshlq_u32(vreinterpretq_u32_m128i(a), vc)); +#if defined(__aarch64__) + return (int32_t) vgetq_lane_f64(vrndiq_f64(vreinterpretq_f64_m128d(a)), 0); +#else + __m128d rnd = _mm_round_pd(a, _MM_FROUND_CUR_DIRECTION); + double ret = ((double *) &rnd)[0]; + return (int32_t) ret; +#endif } -// Shifts the 2 signed or unsigned 64-bit integers in a right by count bits -// while shifting in zeros. +// Convert the lower double-precision (64-bit) floating-point element in a to a +// 64-bit integer, and store the result in dst. // -// r0 := srl(a0, count) -// r1 := srl(a1, count) +// dst[63:0] := Convert_FP64_To_Int64(a[63:0]) // -// https://msdn.microsoft.com/en-us/library/yf6cf9k8(v%3dvs.90).aspx -FORCE_INLINE __m128i _mm_srl_epi64(__m128i a, __m128i count) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsd_si64 +FORCE_INLINE int64_t _mm_cvtsd_si64(__m128d a) { - uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); - if (unlikely(c > 63)) - return _mm_setzero_si128(); +#if defined(__aarch64__) + return (int64_t) vgetq_lane_f64(vrndiq_f64(vreinterpretq_f64_m128d(a)), 0); +#else + __m128d rnd = _mm_round_pd(a, _MM_FROUND_CUR_DIRECTION); + double ret = ((double *) &rnd)[0]; + return (int64_t) ret; +#endif +} - int64x2_t vc = vdupq_n_s64(-(int64_t) c); - return vreinterpretq_m128i_u64(vshlq_u64(vreinterpretq_u64_m128i(a), vc)); +// Convert the lower double-precision (64-bit) floating-point element in a to a +// 64-bit integer, and store the result in dst. +// +// dst[63:0] := Convert_FP64_To_Int64(a[63:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsd_si64x +#define _mm_cvtsd_si64x _mm_cvtsd_si64 + +// Convert the lower double-precision (64-bit) floating-point element in b to a +// single-precision (32-bit) floating-point element, store the result in the +// lower element of dst, and copy the upper 3 packed elements from a to the +// upper elements of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsd_ss +FORCE_INLINE __m128 _mm_cvtsd_ss(__m128 a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128_f32(vsetq_lane_f32( + vget_lane_f32(vcvt_f32_f64(vreinterpretq_f64_m128d(b)), 0), + vreinterpretq_f32_m128(a), 0)); +#else + return vreinterpretq_m128_f32(vsetq_lane_f32((float) ((double *) &b)[0], + vreinterpretq_f32_m128(a), 0)); +#endif +} + +// Copy the lower 32-bit integer in a to dst. +// +// dst[31:0] := a[31:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si32 +FORCE_INLINE int _mm_cvtsi128_si32(__m128i a) +{ + return vgetq_lane_s32(vreinterpretq_s32_m128i(a), 0); +} + +// Copy the lower 64-bit integer in a to dst. +// +// dst[63:0] := a[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si64 +FORCE_INLINE int64_t _mm_cvtsi128_si64(__m128i a) +{ + return vgetq_lane_s64(vreinterpretq_s64_m128i(a), 0); +} + +// Copy the lower 64-bit integer in a to dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si64x +#define _mm_cvtsi128_si64x(a) _mm_cvtsi128_si64(a) + +// Convert the signed 32-bit integer b to a double-precision (64-bit) +// floating-point element, store the result in the lower element of dst, and +// copy the upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi32_sd +FORCE_INLINE __m128d _mm_cvtsi32_sd(__m128d a, int32_t b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vsetq_lane_f64((double) b, vreinterpretq_f64_m128d(a), 0)); +#else + double bf = (double) b; + return vreinterpretq_m128d_s64( + vsetq_lane_s64(*(int64_t *) &bf, vreinterpretq_s64_m128d(a), 0)); +#endif +} + +// Copy the lower 64-bit integer in a to dst. +// +// dst[63:0] := a[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si64x +#define _mm_cvtsi128_si64x(a) _mm_cvtsi128_si64(a) + +// Moves 32-bit integer a to the least significant 32 bits of an __m128 object, +// zero extending the upper bits. +// +// r0 := a +// r1 := 0x0 +// r2 := 0x0 +// r3 := 0x0 +// +// https://msdn.microsoft.com/en-us/library/ct3539ha%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_cvtsi32_si128(int a) +{ + return vreinterpretq_m128i_s32(vsetq_lane_s32(a, vdupq_n_s32(0), 0)); +} + +// Convert the signed 64-bit integer b to a double-precision (64-bit) +// floating-point element, store the result in the lower element of dst, and +// copy the upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi64_sd +FORCE_INLINE __m128d _mm_cvtsi64_sd(__m128d a, int64_t b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vsetq_lane_f64((double) b, vreinterpretq_f64_m128d(a), 0)); +#else + double bf = (double) b; + return vreinterpretq_m128d_s64( + vsetq_lane_s64(*(int64_t *) &bf, vreinterpretq_s64_m128d(a), 0)); +#endif +} + +// Moves 64-bit integer a to the least significant 64 bits of an __m128 object, +// zero extending the upper bits. +// +// r0 := a +// r1 := 0x0 +FORCE_INLINE __m128i _mm_cvtsi64_si128(int64_t a) +{ + return vreinterpretq_m128i_s64(vsetq_lane_s64(a, vdupq_n_s64(0), 0)); +} + +// Copy 64-bit integer a to the lower element of dst, and zero the upper +// element. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi64x_si128 +#define _mm_cvtsi64x_si128(a) _mm_cvtsi64_si128(a) + +// Convert the signed 64-bit integer b to a double-precision (64-bit) +// floating-point element, store the result in the lower element of dst, and +// copy the upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi64x_sd +#define _mm_cvtsi64x_sd(a, b) _mm_cvtsi64_sd(a, b) + +// Convert the lower single-precision (32-bit) floating-point element in b to a +// double-precision (64-bit) floating-point element, store the result in the +// lower element of dst, and copy the upper element from a to the upper element +// of dst. +// +// dst[63:0] := Convert_FP32_To_FP64(b[31:0]) +// dst[127:64] := a[127:64] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtss_sd +FORCE_INLINE __m128d _mm_cvtss_sd(__m128d a, __m128 b) +{ + double d = (double) vgetq_lane_f32(vreinterpretq_f32_m128(b), 0); +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vsetq_lane_f64(d, vreinterpretq_f64_m128d(a), 0)); +#else + return vreinterpretq_m128d_s64( + vsetq_lane_s64(*(int64_t *) &d, vreinterpretq_s64_m128d(a), 0)); +#endif +} + +// Convert packed double-precision (64-bit) floating-point elements in a to +// packed 32-bit integers with truncation, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttpd_epi32 +FORCE_INLINE __m128i _mm_cvttpd_epi32(__m128d a) +{ + double a0 = ((double *) &a)[0]; + double a1 = ((double *) &a)[1]; + return _mm_set_epi32(0, 0, (int32_t) a1, (int32_t) a0); +} + +// Convert packed double-precision (64-bit) floating-point elements in a to +// packed 32-bit integers with truncation, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttpd_pi32 +FORCE_INLINE __m64 _mm_cvttpd_pi32(__m128d a) +{ + double a0 = ((double *) &a)[0]; + double a1 = ((double *) &a)[1]; + int32_t ALIGN_STRUCT(16) data[2] = {(int32_t) a0, (int32_t) a1}; + return vreinterpret_m64_s32(vld1_s32(data)); +} + +// Converts the four single-precision, floating-point values of a to signed +// 32-bit integer values using truncate. +// https://msdn.microsoft.com/en-us/library/vstudio/1h005y6x(v=vs.100).aspx +FORCE_INLINE __m128i _mm_cvttps_epi32(__m128 a) +{ + return vreinterpretq_m128i_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a))); +} + +// Convert the lower double-precision (64-bit) floating-point element in a to a +// 32-bit integer with truncation, and store the result in dst. +// +// dst[63:0] := Convert_FP64_To_Int32_Truncate(a[63:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttsd_si32 +FORCE_INLINE int32_t _mm_cvttsd_si32(__m128d a) +{ + double ret = *((double *) &a); + return (int32_t) ret; +} + +// Convert the lower double-precision (64-bit) floating-point element in a to a +// 64-bit integer with truncation, and store the result in dst. +// +// dst[63:0] := Convert_FP64_To_Int64_Truncate(a[63:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttsd_si64 +FORCE_INLINE int64_t _mm_cvttsd_si64(__m128d a) +{ +#if defined(__aarch64__) + return vgetq_lane_s64(vcvtq_s64_f64(vreinterpretq_f64_m128d(a)), 0); +#else + double ret = *((double *) &a); + return (int64_t) ret; +#endif +} + +// Convert the lower double-precision (64-bit) floating-point element in a to a +// 64-bit integer with truncation, and store the result in dst. +// +// dst[63:0] := Convert_FP64_To_Int64_Truncate(a[63:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttsd_si64x +#define _mm_cvttsd_si64x(a) _mm_cvttsd_si64(a) + +// Divide packed double-precision (64-bit) floating-point elements in a by +// packed elements in b, and store the results in dst. +// +// FOR j := 0 to 1 +// i := 64*j +// dst[i+63:i] := a[i+63:i] / b[i+63:i] +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_div_pd +FORCE_INLINE __m128d _mm_div_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vdivq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + double *da = (double *) &a; + double *db = (double *) &b; + double c[2]; + c[0] = da[0] / db[0]; + c[1] = da[1] / db[1]; + return vld1q_f32((float32_t *) c); +#endif +} + +// Divide the lower double-precision (64-bit) floating-point element in a by the +// lower double-precision (64-bit) floating-point element in b, store the result +// in the lower element of dst, and copy the upper element from a to the upper +// element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_div_sd +FORCE_INLINE __m128d _mm_div_sd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + float64x2_t tmp = + vdivq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)); + return vreinterpretq_m128d_f64( + vsetq_lane_f64(vgetq_lane_f64(vreinterpretq_f64_m128d(a), 1), tmp, 1)); +#else + return _mm_move_sd(a, _mm_div_pd(a, b)); +#endif +} + +// Extracts the selected signed or unsigned 16-bit integer from a and zero +// extends. +// https://msdn.microsoft.com/en-us/library/6dceta0c(v=vs.100).aspx +// FORCE_INLINE int _mm_extract_epi16(__m128i a, __constrange(0,8) int imm) +#define _mm_extract_epi16(a, imm) \ + vgetq_lane_u16(vreinterpretq_u16_m128i(a), (imm)) + +// Inserts the least significant 16 bits of b into the selected 16-bit integer +// of a. +// https://msdn.microsoft.com/en-us/library/kaze8hz1%28v=vs.100%29.aspx +// FORCE_INLINE __m128i _mm_insert_epi16(__m128i a, int b, +// __constrange(0,8) int imm) +#define _mm_insert_epi16(a, b, imm) \ + __extension__({ \ + vreinterpretq_m128i_s16( \ + vsetq_lane_s16((b), vreinterpretq_s16_m128i(a), (imm))); \ + }) + +// Loads two double-precision from 16-byte aligned memory, floating-point +// values. +// +// dst[127:0] := MEM[mem_addr+127:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_pd +FORCE_INLINE __m128d _mm_load_pd(const double *p) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vld1q_f64(p)); +#else + const float *fp = (const float *) p; + float ALIGN_STRUCT(16) data[4] = {fp[0], fp[1], fp[2], fp[3]}; + return vreinterpretq_m128d_f32(vld1q_f32(data)); +#endif +} + +// Load a double-precision (64-bit) floating-point element from memory into both +// elements of dst. +// +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[127:64] := MEM[mem_addr+63:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_pd1 +#define _mm_load_pd1 _mm_load1_pd + +// Load a double-precision (64-bit) floating-point element from memory into the +// lower of dst, and zero the upper element. mem_addr does not need to be +// aligned on any particular boundary. +// +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[127:64] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_sd +FORCE_INLINE __m128d _mm_load_sd(const double *p) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vsetq_lane_f64(*p, vdupq_n_f64(0), 0)); +#else + const float *fp = (const float *) p; + float ALIGN_STRUCT(16) data[4] = {fp[0], fp[1], 0, 0}; + return vreinterpretq_m128d_f32(vld1q_f32(data)); +#endif +} + +// Loads 128-bit value. : +// https://msdn.microsoft.com/en-us/library/atzzad1h(v=vs.80).aspx +FORCE_INLINE __m128i _mm_load_si128(const __m128i *p) +{ + return vreinterpretq_m128i_s32(vld1q_s32((const int32_t *) p)); +} + +// Load a double-precision (64-bit) floating-point element from memory into both +// elements of dst. +// +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[127:64] := MEM[mem_addr+63:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load1_pd +FORCE_INLINE __m128d _mm_load1_pd(const double *p) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vld1q_dup_f64(p)); +#else + return vreinterpretq_m128d_s64(vdupq_n_s64(*(const int64_t *) p)); +#endif +} + +// Load a double-precision (64-bit) floating-point element from memory into the +// upper element of dst, and copy the lower element from a to dst. mem_addr does +// not need to be aligned on any particular boundary. +// +// dst[63:0] := a[63:0] +// dst[127:64] := MEM[mem_addr+63:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadh_pd +FORCE_INLINE __m128d _mm_loadh_pd(__m128d a, const double *p) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vcombine_f64(vget_low_f64(vreinterpretq_f64_m128d(a)), vld1_f64(p))); +#else + return vreinterpretq_m128d_f32(vcombine_f32( + vget_low_f32(vreinterpretq_f32_m128d(a)), vld1_f32((const float *) p))); +#endif +} + +// Load 64-bit integer from memory into the first element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadl_epi64 +FORCE_INLINE __m128i _mm_loadl_epi64(__m128i const *p) +{ + /* Load the lower 64 bits of the value pointed to by p into the + * lower 64 bits of the result, zeroing the upper 64 bits of the result. + */ + return vreinterpretq_m128i_s32( + vcombine_s32(vld1_s32((int32_t const *) p), vcreate_s32(0))); +} + +// Load a double-precision (64-bit) floating-point element from memory into the +// lower element of dst, and copy the upper element from a to dst. mem_addr does +// not need to be aligned on any particular boundary. +// +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[127:64] := a[127:64] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadl_pd +FORCE_INLINE __m128d _mm_loadl_pd(__m128d a, const double *p) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vcombine_f64(vld1_f64(p), vget_high_f64(vreinterpretq_f64_m128d(a)))); +#else + return vreinterpretq_m128d_f32( + vcombine_f32(vld1_f32((const float *) p), + vget_high_f32(vreinterpretq_f32_m128d(a)))); +#endif +} + +// Load 2 double-precision (64-bit) floating-point elements from memory into dst +// in reverse order. mem_addr must be aligned on a 16-byte boundary or a +// general-protection exception may be generated. +// +// dst[63:0] := MEM[mem_addr+127:mem_addr+64] +// dst[127:64] := MEM[mem_addr+63:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadr_pd +FORCE_INLINE __m128d _mm_loadr_pd(const double *p) +{ +#if defined(__aarch64__) + float64x2_t v = vld1q_f64(p); + return vreinterpretq_m128d_f64(vextq_f64(v, v, 1)); +#else + int64x2_t v = vld1q_s64((const int64_t *) p); + return vreinterpretq_m128d_s64(vextq_s64(v, v, 1)); +#endif +} + +// Loads two double-precision from unaligned memory, floating-point values. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_pd +FORCE_INLINE __m128d _mm_loadu_pd(const double *p) +{ + return _mm_load_pd(p); +} + +// Loads 128-bit value. : +// https://msdn.microsoft.com/zh-cn/library/f4k12ae8(v=vs.90).aspx +FORCE_INLINE __m128i _mm_loadu_si128(const __m128i *p) +{ + return vreinterpretq_m128i_s32(vld1q_s32((const int32_t *) p)); +} + +// Load unaligned 32-bit integer from memory into the first element of dst. +// +// dst[31:0] := MEM[mem_addr+31:mem_addr] +// dst[MAX:32] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_si32 +FORCE_INLINE __m128i _mm_loadu_si32(const void *p) +{ + return vreinterpretq_m128i_s32( + vsetq_lane_s32(*(const int32_t *) p, vdupq_n_s32(0), 0)); +} + +// Multiplies the 8 signed 16-bit integers from a by the 8 signed 16-bit +// integers from b. +// +// r0 := (a0 * b0) + (a1 * b1) +// r1 := (a2 * b2) + (a3 * b3) +// r2 := (a4 * b4) + (a5 * b5) +// r3 := (a6 * b6) + (a7 * b7) +// https://msdn.microsoft.com/en-us/library/yht36sa6(v=vs.90).aspx +FORCE_INLINE __m128i _mm_madd_epi16(__m128i a, __m128i b) +{ + int32x4_t low = vmull_s16(vget_low_s16(vreinterpretq_s16_m128i(a)), + vget_low_s16(vreinterpretq_s16_m128i(b))); + int32x4_t high = vmull_s16(vget_high_s16(vreinterpretq_s16_m128i(a)), + vget_high_s16(vreinterpretq_s16_m128i(b))); + + int32x2_t low_sum = vpadd_s32(vget_low_s32(low), vget_high_s32(low)); + int32x2_t high_sum = vpadd_s32(vget_low_s32(high), vget_high_s32(high)); + + return vreinterpretq_m128i_s32(vcombine_s32(low_sum, high_sum)); +} + +// Conditionally store 8-bit integer elements from a into memory using mask +// (elements are not stored when the highest bit is not set in the corresponding +// element) and a non-temporal memory hint. mem_addr does not need to be aligned +// on any particular boundary. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_maskmoveu_si128 +FORCE_INLINE void _mm_maskmoveu_si128(__m128i a, __m128i mask, char *mem_addr) +{ + int8x16_t shr_mask = vshrq_n_s8(vreinterpretq_s8_m128i(mask), 7); + __m128 b = _mm_load_ps((const float *) mem_addr); + int8x16_t masked = + vbslq_s8(vreinterpretq_u8_s8(shr_mask), vreinterpretq_s8_m128i(a), + vreinterpretq_s8_m128(b)); + vst1q_s8((int8_t *) mem_addr, masked); +} + +// Computes the pairwise maxima of the 8 signed 16-bit integers from a and the 8 +// signed 16-bit integers from b. +// https://msdn.microsoft.com/en-us/LIBRary/3x060h7c(v=vs.100).aspx +FORCE_INLINE __m128i _mm_max_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vmaxq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Computes the pairwise maxima of the 16 unsigned 8-bit integers from a and the +// 16 unsigned 8-bit integers from b. +// https://msdn.microsoft.com/en-us/library/st6634za(v=vs.100).aspx +FORCE_INLINE __m128i _mm_max_epu8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vmaxq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); +} + +// Compare packed double-precision (64-bit) floating-point elements in a and b, +// and store packed maximum values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pd +FORCE_INLINE __m128d _mm_max_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) +#if SSE2NEON_PRECISE_MINMAX + float64x2_t _a = vreinterpretq_f64_m128d(a); + float64x2_t _b = vreinterpretq_f64_m128d(b); + return vreinterpretq_m128d_f64(vbslq_f64(vcgtq_f64(_a, _b), _a, _b)); +#else + return vreinterpretq_m128d_f64( + vmaxq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#endif +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = (*(double *) &a0) > (*(double *) &b0) ? a0 : b0; + d[1] = (*(double *) &a1) > (*(double *) &b1) ? a1 : b1; + + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif +} + +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b, store the maximum value in the lower element of dst, and copy the upper +// element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_sd +FORCE_INLINE __m128d _mm_max_sd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return _mm_move_sd(a, _mm_max_pd(a, b)); +#else + double *da = (double *) &a; + double *db = (double *) &b; + double c[2] = {da[0] > db[0] ? da[0] : db[0], da[1]}; + return vreinterpretq_m128d_f32(vld1q_f32((float32_t *) c)); +#endif +} + +// Computes the pairwise minima of the 8 signed 16-bit integers from a and the 8 +// signed 16-bit integers from b. +// https://msdn.microsoft.com/en-us/library/vstudio/6te997ew(v=vs.100).aspx +FORCE_INLINE __m128i _mm_min_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vminq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Computes the pairwise minima of the 16 unsigned 8-bit integers from a and the +// 16 unsigned 8-bit integers from b. +// https://msdn.microsoft.com/ko-kr/library/17k8cf58(v=vs.100).aspxx +FORCE_INLINE __m128i _mm_min_epu8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vminq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); +} + +// Compare packed double-precision (64-bit) floating-point elements in a and b, +// and store packed minimum values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pd +FORCE_INLINE __m128d _mm_min_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) +#if SSE2NEON_PRECISE_MINMAX + float64x2_t _a = vreinterpretq_f64_m128d(a); + float64x2_t _b = vreinterpretq_f64_m128d(b); + return vreinterpretq_m128d_f64(vbslq_f64(vcltq_f64(_a, _b), _a, _b)); +#else + return vreinterpretq_m128d_f64( + vminq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#endif +#else + uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); + uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); + uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); + uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); + uint64_t d[2]; + d[0] = (*(double *) &a0) < (*(double *) &b0) ? a0 : b0; + d[1] = (*(double *) &a1) < (*(double *) &b1) ? a1 : b1; + return vreinterpretq_m128d_u64(vld1q_u64(d)); +#endif +} + +// Compare the lower double-precision (64-bit) floating-point elements in a and +// b, store the minimum value in the lower element of dst, and copy the upper +// element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_sd +FORCE_INLINE __m128d _mm_min_sd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return _mm_move_sd(a, _mm_min_pd(a, b)); +#else + double *da = (double *) &a; + double *db = (double *) &b; + double c[2] = {da[0] < db[0] ? da[0] : db[0], da[1]}; + return vreinterpretq_m128d_f32(vld1q_f32((float32_t *) c)); +#endif +} + +// Copy the lower 64-bit integer in a to the lower element of dst, and zero the +// upper element. +// +// dst[63:0] := a[63:0] +// dst[127:64] := 0 +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_move_epi64 +FORCE_INLINE __m128i _mm_move_epi64(__m128i a) +{ + return vreinterpretq_m128i_s64( + vsetq_lane_s64(0, vreinterpretq_s64_m128i(a), 1)); +} + +// Move the lower double-precision (64-bit) floating-point element from b to the +// lower element of dst, and copy the upper element from a to the upper element +// of dst. +// +// dst[63:0] := b[63:0] +// dst[127:64] := a[127:64] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_move_sd +FORCE_INLINE __m128d _mm_move_sd(__m128d a, __m128d b) +{ + return vreinterpretq_m128d_f32( + vcombine_f32(vget_low_f32(vreinterpretq_f32_m128d(b)), + vget_high_f32(vreinterpretq_f32_m128d(a)))); } // NEON does not provide a version of this function. @@ -2865,88 +4862,1193 @@ FORCE_INLINE __m128i _mm_movpi64_epi64(__m64 a) vcombine_s64(vreinterpret_s64_m64(a), vdup_n_s64(0))); } -// NEON does not provide this method -// Creates a 4-bit mask from the most significant bits of the four -// single-precision, floating-point values. -// https://msdn.microsoft.com/en-us/library/vstudio/4490ys29(v=vs.100).aspx -FORCE_INLINE int _mm_movemask_ps(__m128 a) +// Multiply the low unsigned 32-bit integers from each packed 64-bit element in +// a and b, and store the unsigned 64-bit results in dst. +// +// r0 := (a0 & 0xFFFFFFFF) * (b0 & 0xFFFFFFFF) +// r1 := (a2 & 0xFFFFFFFF) * (b2 & 0xFFFFFFFF) +FORCE_INLINE __m128i _mm_mul_epu32(__m128i a, __m128i b) +{ + // vmull_u32 upcasts instead of masking, so we downcast. + uint32x2_t a_lo = vmovn_u64(vreinterpretq_u64_m128i(a)); + uint32x2_t b_lo = vmovn_u64(vreinterpretq_u64_m128i(b)); + return vreinterpretq_m128i_u64(vmull_u32(a_lo, b_lo)); +} + +// Multiply packed double-precision (64-bit) floating-point elements in a and b, +// and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mul_pd +FORCE_INLINE __m128d _mm_mul_pd(__m128d a, __m128d b) { - uint32x4_t input = vreinterpretq_u32_m128(a); #if defined(__aarch64__) - static const int32x4_t shift = {0, 1, 2, 3}; - uint32x4_t tmp = vshrq_n_u32(input, 31); - return vaddvq_u32(vshlq_u32(tmp, shift)); + return vreinterpretq_m128d_f64( + vmulq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); #else - // Uses the exact same method as _mm_movemask_epi8, see that for details. - // Shift out everything but the sign bits with a 32-bit unsigned shift - // right. - uint64x2_t high_bits = vreinterpretq_u64_u32(vshrq_n_u32(input, 31)); - // Merge the two pairs together with a 64-bit unsigned shift right + add. - uint8x16_t paired = - vreinterpretq_u8_u64(vsraq_n_u64(high_bits, high_bits, 31)); - // Extract the result. - return vgetq_lane_u8(paired, 0) | (vgetq_lane_u8(paired, 8) << 2); + double *da = (double *) &a; + double *db = (double *) &b; + double c[2]; + c[0] = da[0] * db[0]; + c[1] = da[1] * db[1]; + return vld1q_f32((float32_t *) c); #endif } -// Compute the bitwise NOT of a and then AND with a 128-bit vector containing -// all 1's, and return 1 if the result is zero, otherwise return 0. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_test_all_ones -FORCE_INLINE int _mm_test_all_ones(__m128i a) +// Multiply the lower double-precision (64-bit) floating-point element in a and +// b, store the result in the lower element of dst, and copy the upper element +// from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_mul_sd +FORCE_INLINE __m128d _mm_mul_sd(__m128d a, __m128d b) { - return (uint64_t)(vgetq_lane_s64(a, 0) & vgetq_lane_s64(a, 1)) == - ~(uint64_t) 0; + return _mm_move_sd(a, _mm_mul_pd(a, b)); } -// Compute the bitwise AND of 128 bits (representing integer data) in a and -// mask, and return 1 if the result is zero, otherwise return 0. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_test_all_zeros -FORCE_INLINE int _mm_test_all_zeros(__m128i a, __m128i mask) +// Multiply the low unsigned 32-bit integers from a and b, and store the +// unsigned 64-bit result in dst. +// +// dst[63:0] := a[31:0] * b[31:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mul_su32 +FORCE_INLINE __m64 _mm_mul_su32(__m64 a, __m64 b) { - int64x2_t a_and_mask = - vandq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(mask)); - return (vgetq_lane_s64(a_and_mask, 0) | vgetq_lane_s64(a_and_mask, 1)) ? 0 - : 1; + return vreinterpret_m64_u64(vget_low_u64( + vmull_u32(vreinterpret_u32_m64(a), vreinterpret_u32_m64(b)))); } -/* Math operations */ - -// Subtracts the four single-precision, floating-point values of a and b. +// Multiplies the 8 signed 16-bit integers from a by the 8 signed 16-bit +// integers from b. // -// r0 := a0 - b0 -// r1 := a1 - b1 -// r2 := a2 - b2 -// r3 := a3 - b3 +// r0 := (a0 * b0)[31:16] +// r1 := (a1 * b1)[31:16] +// ... +// r7 := (a7 * b7)[31:16] // -// https://msdn.microsoft.com/en-us/library/vstudio/1zad2k61(v=vs.100).aspx -FORCE_INLINE __m128 _mm_sub_ps(__m128 a, __m128 b) +// https://msdn.microsoft.com/en-us/library/vstudio/59hddw1d(v=vs.100).aspx +FORCE_INLINE __m128i _mm_mulhi_epi16(__m128i a, __m128i b) { - return vreinterpretq_m128_f32( - vsubq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); + /* FIXME: issue with large values because of result saturation */ + // int16x8_t ret = vqdmulhq_s16(vreinterpretq_s16_m128i(a), + // vreinterpretq_s16_m128i(b)); /* =2*a*b */ return + // vreinterpretq_m128i_s16(vshrq_n_s16(ret, 1)); + int16x4_t a3210 = vget_low_s16(vreinterpretq_s16_m128i(a)); + int16x4_t b3210 = vget_low_s16(vreinterpretq_s16_m128i(b)); + int32x4_t ab3210 = vmull_s16(a3210, b3210); /* 3333222211110000 */ + int16x4_t a7654 = vget_high_s16(vreinterpretq_s16_m128i(a)); + int16x4_t b7654 = vget_high_s16(vreinterpretq_s16_m128i(b)); + int32x4_t ab7654 = vmull_s16(a7654, b7654); /* 7777666655554444 */ + uint16x8x2_t r = + vuzpq_u16(vreinterpretq_u16_s32(ab3210), vreinterpretq_u16_s32(ab7654)); + return vreinterpretq_m128i_u16(r.val[1]); } -// Subtract the lower single-precision (32-bit) floating-point element in b from -// the lower single-precision (32-bit) floating-point element in a, store the -// result in the lower element of dst, and copy the upper 3 packed elements from -// a to the upper elements of dst. -// -// dst[31:0] := a[31:0] - b[31:0] -// dst[127:32] := a[127:32] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_ss -FORCE_INLINE __m128 _mm_sub_ss(__m128 a, __m128 b) +// Multiply the packed unsigned 16-bit integers in a and b, producing +// intermediate 32-bit integers, and store the high 16 bits of the intermediate +// integers in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mulhi_epu16 +FORCE_INLINE __m128i _mm_mulhi_epu16(__m128i a, __m128i b) { - return _mm_move_ss(a, _mm_sub_ps(a, b)); + uint16x4_t a3210 = vget_low_u16(vreinterpretq_u16_m128i(a)); + uint16x4_t b3210 = vget_low_u16(vreinterpretq_u16_m128i(b)); + uint32x4_t ab3210 = vmull_u16(a3210, b3210); +#if defined(__aarch64__) + uint32x4_t ab7654 = + vmull_high_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b)); + uint16x8_t r = vuzp2q_u16(vreinterpretq_u16_u32(ab3210), + vreinterpretq_u16_u32(ab7654)); + return vreinterpretq_m128i_u16(r); +#else + uint16x4_t a7654 = vget_high_u16(vreinterpretq_u16_m128i(a)); + uint16x4_t b7654 = vget_high_u16(vreinterpretq_u16_m128i(b)); + uint32x4_t ab7654 = vmull_u16(a7654, b7654); + uint16x8x2_t r = + vuzpq_u16(vreinterpretq_u16_u32(ab3210), vreinterpretq_u16_u32(ab7654)); + return vreinterpretq_m128i_u16(r.val[1]); +#endif } -// Subtract 2 packed 64-bit integers in b from 2 packed 64-bit integers in a, -// and store the results in dst. -// r0 := a0 - b0 -// r1 := a1 - b1 -FORCE_INLINE __m128i _mm_sub_epi64(__m128i a, __m128i b) +// Multiplies the 8 signed or unsigned 16-bit integers from a by the 8 signed or +// unsigned 16-bit integers from b. +// +// r0 := (a0 * b0)[15:0] +// r1 := (a1 * b1)[15:0] +// ... +// r7 := (a7 * b7)[15:0] +// +// https://msdn.microsoft.com/en-us/library/vstudio/9ks1472s(v=vs.100).aspx +FORCE_INLINE __m128i _mm_mullo_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vmulq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} + +// Compute the bitwise OR of packed double-precision (64-bit) floating-point +// elements in a and b, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_or_pd +FORCE_INLINE __m128d _mm_or_pd(__m128d a, __m128d b) +{ + return vreinterpretq_m128d_s64( + vorrq_s64(vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b))); +} + +// Computes the bitwise OR of the 128-bit value in a and the 128-bit value in b. +// +// r := a | b +// +// https://msdn.microsoft.com/en-us/library/vstudio/ew8ty0db(v=vs.100).aspx +FORCE_INLINE __m128i _mm_or_si128(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vorrq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Packs the 16 signed 16-bit integers from a and b into 8-bit integers and +// saturates. +// https://msdn.microsoft.com/en-us/library/k4y4f7w5%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_packs_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s8( + vcombine_s8(vqmovn_s16(vreinterpretq_s16_m128i(a)), + vqmovn_s16(vreinterpretq_s16_m128i(b)))); +} + +// Packs the 8 signed 32-bit integers from a and b into signed 16-bit integers +// and saturates. +// +// r0 := SignedSaturate(a0) +// r1 := SignedSaturate(a1) +// r2 := SignedSaturate(a2) +// r3 := SignedSaturate(a3) +// r4 := SignedSaturate(b0) +// r5 := SignedSaturate(b1) +// r6 := SignedSaturate(b2) +// r7 := SignedSaturate(b3) +// +// https://msdn.microsoft.com/en-us/library/393t56f9%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_packs_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vcombine_s16(vqmovn_s32(vreinterpretq_s32_m128i(a)), + vqmovn_s32(vreinterpretq_s32_m128i(b)))); +} + +// Packs the 16 signed 16 - bit integers from a and b into 8 - bit unsigned +// integers and saturates. +// +// r0 := UnsignedSaturate(a0) +// r1 := UnsignedSaturate(a1) +// ... +// r7 := UnsignedSaturate(a7) +// r8 := UnsignedSaturate(b0) +// r9 := UnsignedSaturate(b1) +// ... +// r15 := UnsignedSaturate(b7) +// +// https://msdn.microsoft.com/en-us/library/07ad1wx4(v=vs.100).aspx +FORCE_INLINE __m128i _mm_packus_epi16(const __m128i a, const __m128i b) +{ + return vreinterpretq_m128i_u8( + vcombine_u8(vqmovun_s16(vreinterpretq_s16_m128i(a)), + vqmovun_s16(vreinterpretq_s16_m128i(b)))); +} + +// Pause the processor. This is typically used in spin-wait loops and depending +// on the x86 processor typical values are in the 40-100 cycle range. The +// 'yield' instruction isn't a good fit because it's effectively a nop on most +// Arm cores. Experience with several databases has shown has shown an 'isb' is +// a reasonable approximation. +FORCE_INLINE void _mm_pause() +{ + __asm__ __volatile__("isb\n"); +} + +// Compute the absolute differences of packed unsigned 8-bit integers in a and +// b, then horizontally sum each consecutive 8 differences to produce two +// unsigned 16-bit integers, and pack these unsigned 16-bit integers in the low +// 16 bits of 64-bit elements in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sad_epu8 +FORCE_INLINE __m128i _mm_sad_epu8(__m128i a, __m128i b) +{ + uint16x8_t t = vpaddlq_u8(vabdq_u8((uint8x16_t) a, (uint8x16_t) b)); + return vreinterpretq_m128i_u64(vpaddlq_u32(vpaddlq_u16(t))); +} + +// Sets the 8 signed 16-bit integer values. +// https://msdn.microsoft.com/en-au/library/3e0fek84(v=vs.90).aspx +FORCE_INLINE __m128i _mm_set_epi16(short i7, + short i6, + short i5, + short i4, + short i3, + short i2, + short i1, + short i0) +{ + int16_t ALIGN_STRUCT(16) data[8] = {i0, i1, i2, i3, i4, i5, i6, i7}; + return vreinterpretq_m128i_s16(vld1q_s16(data)); +} + +// Sets the 4 signed 32-bit integer values. +// https://msdn.microsoft.com/en-us/library/vstudio/019beekt(v=vs.100).aspx +FORCE_INLINE __m128i _mm_set_epi32(int i3, int i2, int i1, int i0) +{ + int32_t ALIGN_STRUCT(16) data[4] = {i0, i1, i2, i3}; + return vreinterpretq_m128i_s32(vld1q_s32(data)); +} + +// Returns the __m128i structure with its two 64-bit integer values +// initialized to the values of the two 64-bit integers passed in. +// https://msdn.microsoft.com/en-us/library/dk2sdw0h(v=vs.120).aspx +FORCE_INLINE __m128i _mm_set_epi64(__m64 i1, __m64 i2) +{ + return _mm_set_epi64x((int64_t) i1, (int64_t) i2); +} + +// Returns the __m128i structure with its two 64-bit integer values +// initialized to the values of the two 64-bit integers passed in. +// https://msdn.microsoft.com/en-us/library/dk2sdw0h(v=vs.120).aspx +FORCE_INLINE __m128i _mm_set_epi64x(int64_t i1, int64_t i2) { return vreinterpretq_m128i_s64( - vsubq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b))); + vcombine_s64(vcreate_s64(i2), vcreate_s64(i1))); +} + +// Sets the 16 signed 8-bit integer values. +// https://msdn.microsoft.com/en-us/library/x0cx8zd3(v=vs.90).aspx +FORCE_INLINE __m128i _mm_set_epi8(signed char b15, + signed char b14, + signed char b13, + signed char b12, + signed char b11, + signed char b10, + signed char b9, + signed char b8, + signed char b7, + signed char b6, + signed char b5, + signed char b4, + signed char b3, + signed char b2, + signed char b1, + signed char b0) +{ + int8_t ALIGN_STRUCT(16) + data[16] = {(int8_t) b0, (int8_t) b1, (int8_t) b2, (int8_t) b3, + (int8_t) b4, (int8_t) b5, (int8_t) b6, (int8_t) b7, + (int8_t) b8, (int8_t) b9, (int8_t) b10, (int8_t) b11, + (int8_t) b12, (int8_t) b13, (int8_t) b14, (int8_t) b15}; + return (__m128i) vld1q_s8(data); +} + +// Set packed double-precision (64-bit) floating-point elements in dst with the +// supplied values. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_pd +FORCE_INLINE __m128d _mm_set_pd(double e1, double e0) +{ + double ALIGN_STRUCT(16) data[2] = {e0, e1}; +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vld1q_f64((float64_t *) data)); +#else + return vreinterpretq_m128d_f32(vld1q_f32((float32_t *) data)); +#endif +} + +// Broadcast double-precision (64-bit) floating-point value a to all elements of +// dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_pd1 +#define _mm_set_pd1 _mm_set1_pd + +// Copy double-precision (64-bit) floating-point element a to the lower element +// of dst, and zero the upper element. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set_sd +FORCE_INLINE __m128d _mm_set_sd(double a) +{ + return _mm_set_pd(0, a); +} + +// Sets the 8 signed 16-bit integer values to w. +// +// r0 := w +// r1 := w +// ... +// r7 := w +// +// https://msdn.microsoft.com/en-us/library/k0ya3x0e(v=vs.90).aspx +FORCE_INLINE __m128i _mm_set1_epi16(short w) +{ + return vreinterpretq_m128i_s16(vdupq_n_s16(w)); +} + +// Sets the 4 signed 32-bit integer values to i. +// +// r0 := i +// r1 := i +// r2 := i +// r3 := I +// +// https://msdn.microsoft.com/en-us/library/vstudio/h4xscxat(v=vs.100).aspx +FORCE_INLINE __m128i _mm_set1_epi32(int _i) +{ + return vreinterpretq_m128i_s32(vdupq_n_s32(_i)); +} + +// Sets the 2 signed 64-bit integer values to i. +// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/whtfzhzk(v=vs.100) +FORCE_INLINE __m128i _mm_set1_epi64(__m64 _i) +{ + return vreinterpretq_m128i_s64(vdupq_n_s64((int64_t) _i)); +} + +// Sets the 2 signed 64-bit integer values to i. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set1_epi64x +FORCE_INLINE __m128i _mm_set1_epi64x(int64_t _i) +{ + return vreinterpretq_m128i_s64(vdupq_n_s64(_i)); +} + +// Sets the 16 signed 8-bit integer values to b. +// +// r0 := b +// r1 := b +// ... +// r15 := b +// +// https://msdn.microsoft.com/en-us/library/6e14xhyf(v=vs.100).aspx +FORCE_INLINE __m128i _mm_set1_epi8(signed char w) +{ + return vreinterpretq_m128i_s8(vdupq_n_s8(w)); +} + +// Broadcast double-precision (64-bit) floating-point value a to all elements of +// dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_set1_pd +FORCE_INLINE __m128d _mm_set1_pd(double d) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vdupq_n_f64(d)); +#else + return vreinterpretq_m128d_s64(vdupq_n_s64(*(int64_t *) &d)); +#endif +} + +// Sets the 8 signed 16-bit integer values in reverse order. +// +// Return Value +// r0 := w0 +// r1 := w1 +// ... +// r7 := w7 +FORCE_INLINE __m128i _mm_setr_epi16(short w0, + short w1, + short w2, + short w3, + short w4, + short w5, + short w6, + short w7) +{ + int16_t ALIGN_STRUCT(16) data[8] = {w0, w1, w2, w3, w4, w5, w6, w7}; + return vreinterpretq_m128i_s16(vld1q_s16((int16_t *) data)); +} + +// Sets the 4 signed 32-bit integer values in reverse order +// https://technet.microsoft.com/en-us/library/security/27yb3ee5(v=vs.90).aspx +FORCE_INLINE __m128i _mm_setr_epi32(int i3, int i2, int i1, int i0) +{ + int32_t ALIGN_STRUCT(16) data[4] = {i3, i2, i1, i0}; + return vreinterpretq_m128i_s32(vld1q_s32(data)); +} + +// Set packed 64-bit integers in dst with the supplied values in reverse order. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_setr_epi64 +FORCE_INLINE __m128i _mm_setr_epi64(__m64 e1, __m64 e0) +{ + return vreinterpretq_m128i_s64(vcombine_s64(e1, e0)); +} + +// Sets the 16 signed 8-bit integer values in reverse order. +// https://msdn.microsoft.com/en-us/library/2khb9c7k(v=vs.90).aspx +FORCE_INLINE __m128i _mm_setr_epi8(signed char b0, + signed char b1, + signed char b2, + signed char b3, + signed char b4, + signed char b5, + signed char b6, + signed char b7, + signed char b8, + signed char b9, + signed char b10, + signed char b11, + signed char b12, + signed char b13, + signed char b14, + signed char b15) +{ + int8_t ALIGN_STRUCT(16) + data[16] = {(int8_t) b0, (int8_t) b1, (int8_t) b2, (int8_t) b3, + (int8_t) b4, (int8_t) b5, (int8_t) b6, (int8_t) b7, + (int8_t) b8, (int8_t) b9, (int8_t) b10, (int8_t) b11, + (int8_t) b12, (int8_t) b13, (int8_t) b14, (int8_t) b15}; + return (__m128i) vld1q_s8(data); +} + +// Set packed double-precision (64-bit) floating-point elements in dst with the +// supplied values in reverse order. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_setr_pd +FORCE_INLINE __m128d _mm_setr_pd(double e1, double e0) +{ + return _mm_set_pd(e0, e1); +} + +// Return vector of type __m128d with all elements set to zero. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_setzero_pd +FORCE_INLINE __m128d _mm_setzero_pd(void) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vdupq_n_f64(0)); +#else + return vreinterpretq_m128d_f32(vdupq_n_f32(0)); +#endif +} + +// Sets the 128-bit value to zero +// https://msdn.microsoft.com/en-us/library/vstudio/ys7dw0kh(v=vs.100).aspx +FORCE_INLINE __m128i _mm_setzero_si128(void) +{ + return vreinterpretq_m128i_s32(vdupq_n_s32(0)); +} + +// Shuffles the 4 signed or unsigned 32-bit integers in a as specified by imm. +// https://msdn.microsoft.com/en-us/library/56f67xbk%28v=vs.90%29.aspx +// FORCE_INLINE __m128i _mm_shuffle_epi32(__m128i a, +// __constrange(0,255) int imm) +#if __has_builtin(__builtin_shufflevector) +#define _mm_shuffle_epi32(a, imm) \ + __extension__({ \ + int32x4_t _input = vreinterpretq_s32_m128i(a); \ + int32x4_t _shuf = __builtin_shufflevector( \ + _input, _input, (imm) & (0x3), ((imm) >> 2) & 0x3, \ + ((imm) >> 4) & 0x3, ((imm) >> 6) & 0x3); \ + vreinterpretq_m128i_s32(_shuf); \ + }) +#else // generic +#define _mm_shuffle_epi32(a, imm) \ + __extension__({ \ + __m128i ret; \ + switch (imm) { \ + case _MM_SHUFFLE(1, 0, 3, 2): \ + ret = _mm_shuffle_epi_1032((a)); \ + break; \ + case _MM_SHUFFLE(2, 3, 0, 1): \ + ret = _mm_shuffle_epi_2301((a)); \ + break; \ + case _MM_SHUFFLE(0, 3, 2, 1): \ + ret = _mm_shuffle_epi_0321((a)); \ + break; \ + case _MM_SHUFFLE(2, 1, 0, 3): \ + ret = _mm_shuffle_epi_2103((a)); \ + break; \ + case _MM_SHUFFLE(1, 0, 1, 0): \ + ret = _mm_shuffle_epi_1010((a)); \ + break; \ + case _MM_SHUFFLE(1, 0, 0, 1): \ + ret = _mm_shuffle_epi_1001((a)); \ + break; \ + case _MM_SHUFFLE(0, 1, 0, 1): \ + ret = _mm_shuffle_epi_0101((a)); \ + break; \ + case _MM_SHUFFLE(2, 2, 1, 1): \ + ret = _mm_shuffle_epi_2211((a)); \ + break; \ + case _MM_SHUFFLE(0, 1, 2, 2): \ + ret = _mm_shuffle_epi_0122((a)); \ + break; \ + case _MM_SHUFFLE(3, 3, 3, 2): \ + ret = _mm_shuffle_epi_3332((a)); \ + break; \ + case _MM_SHUFFLE(0, 0, 0, 0): \ + ret = _mm_shuffle_epi32_splat((a), 0); \ + break; \ + case _MM_SHUFFLE(1, 1, 1, 1): \ + ret = _mm_shuffle_epi32_splat((a), 1); \ + break; \ + case _MM_SHUFFLE(2, 2, 2, 2): \ + ret = _mm_shuffle_epi32_splat((a), 2); \ + break; \ + case _MM_SHUFFLE(3, 3, 3, 3): \ + ret = _mm_shuffle_epi32_splat((a), 3); \ + break; \ + default: \ + ret = _mm_shuffle_epi32_default((a), (imm)); \ + break; \ + } \ + ret; \ + }) +#endif + +// Shuffle double-precision (64-bit) floating-point elements using the control +// in imm8, and store the results in dst. +// +// dst[63:0] := (imm8[0] == 0) ? a[63:0] : a[127:64] +// dst[127:64] := (imm8[1] == 0) ? b[63:0] : b[127:64] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_shuffle_pd +#if __has_builtin(__builtin_shufflevector) +#define _mm_shuffle_pd(a, b, imm8) \ + vreinterpretq_m128d_s64(__builtin_shufflevector( \ + vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b), imm8 & 0x1, \ + ((imm8 & 0x2) >> 1) + 2)) +#else +#define _mm_shuffle_pd(a, b, imm8) \ + _mm_castsi128_pd(_mm_set_epi64x( \ + vgetq_lane_s64(vreinterpretq_s64_m128d(b), (imm8 & 0x2) >> 1), \ + vgetq_lane_s64(vreinterpretq_s64_m128d(a), imm8 & 0x1))) +#endif + +// FORCE_INLINE __m128i _mm_shufflehi_epi16(__m128i a, +// __constrange(0,255) int imm) +#if __has_builtin(__builtin_shufflevector) +#define _mm_shufflehi_epi16(a, imm) \ + __extension__({ \ + int16x8_t _input = vreinterpretq_s16_m128i(a); \ + int16x8_t _shuf = __builtin_shufflevector( \ + _input, _input, 0, 1, 2, 3, ((imm) & (0x3)) + 4, \ + (((imm) >> 2) & 0x3) + 4, (((imm) >> 4) & 0x3) + 4, \ + (((imm) >> 6) & 0x3) + 4); \ + vreinterpretq_m128i_s16(_shuf); \ + }) +#else // generic +#define _mm_shufflehi_epi16(a, imm) _mm_shufflehi_epi16_function((a), (imm)) +#endif + +// FORCE_INLINE __m128i _mm_shufflelo_epi16(__m128i a, +// __constrange(0,255) int imm) +#if __has_builtin(__builtin_shufflevector) +#define _mm_shufflelo_epi16(a, imm) \ + __extension__({ \ + int16x8_t _input = vreinterpretq_s16_m128i(a); \ + int16x8_t _shuf = __builtin_shufflevector( \ + _input, _input, ((imm) & (0x3)), (((imm) >> 2) & 0x3), \ + (((imm) >> 4) & 0x3), (((imm) >> 6) & 0x3), 4, 5, 6, 7); \ + vreinterpretq_m128i_s16(_shuf); \ + }) +#else // generic +#define _mm_shufflelo_epi16(a, imm) _mm_shufflelo_epi16_function((a), (imm)) +#endif + +// Shift packed 16-bit integers in a left by count while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// IF count[63:0] > 15 +// dst[i+15:i] := 0 +// ELSE +// dst[i+15:i] := ZeroExtend16(a[i+15:i] << count[63:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sll_epi16 +FORCE_INLINE __m128i _mm_sll_epi16(__m128i a, __m128i count) +{ + uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); + if (_sse2neon_unlikely(c & ~15)) + return _mm_setzero_si128(); + + int16x8_t vc = vdupq_n_s16((int16_t) c); + return vreinterpretq_m128i_s16(vshlq_s16(vreinterpretq_s16_m128i(a), vc)); +} + +// Shift packed 32-bit integers in a left by count while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 3 +// i := j*32 +// IF count[63:0] > 31 +// dst[i+31:i] := 0 +// ELSE +// dst[i+31:i] := ZeroExtend32(a[i+31:i] << count[63:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sll_epi32 +FORCE_INLINE __m128i _mm_sll_epi32(__m128i a, __m128i count) +{ + uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); + if (_sse2neon_unlikely(c & ~31)) + return _mm_setzero_si128(); + + int32x4_t vc = vdupq_n_s32((int32_t) c); + return vreinterpretq_m128i_s32(vshlq_s32(vreinterpretq_s32_m128i(a), vc)); +} + +// Shift packed 64-bit integers in a left by count while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 1 +// i := j*64 +// IF count[63:0] > 63 +// dst[i+63:i] := 0 +// ELSE +// dst[i+63:i] := ZeroExtend64(a[i+63:i] << count[63:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sll_epi64 +FORCE_INLINE __m128i _mm_sll_epi64(__m128i a, __m128i count) +{ + uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); + if (_sse2neon_unlikely(c & ~63)) + return _mm_setzero_si128(); + + int64x2_t vc = vdupq_n_s64((int64_t) c); + return vreinterpretq_m128i_s64(vshlq_s64(vreinterpretq_s64_m128i(a), vc)); +} + +// Shift packed 16-bit integers in a left by imm8 while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// IF imm8[7:0] > 15 +// dst[i+15:i] := 0 +// ELSE +// dst[i+15:i] := ZeroExtend16(a[i+15:i] << imm8[7:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_slli_epi16 +FORCE_INLINE __m128i _mm_slli_epi16(__m128i a, int imm) +{ + if (_sse2neon_unlikely(imm & ~15)) + return _mm_setzero_si128(); + return vreinterpretq_m128i_s16( + vshlq_s16(vreinterpretq_s16_m128i(a), vdupq_n_s16(imm))); +} + +// Shift packed 32-bit integers in a left by imm8 while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 3 +// i := j*32 +// IF imm8[7:0] > 31 +// dst[i+31:i] := 0 +// ELSE +// dst[i+31:i] := ZeroExtend32(a[i+31:i] << imm8[7:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_slli_epi32 +FORCE_INLINE __m128i _mm_slli_epi32(__m128i a, int imm) +{ + if (_sse2neon_unlikely(imm & ~31)) + return _mm_setzero_si128(); + return vreinterpretq_m128i_s32( + vshlq_s32(vreinterpretq_s32_m128i(a), vdupq_n_s32(imm))); +} + +// Shift packed 64-bit integers in a left by imm8 while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 1 +// i := j*64 +// IF imm8[7:0] > 63 +// dst[i+63:i] := 0 +// ELSE +// dst[i+63:i] := ZeroExtend64(a[i+63:i] << imm8[7:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_slli_epi64 +FORCE_INLINE __m128i _mm_slli_epi64(__m128i a, int imm) +{ + if (_sse2neon_unlikely(imm & ~63)) + return _mm_setzero_si128(); + return vreinterpretq_m128i_s64( + vshlq_s64(vreinterpretq_s64_m128i(a), vdupq_n_s64(imm))); +} + +// Shift a left by imm8 bytes while shifting in zeros, and store the results in +// dst. +// +// tmp := imm8[7:0] +// IF tmp > 15 +// tmp := 16 +// FI +// dst[127:0] := a[127:0] << (tmp*8) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_slli_si128 +FORCE_INLINE __m128i _mm_slli_si128(__m128i a, int imm) +{ + if (_sse2neon_unlikely(imm & ~15)) + return _mm_setzero_si128(); + uint8x16_t tmp[2] = {vdupq_n_u8(0), vreinterpretq_u8_m128i(a)}; + return vreinterpretq_m128i_u8( + vld1q_u8(((uint8_t const *) tmp) + (16 - imm))); +} + +// Compute the square root of packed double-precision (64-bit) floating-point +// elements in a, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sqrt_pd +FORCE_INLINE __m128d _mm_sqrt_pd(__m128d a) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vsqrtq_f64(vreinterpretq_f64_m128d(a))); +#else + double a0 = sqrt(((double *) &a)[0]); + double a1 = sqrt(((double *) &a)[1]); + return _mm_set_pd(a1, a0); +#endif +} + +// Compute the square root of the lower double-precision (64-bit) floating-point +// element in b, store the result in the lower element of dst, and copy the +// upper element from a to the upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sqrt_sd +FORCE_INLINE __m128d _mm_sqrt_sd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return _mm_move_sd(a, _mm_sqrt_pd(b)); +#else + return _mm_set_pd(((double *) &a)[1], sqrt(((double *) &b)[0])); +#endif +} + +// Shift packed 16-bit integers in a right by count while shifting in sign bits, +// and store the results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// IF count[63:0] > 15 +// dst[i+15:i] := (a[i+15] ? 0xFFFF : 0x0) +// ELSE +// dst[i+15:i] := SignExtend16(a[i+15:i] >> count[63:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sra_epi16 +FORCE_INLINE __m128i _mm_sra_epi16(__m128i a, __m128i count) +{ + int64_t c = (int64_t) vget_low_s64((int64x2_t) count); + if (_sse2neon_unlikely(c & ~15)) + return _mm_cmplt_epi16(a, _mm_setzero_si128()); + return vreinterpretq_m128i_s16(vshlq_s16((int16x8_t) a, vdupq_n_s16(-c))); +} + +// Shift packed 32-bit integers in a right by count while shifting in sign bits, +// and store the results in dst. +// +// FOR j := 0 to 3 +// i := j*32 +// IF count[63:0] > 31 +// dst[i+31:i] := (a[i+31] ? 0xFFFFFFFF : 0x0) +// ELSE +// dst[i+31:i] := SignExtend32(a[i+31:i] >> count[63:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sra_epi32 +FORCE_INLINE __m128i _mm_sra_epi32(__m128i a, __m128i count) +{ + int64_t c = (int64_t) vget_low_s64((int64x2_t) count); + if (_sse2neon_unlikely(c & ~31)) + return _mm_cmplt_epi32(a, _mm_setzero_si128()); + return vreinterpretq_m128i_s32(vshlq_s32((int32x4_t) a, vdupq_n_s32(-c))); +} + +// Shift packed 16-bit integers in a right by imm8 while shifting in sign +// bits, and store the results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// IF imm8[7:0] > 15 +// dst[i+15:i] := (a[i+15] ? 0xFFFF : 0x0) +// ELSE +// dst[i+15:i] := SignExtend16(a[i+15:i] >> imm8[7:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srai_epi16 +FORCE_INLINE __m128i _mm_srai_epi16(__m128i a, int imm) +{ + const int count = (imm & ~15) ? 15 : imm; + return (__m128i) vshlq_s16((int16x8_t) a, vdupq_n_s16(-count)); +} + +// Shift packed 32-bit integers in a right by imm8 while shifting in sign bits, +// and store the results in dst. +// +// FOR j := 0 to 3 +// i := j*32 +// IF imm8[7:0] > 31 +// dst[i+31:i] := (a[i+31] ? 0xFFFFFFFF : 0x0) +// ELSE +// dst[i+31:i] := SignExtend32(a[i+31:i] >> imm8[7:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srai_epi32 +// FORCE_INLINE __m128i _mm_srai_epi32(__m128i a, __constrange(0,255) int imm) +#define _mm_srai_epi32(a, imm) \ + __extension__({ \ + __m128i ret; \ + if (_sse2neon_unlikely((imm) == 0)) { \ + ret = a; \ + } else if (_sse2neon_likely(0 < (imm) && (imm) < 32)) { \ + ret = vreinterpretq_m128i_s32( \ + vshlq_s32(vreinterpretq_s32_m128i(a), vdupq_n_s32(-imm))); \ + } else { \ + ret = vreinterpretq_m128i_s32( \ + vshrq_n_s32(vreinterpretq_s32_m128i(a), 31)); \ + } \ + ret; \ + }) + +// Shift packed 16-bit integers in a right by count while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// IF count[63:0] > 15 +// dst[i+15:i] := 0 +// ELSE +// dst[i+15:i] := ZeroExtend16(a[i+15:i] >> count[63:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srl_epi16 +FORCE_INLINE __m128i _mm_srl_epi16(__m128i a, __m128i count) +{ + uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); + if (_sse2neon_unlikely(c & ~15)) + return _mm_setzero_si128(); + + int16x8_t vc = vdupq_n_s16(-(int16_t) c); + return vreinterpretq_m128i_u16(vshlq_u16(vreinterpretq_u16_m128i(a), vc)); +} + +// Shift packed 32-bit integers in a right by count while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 3 +// i := j*32 +// IF count[63:0] > 31 +// dst[i+31:i] := 0 +// ELSE +// dst[i+31:i] := ZeroExtend32(a[i+31:i] >> count[63:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srl_epi32 +FORCE_INLINE __m128i _mm_srl_epi32(__m128i a, __m128i count) +{ + uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); + if (_sse2neon_unlikely(c & ~31)) + return _mm_setzero_si128(); + + int32x4_t vc = vdupq_n_s32(-(int32_t) c); + return vreinterpretq_m128i_u32(vshlq_u32(vreinterpretq_u32_m128i(a), vc)); +} + +// Shift packed 64-bit integers in a right by count while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 1 +// i := j*64 +// IF count[63:0] > 63 +// dst[i+63:i] := 0 +// ELSE +// dst[i+63:i] := ZeroExtend64(a[i+63:i] >> count[63:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srl_epi64 +FORCE_INLINE __m128i _mm_srl_epi64(__m128i a, __m128i count) +{ + uint64_t c = vreinterpretq_nth_u64_m128i(count, 0); + if (_sse2neon_unlikely(c & ~63)) + return _mm_setzero_si128(); + + int64x2_t vc = vdupq_n_s64(-(int64_t) c); + return vreinterpretq_m128i_u64(vshlq_u64(vreinterpretq_u64_m128i(a), vc)); +} + +// Shift packed 16-bit integers in a right by imm8 while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// IF imm8[7:0] > 15 +// dst[i+15:i] := 0 +// ELSE +// dst[i+15:i] := ZeroExtend16(a[i+15:i] >> imm8[7:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srli_epi16 +#define _mm_srli_epi16(a, imm) \ + __extension__({ \ + __m128i ret; \ + if (_sse2neon_unlikely((imm) & ~15)) { \ + ret = _mm_setzero_si128(); \ + } else { \ + ret = vreinterpretq_m128i_u16( \ + vshlq_u16(vreinterpretq_u16_m128i(a), vdupq_n_s16(-(imm)))); \ + } \ + ret; \ + }) + +// Shift packed 32-bit integers in a right by imm8 while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 3 +// i := j*32 +// IF imm8[7:0] > 31 +// dst[i+31:i] := 0 +// ELSE +// dst[i+31:i] := ZeroExtend32(a[i+31:i] >> imm8[7:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srli_epi32 +// FORCE_INLINE __m128i _mm_srli_epi32(__m128i a, __constrange(0,255) int imm) +#define _mm_srli_epi32(a, imm) \ + __extension__({ \ + __m128i ret; \ + if (_sse2neon_unlikely((imm) & ~31)) { \ + ret = _mm_setzero_si128(); \ + } else { \ + ret = vreinterpretq_m128i_u32( \ + vshlq_u32(vreinterpretq_u32_m128i(a), vdupq_n_s32(-(imm)))); \ + } \ + ret; \ + }) + +// Shift packed 64-bit integers in a right by imm8 while shifting in zeros, and +// store the results in dst. +// +// FOR j := 0 to 1 +// i := j*64 +// IF imm8[7:0] > 63 +// dst[i+63:i] := 0 +// ELSE +// dst[i+63:i] := ZeroExtend64(a[i+63:i] >> imm8[7:0]) +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srli_epi64 +#define _mm_srli_epi64(a, imm) \ + __extension__({ \ + __m128i ret; \ + if (_sse2neon_unlikely((imm) & ~63)) { \ + ret = _mm_setzero_si128(); \ + } else { \ + ret = vreinterpretq_m128i_u64( \ + vshlq_u64(vreinterpretq_u64_m128i(a), vdupq_n_s64(-(imm)))); \ + } \ + ret; \ + }) + +// Shift a right by imm8 bytes while shifting in zeros, and store the results in +// dst. +// +// tmp := imm8[7:0] +// IF tmp > 15 +// tmp := 16 +// FI +// dst[127:0] := a[127:0] >> (tmp*8) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_srli_si128 +FORCE_INLINE __m128i _mm_srli_si128(__m128i a, int imm) +{ + if (_sse2neon_unlikely(imm & ~15)) + return _mm_setzero_si128(); + uint8x16_t tmp[2] = {vreinterpretq_u8_m128i(a), vdupq_n_u8(0)}; + return vreinterpretq_m128i_u8(vld1q_u8(((uint8_t const *) tmp) + imm)); +} + +// Store 128-bits (composed of 2 packed double-precision (64-bit) floating-point +// elements) from a into memory. mem_addr must be aligned on a 16-byte boundary +// or a general-protection exception may be generated. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store_pd +FORCE_INLINE void _mm_store_pd(double *mem_addr, __m128d a) +{ +#if defined(__aarch64__) + vst1q_f64((float64_t *) mem_addr, vreinterpretq_f64_m128d(a)); +#else + vst1q_f32((float32_t *) mem_addr, vreinterpretq_f32_m128d(a)); +#endif +} + +// Store the lower double-precision (64-bit) floating-point element from a into +// 2 contiguous elements in memory. mem_addr must be aligned on a 16-byte +// boundary or a general-protection exception may be generated. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_store_pd1 +FORCE_INLINE void _mm_store_pd1(double *mem_addr, __m128d a) +{ +#if defined(__aarch64__) + float64x1_t a_low = vget_low_f64(vreinterpretq_f64_m128d(a)); + vst1q_f64((float64_t *) mem_addr, + vreinterpretq_f64_m128d(vcombine_f64(a_low, a_low))); +#else + float32x2_t a_low = vget_low_f32(vreinterpretq_f32_m128d(a)); + vst1q_f32((float32_t *) mem_addr, + vreinterpretq_f32_m128d(vcombine_f32(a_low, a_low))); +#endif +} + +// Store the lower double-precision (64-bit) floating-point element from a into +// memory. mem_addr does not need to be aligned on any particular boundary. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_store_sd +FORCE_INLINE void _mm_store_sd(double *mem_addr, __m128d a) +{ +#if defined(__aarch64__) + vst1_f64((float64_t *) mem_addr, vget_low_f64(vreinterpretq_f64_m128d(a))); +#else + vst1_u64((uint64_t *) mem_addr, vget_low_u64(vreinterpretq_u64_m128d(a))); +#endif +} + +// Stores four 32-bit integer values as (as a __m128i value) at the address p. +// https://msdn.microsoft.com/en-us/library/vstudio/edk11s13(v=vs.100).aspx +FORCE_INLINE void _mm_store_si128(__m128i *p, __m128i a) +{ + vst1q_s32((int32_t *) p, vreinterpretq_s32_m128i(a)); +} + +// Store the lower double-precision (64-bit) floating-point element from a into +// 2 contiguous elements in memory. mem_addr must be aligned on a 16-byte +// boundary or a general-protection exception may be generated. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#expand=9,526,5601&text=_mm_store1_pd +#define _mm_store1_pd _mm_store_pd1 + +// Store the upper double-precision (64-bit) floating-point element from a into +// memory. +// +// MEM[mem_addr+63:mem_addr] := a[127:64] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeh_pd +FORCE_INLINE void _mm_storeh_pd(double *mem_addr, __m128d a) +{ +#if defined(__aarch64__) + vst1_f64((float64_t *) mem_addr, vget_high_f64(vreinterpretq_f64_m128d(a))); +#else + vst1_f32((float32_t *) mem_addr, vget_high_f32(vreinterpretq_f32_m128d(a))); +#endif +} + +// Reads the lower 64 bits of b and stores them into the lower 64 bits of a. +// https://msdn.microsoft.com/en-us/library/hhwf428f%28v=vs.90%29.aspx +FORCE_INLINE void _mm_storel_epi64(__m128i *a, __m128i b) +{ + vst1_u64((uint64_t *) a, vget_low_u64(vreinterpretq_u64_m128i(b))); +} + +// Store the lower double-precision (64-bit) floating-point element from a into +// memory. +// +// MEM[mem_addr+63:mem_addr] := a[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storel_pd +FORCE_INLINE void _mm_storel_pd(double *mem_addr, __m128d a) +{ +#if defined(__aarch64__) + vst1_f64((float64_t *) mem_addr, vget_low_f64(vreinterpretq_f64_m128d(a))); +#else + vst1_f32((float32_t *) mem_addr, vget_low_f32(vreinterpretq_f32_m128d(a))); +#endif +} + +// Store 2 double-precision (64-bit) floating-point elements from a into memory +// in reverse order. mem_addr must be aligned on a 16-byte boundary or a +// general-protection exception may be generated. +// +// MEM[mem_addr+63:mem_addr] := a[127:64] +// MEM[mem_addr+127:mem_addr+64] := a[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storer_pd +FORCE_INLINE void _mm_storer_pd(double *mem_addr, __m128d a) +{ + float32x4_t f = vreinterpretq_f32_m128d(a); + _mm_store_pd(mem_addr, vreinterpretq_m128d_f32(vextq_f32(f, f, 2))); +} + +// Store 128-bits (composed of 2 packed double-precision (64-bit) floating-point +// elements) from a into memory. mem_addr does not need to be aligned on any +// particular boundary. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_pd +FORCE_INLINE void _mm_storeu_pd(double *mem_addr, __m128d a) +{ + _mm_store_pd(mem_addr, a); +} + +// Stores 128-bits of integer data a at the address p. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_si128 +FORCE_INLINE void _mm_storeu_si128(__m128i *p, __m128i a) +{ + vst1q_s32((int32_t *) p, vreinterpretq_s32_m128i(a)); +} + +// Stores 32-bits of integer data a at the address p. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_storeu_si32 +FORCE_INLINE void _mm_storeu_si32(void *p, __m128i a) +{ + vst1q_lane_s32((int32_t *) p, vreinterpretq_s32_m128i(a), 0); +} + +// Store 128-bits (composed of 2 packed double-precision (64-bit) floating-point +// elements) from a into memory using a non-temporal memory hint. mem_addr must +// be aligned on a 16-byte boundary or a general-protection exception may be +// generated. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_pd +FORCE_INLINE void _mm_stream_pd(double *p, __m128d a) +{ +#if __has_builtin(__builtin_nontemporal_store) + __builtin_nontemporal_store(a, (float32x4_t *) p); +#elif defined(__aarch64__) + vst1q_f64(p, vreinterpretq_f64_m128d(a)); +#else + vst1q_s64((int64_t *) p, vreinterpretq_s64_m128d(a)); +#endif +} + +// Stores the data in a to the address p without polluting the caches. If the +// cache line containing address p is already in the cache, the cache will be +// updated. +// https://msdn.microsoft.com/en-us/library/ba08y07y%28v=vs.90%29.aspx +FORCE_INLINE void _mm_stream_si128(__m128i *p, __m128i a) +{ +#if __has_builtin(__builtin_nontemporal_store) + __builtin_nontemporal_store(a, p); +#else + vst1q_s64((int64_t *) p, vreinterpretq_s64_m128i(a)); +#endif +} + +// Store 32-bit integer a into memory using a non-temporal hint to minimize +// cache pollution. If the cache line containing address mem_addr is already in +// the cache, the cache will be updated. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_si32 +FORCE_INLINE void _mm_stream_si32(int *p, int a) +{ + vst1q_lane_s32((int32_t *) p, vdupq_n_s32(a), 0); +} + +// Store 64-bit integer a into memory using a non-temporal hint to minimize +// cache pollution. If the cache line containing address mem_addr is already in +// the cache, the cache will be updated. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_si64 +FORCE_INLINE void _mm_stream_si64(__int64 *p, __int64 a) +{ + vst1_s64((int64_t *) p, vdup_n_s64((int64_t) a)); +} + +// Subtract packed 16-bit integers in b from packed 16-bit integers in a, and +// store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_epi16 +FORCE_INLINE __m128i _mm_sub_epi16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s16( + vsubq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); } // Subtracts the 4 signed or unsigned 32-bit integers of b from the 4 signed or @@ -2964,13 +6066,14 @@ FORCE_INLINE __m128i _mm_sub_epi32(__m128i a, __m128i b) vsubq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); } -// Subtract packed 16-bit integers in b from packed 16-bit integers in a, and -// store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_epi16 -FORCE_INLINE __m128i _mm_sub_epi16(__m128i a, __m128i b) +// Subtract 2 packed 64-bit integers in b from 2 packed 64-bit integers in a, +// and store the results in dst. +// r0 := a0 - b0 +// r1 := a1 - b1 +FORCE_INLINE __m128i _mm_sub_epi64(__m128i a, __m128i b) { - return vreinterpretq_m128i_s16( - vsubq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); + return vreinterpretq_m128i_s64( + vsubq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b))); } // Subtract packed 8-bit integers in b from packed 8-bit integers in a, and @@ -2982,78 +6085,6 @@ FORCE_INLINE __m128i _mm_sub_epi8(__m128i a, __m128i b) vsubq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); } -// Subtract 64-bit integer b from 64-bit integer a, and store the result in dst. -// -// dst[63:0] := a[63:0] - b[63:0] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_si64 -FORCE_INLINE __m64 _mm_sub_si64(__m64 a, __m64 b) -{ - return vreinterpret_m64_s64( - vsub_s64(vreinterpret_s64_m64(a), vreinterpret_s64_m64(b))); -} - -// Subtracts the 8 unsigned 16-bit integers of bfrom the 8 unsigned 16-bit -// integers of a and saturates.. -// https://technet.microsoft.com/en-us/subscriptions/index/f44y0s19(v=vs.90).aspx -FORCE_INLINE __m128i _mm_subs_epu16(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_u16( - vqsubq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); -} - -// Subtracts the 16 unsigned 8-bit integers of b from the 16 unsigned 8-bit -// integers of a and saturates. -// -// r0 := UnsignedSaturate(a0 - b0) -// r1 := UnsignedSaturate(a1 - b1) -// ... -// r15 := UnsignedSaturate(a15 - b15) -// -// https://technet.microsoft.com/en-us/subscriptions/yadkxc18(v=vs.90) -FORCE_INLINE __m128i _mm_subs_epu8(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_u8( - vqsubq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); -} - -#define _mm_ucomieq_sd _mm_comieq_sd -#define _mm_ucomige_sd _mm_comige_sd -#define _mm_ucomigt_sd _mm_comigt_sd -#define _mm_ucomile_sd _mm_comile_sd -#define _mm_ucomilt_sd _mm_comilt_sd -#define _mm_ucomineq_sd _mm_comineq_sd - -// Subtracts the 16 signed 8-bit integers of b from the 16 signed 8-bit integers -// of a and saturates. -// -// r0 := SignedSaturate(a0 - b0) -// r1 := SignedSaturate(a1 - b1) -// ... -// r15 := SignedSaturate(a15 - b15) -// -// https://technet.microsoft.com/en-us/subscriptions/by7kzks1(v=vs.90) -FORCE_INLINE __m128i _mm_subs_epi8(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_s8( - vqsubq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); -} - -// Subtracts the 8 signed 16-bit integers of b from the 8 signed 16-bit integers -// of a and saturates. -// -// r0 := SignedSaturate(a0 - b0) -// r1 := SignedSaturate(a1 - b1) -// ... -// r7 := SignedSaturate(a7 - b7) -// -// https://technet.microsoft.com/en-us/subscriptions/3247z5b8(v=vs.90) -FORCE_INLINE __m128i _mm_subs_epi16(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_s16( - vqsubq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); -} - // Subtract packed double-precision (64-bit) floating-point elements in b from // packed double-precision (64-bit) floating-point elements in a, and store the // results in dst. @@ -3089,52 +6120,975 @@ FORCE_INLINE __m128d _mm_sub_sd(__m128d a, __m128d b) return _mm_move_sd(a, _mm_sub_pd(a, b)); } -// Add packed unsigned 16-bit integers in a and b using saturation, and store -// the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_adds_epu16 -FORCE_INLINE __m128i _mm_adds_epu16(__m128i a, __m128i b) +// Subtract 64-bit integer b from 64-bit integer a, and store the result in dst. +// +// dst[63:0] := a[63:0] - b[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sub_si64 +FORCE_INLINE __m64 _mm_sub_si64(__m64 a, __m64 b) { - return vreinterpretq_m128i_u16( - vqaddq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); + return vreinterpret_m64_s64( + vsub_s64(vreinterpret_s64_m64(a), vreinterpret_s64_m64(b))); } -// Negate packed 8-bit integers in a when the corresponding signed -// 8-bit integer in b is negative, and store the results in dst. -// Element in dst are zeroed out when the corresponding element -// in b is zero. +// Subtracts the 8 signed 16-bit integers of b from the 8 signed 16-bit integers +// of a and saturates. // -// for i in 0..15 -// if b[i] < 0 -// r[i] := -a[i] -// else if b[i] == 0 -// r[i] := 0 -// else -// r[i] := a[i] -// fi -// done -FORCE_INLINE __m128i _mm_sign_epi8(__m128i _a, __m128i _b) +// r0 := SignedSaturate(a0 - b0) +// r1 := SignedSaturate(a1 - b1) +// ... +// r7 := SignedSaturate(a7 - b7) +// +// https://technet.microsoft.com/en-us/subscriptions/3247z5b8(v=vs.90) +FORCE_INLINE __m128i _mm_subs_epi16(__m128i a, __m128i b) { - int8x16_t a = vreinterpretq_s8_m128i(_a); - int8x16_t b = vreinterpretq_s8_m128i(_b); + return vreinterpretq_m128i_s16( + vqsubq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +} - // signed shift right: faster than vclt - // (b < 0) ? 0xFF : 0 - uint8x16_t ltMask = vreinterpretq_u8_s8(vshrq_n_s8(b, 7)); +// Subtracts the 16 signed 8-bit integers of b from the 16 signed 8-bit integers +// of a and saturates. +// +// r0 := SignedSaturate(a0 - b0) +// r1 := SignedSaturate(a1 - b1) +// ... +// r15 := SignedSaturate(a15 - b15) +// +// https://technet.microsoft.com/en-us/subscriptions/by7kzks1(v=vs.90) +FORCE_INLINE __m128i _mm_subs_epi8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s8( + vqsubq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +} - // (b == 0) ? 0xFF : 0 -#if defined(__aarch64__) - int8x16_t zeroMask = vreinterpretq_s8_u8(vceqzq_s8(b)); -#else - int8x16_t zeroMask = vreinterpretq_s8_u8(vceqq_s8(b, vdupq_n_s8(0))); +// Subtracts the 8 unsigned 16-bit integers of bfrom the 8 unsigned 16-bit +// integers of a and saturates.. +// https://technet.microsoft.com/en-us/subscriptions/index/f44y0s19(v=vs.90).aspx +FORCE_INLINE __m128i _mm_subs_epu16(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vqsubq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); +} + +// Subtracts the 16 unsigned 8-bit integers of b from the 16 unsigned 8-bit +// integers of a and saturates. +// +// r0 := UnsignedSaturate(a0 - b0) +// r1 := UnsignedSaturate(a1 - b1) +// ... +// r15 := UnsignedSaturate(a15 - b15) +// +// https://technet.microsoft.com/en-us/subscriptions/yadkxc18(v=vs.90) +FORCE_INLINE __m128i _mm_subs_epu8(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u8( + vqsubq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); +} + +#define _mm_ucomieq_sd _mm_comieq_sd +#define _mm_ucomige_sd _mm_comige_sd +#define _mm_ucomigt_sd _mm_comigt_sd +#define _mm_ucomile_sd _mm_comile_sd +#define _mm_ucomilt_sd _mm_comilt_sd +#define _mm_ucomineq_sd _mm_comineq_sd + +// Return vector of type __m128d with undefined elements. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_undefined_pd +FORCE_INLINE __m128d _mm_undefined_pd(void) +{ +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wuninitialized" #endif + __m128d a; + return a; +#if defined(__GNUC__) || defined(__clang__) +#pragma GCC diagnostic pop +#endif +} - // bitwise select either a or nagative 'a' (vnegq_s8(a) return nagative 'a') - // based on ltMask - int8x16_t masked = vbslq_s8(ltMask, vnegq_s8(a), a); - // res = masked & (~zeroMask) - int8x16_t res = vbicq_s8(masked, zeroMask); +// Interleaves the upper 4 signed or unsigned 16-bit integers in a with the +// upper 4 signed or unsigned 16-bit integers in b. +// +// r0 := a4 +// r1 := b4 +// r2 := a5 +// r3 := b5 +// r4 := a6 +// r5 := b6 +// r6 := a7 +// r7 := b7 +// +// https://msdn.microsoft.com/en-us/library/03196cz7(v=vs.100).aspx +FORCE_INLINE __m128i _mm_unpackhi_epi16(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s16( + vzip2q_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +#else + int16x4_t a1 = vget_high_s16(vreinterpretq_s16_m128i(a)); + int16x4_t b1 = vget_high_s16(vreinterpretq_s16_m128i(b)); + int16x4x2_t result = vzip_s16(a1, b1); + return vreinterpretq_m128i_s16(vcombine_s16(result.val[0], result.val[1])); +#endif +} - return vreinterpretq_m128i_s8(res); +// Interleaves the upper 2 signed or unsigned 32-bit integers in a with the +// upper 2 signed or unsigned 32-bit integers in b. +// https://msdn.microsoft.com/en-us/library/65sa7cbs(v=vs.100).aspx +FORCE_INLINE __m128i _mm_unpackhi_epi32(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s32( + vzip2q_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +#else + int32x2_t a1 = vget_high_s32(vreinterpretq_s32_m128i(a)); + int32x2_t b1 = vget_high_s32(vreinterpretq_s32_m128i(b)); + int32x2x2_t result = vzip_s32(a1, b1); + return vreinterpretq_m128i_s32(vcombine_s32(result.val[0], result.val[1])); +#endif +} + +// Interleaves the upper signed or unsigned 64-bit integer in a with the +// upper signed or unsigned 64-bit integer in b. +// +// r0 := a1 +// r1 := b1 +FORCE_INLINE __m128i _mm_unpackhi_epi64(__m128i a, __m128i b) +{ + int64x1_t a_h = vget_high_s64(vreinterpretq_s64_m128i(a)); + int64x1_t b_h = vget_high_s64(vreinterpretq_s64_m128i(b)); + return vreinterpretq_m128i_s64(vcombine_s64(a_h, b_h)); +} + +// Interleaves the upper 8 signed or unsigned 8-bit integers in a with the upper +// 8 signed or unsigned 8-bit integers in b. +// +// r0 := a8 +// r1 := b8 +// r2 := a9 +// r3 := b9 +// ... +// r14 := a15 +// r15 := b15 +// +// https://msdn.microsoft.com/en-us/library/t5h7783k(v=vs.100).aspx +FORCE_INLINE __m128i _mm_unpackhi_epi8(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s8( + vzip2q_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +#else + int8x8_t a1 = + vreinterpret_s8_s16(vget_high_s16(vreinterpretq_s16_m128i(a))); + int8x8_t b1 = + vreinterpret_s8_s16(vget_high_s16(vreinterpretq_s16_m128i(b))); + int8x8x2_t result = vzip_s8(a1, b1); + return vreinterpretq_m128i_s8(vcombine_s8(result.val[0], result.val[1])); +#endif +} + +// Unpack and interleave double-precision (64-bit) floating-point elements from +// the high half of a and b, and store the results in dst. +// +// DEFINE INTERLEAVE_HIGH_QWORDS(src1[127:0], src2[127:0]) { +// dst[63:0] := src1[127:64] +// dst[127:64] := src2[127:64] +// RETURN dst[127:0] +// } +// dst[127:0] := INTERLEAVE_HIGH_QWORDS(a[127:0], b[127:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_unpackhi_pd +FORCE_INLINE __m128d _mm_unpackhi_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vzip2q_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + return vreinterpretq_m128d_s64( + vcombine_s64(vget_high_s64(vreinterpretq_s64_m128d(a)), + vget_high_s64(vreinterpretq_s64_m128d(b)))); +#endif +} + +// Interleaves the lower 4 signed or unsigned 16-bit integers in a with the +// lower 4 signed or unsigned 16-bit integers in b. +// +// r0 := a0 +// r1 := b0 +// r2 := a1 +// r3 := b1 +// r4 := a2 +// r5 := b2 +// r6 := a3 +// r7 := b3 +// +// https://msdn.microsoft.com/en-us/library/btxb17bw%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_unpacklo_epi16(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s16( + vzip1q_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); +#else + int16x4_t a1 = vget_low_s16(vreinterpretq_s16_m128i(a)); + int16x4_t b1 = vget_low_s16(vreinterpretq_s16_m128i(b)); + int16x4x2_t result = vzip_s16(a1, b1); + return vreinterpretq_m128i_s16(vcombine_s16(result.val[0], result.val[1])); +#endif +} + +// Interleaves the lower 2 signed or unsigned 32 - bit integers in a with the +// lower 2 signed or unsigned 32 - bit integers in b. +// +// r0 := a0 +// r1 := b0 +// r2 := a1 +// r3 := b1 +// +// https://msdn.microsoft.com/en-us/library/x8atst9d(v=vs.100).aspx +FORCE_INLINE __m128i _mm_unpacklo_epi32(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s32( + vzip1q_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +#else + int32x2_t a1 = vget_low_s32(vreinterpretq_s32_m128i(a)); + int32x2_t b1 = vget_low_s32(vreinterpretq_s32_m128i(b)); + int32x2x2_t result = vzip_s32(a1, b1); + return vreinterpretq_m128i_s32(vcombine_s32(result.val[0], result.val[1])); +#endif +} + +FORCE_INLINE __m128i _mm_unpacklo_epi64(__m128i a, __m128i b) +{ + int64x1_t a_l = vget_low_s64(vreinterpretq_s64_m128i(a)); + int64x1_t b_l = vget_low_s64(vreinterpretq_s64_m128i(b)); + return vreinterpretq_m128i_s64(vcombine_s64(a_l, b_l)); +} + +// Interleaves the lower 8 signed or unsigned 8-bit integers in a with the lower +// 8 signed or unsigned 8-bit integers in b. +// +// r0 := a0 +// r1 := b0 +// r2 := a1 +// r3 := b1 +// ... +// r14 := a7 +// r15 := b7 +// +// https://msdn.microsoft.com/en-us/library/xf7k860c%28v=vs.90%29.aspx +FORCE_INLINE __m128i _mm_unpacklo_epi8(__m128i a, __m128i b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128i_s8( + vzip1q_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); +#else + int8x8_t a1 = vreinterpret_s8_s16(vget_low_s16(vreinterpretq_s16_m128i(a))); + int8x8_t b1 = vreinterpret_s8_s16(vget_low_s16(vreinterpretq_s16_m128i(b))); + int8x8x2_t result = vzip_s8(a1, b1); + return vreinterpretq_m128i_s8(vcombine_s8(result.val[0], result.val[1])); +#endif +} + +// Unpack and interleave double-precision (64-bit) floating-point elements from +// the low half of a and b, and store the results in dst. +// +// DEFINE INTERLEAVE_QWORDS(src1[127:0], src2[127:0]) { +// dst[63:0] := src1[63:0] +// dst[127:64] := src2[63:0] +// RETURN dst[127:0] +// } +// dst[127:0] := INTERLEAVE_QWORDS(a[127:0], b[127:0]) +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_unpacklo_pd +FORCE_INLINE __m128d _mm_unpacklo_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vzip1q_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + return vreinterpretq_m128d_s64( + vcombine_s64(vget_low_s64(vreinterpretq_s64_m128d(a)), + vget_low_s64(vreinterpretq_s64_m128d(b)))); +#endif +} + +// Compute the bitwise XOR of packed double-precision (64-bit) floating-point +// elements in a and b, and store the results in dst. +// +// FOR j := 0 to 1 +// i := j*64 +// dst[i+63:i] := a[i+63:i] XOR b[i+63:i] +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_xor_pd +FORCE_INLINE __m128d _mm_xor_pd(__m128d a, __m128d b) +{ + return vreinterpretq_m128d_s64( + veorq_s64(vreinterpretq_s64_m128d(a), vreinterpretq_s64_m128d(b))); +} + +// Computes the bitwise XOR of the 128-bit value in a and the 128-bit value in +// b. https://msdn.microsoft.com/en-us/library/fzt08www(v=vs.100).aspx +FORCE_INLINE __m128i _mm_xor_si128(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + veorq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +/* SSE3 */ + +// Alternatively add and subtract packed double-precision (64-bit) +// floating-point elements in a to/from packed elements in b, and store the +// results in dst. +// +// FOR j := 0 to 1 +// i := j*64 +// IF ((j & 1) == 0) +// dst[i+63:i] := a[i+63:i] - b[i+63:i] +// ELSE +// dst[i+63:i] := a[i+63:i] + b[i+63:i] +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_addsub_pd +FORCE_INLINE __m128d _mm_addsub_pd(__m128d a, __m128d b) +{ + _sse2neon_const __m128d mask = _mm_set_pd(1.0f, -1.0f); +#if defined(__aarch64__) + return vreinterpretq_m128d_f64(vfmaq_f64(vreinterpretq_f64_m128d(a), + vreinterpretq_f64_m128d(b), + vreinterpretq_f64_m128d(mask))); +#else + return _mm_add_pd(_mm_mul_pd(b, mask), a); +#endif +} + +// Alternatively add and subtract packed single-precision (32-bit) +// floating-point elements in a to/from packed elements in b, and store the +// results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=addsub_ps +FORCE_INLINE __m128 _mm_addsub_ps(__m128 a, __m128 b) +{ + _sse2neon_const __m128 mask = _mm_setr_ps(-1.0f, 1.0f, -1.0f, 1.0f); +#if defined(__aarch64__) || defined(__ARM_FEATURE_FMA) /* VFPv4+ */ + return vreinterpretq_m128_f32(vfmaq_f32(vreinterpretq_f32_m128(a), + vreinterpretq_f32_m128(mask), + vreinterpretq_f32_m128(b))); +#else + return _mm_add_ps(_mm_mul_ps(b, mask), a); +#endif +} + +// Horizontally add adjacent pairs of double-precision (64-bit) floating-point +// elements in a and b, and pack the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hadd_pd +FORCE_INLINE __m128d _mm_hadd_pd(__m128d a, __m128d b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vpaddq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); +#else + double *da = (double *) &a; + double *db = (double *) &b; + double c[] = {da[0] + da[1], db[0] + db[1]}; + return vreinterpretq_m128d_u64(vld1q_u64((uint64_t *) c)); +#endif +} + +// Computes pairwise add of each argument as single-precision, floating-point +// values a and b. +// https://msdn.microsoft.com/en-us/library/yd9wecaa.aspx +FORCE_INLINE __m128 _mm_hadd_ps(__m128 a, __m128 b) +{ +#if defined(__aarch64__) + return vreinterpretq_m128_f32( + vpaddq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); +#else + float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a)); + float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(a)); + float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b)); + float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(b)); + return vreinterpretq_m128_f32( + vcombine_f32(vpadd_f32(a10, a32), vpadd_f32(b10, b32))); +#endif +} + +// Horizontally subtract adjacent pairs of double-precision (64-bit) +// floating-point elements in a and b, and pack the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsub_pd +FORCE_INLINE __m128d _mm_hsub_pd(__m128d _a, __m128d _b) +{ +#if defined(__aarch64__) + float64x2_t a = vreinterpretq_f64_m128d(_a); + float64x2_t b = vreinterpretq_f64_m128d(_b); + return vreinterpretq_m128d_f64( + vsubq_f64(vuzp1q_f64(a, b), vuzp2q_f64(a, b))); +#else + double *da = (double *) &_a; + double *db = (double *) &_b; + double c[] = {da[0] - da[1], db[0] - db[1]}; + return vreinterpretq_m128d_u64(vld1q_u64((uint64_t *) c)); +#endif +} + +// Horizontally subtract adjacent pairs of single-precision (32-bit) +// floating-point elements in a and b, and pack the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsub_ps +FORCE_INLINE __m128 _mm_hsub_ps(__m128 _a, __m128 _b) +{ + float32x4_t a = vreinterpretq_f32_m128(_a); + float32x4_t b = vreinterpretq_f32_m128(_b); +#if defined(__aarch64__) + return vreinterpretq_m128_f32( + vsubq_f32(vuzp1q_f32(a, b), vuzp2q_f32(a, b))); +#else + float32x4x2_t c = vuzpq_f32(a, b); + return vreinterpretq_m128_f32(vsubq_f32(c.val[0], c.val[1])); +#endif +} + +// Load 128-bits of integer data from unaligned memory into dst. This intrinsic +// may perform better than _mm_loadu_si128 when the data crosses a cache line +// boundary. +// +// dst[127:0] := MEM[mem_addr+127:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_lddqu_si128 +#define _mm_lddqu_si128 _mm_loadu_si128 + +// Load a double-precision (64-bit) floating-point element from memory into both +// elements of dst. +// +// dst[63:0] := MEM[mem_addr+63:mem_addr] +// dst[127:64] := MEM[mem_addr+63:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loaddup_pd +#define _mm_loaddup_pd _mm_load1_pd + +// Duplicate the low double-precision (64-bit) floating-point element from a, +// and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movedup_pd +FORCE_INLINE __m128d _mm_movedup_pd(__m128d a) +{ +#if defined(__aarch64__) + return vreinterpretq_m128d_f64( + vdupq_laneq_f64(vreinterpretq_f64_m128d(a), 0)); +#else + return vreinterpretq_m128d_u64( + vdupq_n_u64(vgetq_lane_u64(vreinterpretq_u64_m128d(a), 0))); +#endif +} + +// Duplicate odd-indexed single-precision (32-bit) floating-point elements +// from a, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_movehdup_ps +FORCE_INLINE __m128 _mm_movehdup_ps(__m128 a) +{ +#if __has_builtin(__builtin_shufflevector) + return vreinterpretq_m128_f32(__builtin_shufflevector( + vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 1, 1, 3, 3)); +#else + float32_t a1 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 1); + float32_t a3 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 3); + float ALIGN_STRUCT(16) data[4] = {a1, a1, a3, a3}; + return vreinterpretq_m128_f32(vld1q_f32(data)); +#endif +} + +// Duplicate even-indexed single-precision (32-bit) floating-point elements +// from a, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_moveldup_ps +FORCE_INLINE __m128 _mm_moveldup_ps(__m128 a) +{ +#if __has_builtin(__builtin_shufflevector) + return vreinterpretq_m128_f32(__builtin_shufflevector( + vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a), 0, 0, 2, 2)); +#else + float32_t a0 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); + float32_t a2 = vgetq_lane_f32(vreinterpretq_f32_m128(a), 2); + float ALIGN_STRUCT(16) data[4] = {a0, a0, a2, a2}; + return vreinterpretq_m128_f32(vld1q_f32(data)); +#endif +} + +/* SSSE3 */ + +// Compute the absolute value of packed signed 16-bit integers in a, and store +// the unsigned results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// dst[i+15:i] := ABS(a[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_epi16 +FORCE_INLINE __m128i _mm_abs_epi16(__m128i a) +{ + return vreinterpretq_m128i_s16(vabsq_s16(vreinterpretq_s16_m128i(a))); +} + +// Compute the absolute value of packed signed 32-bit integers in a, and store +// the unsigned results in dst. +// +// FOR j := 0 to 3 +// i := j*32 +// dst[i+31:i] := ABS(a[i+31:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_epi32 +FORCE_INLINE __m128i _mm_abs_epi32(__m128i a) +{ + return vreinterpretq_m128i_s32(vabsq_s32(vreinterpretq_s32_m128i(a))); +} + +// Compute the absolute value of packed signed 8-bit integers in a, and store +// the unsigned results in dst. +// +// FOR j := 0 to 15 +// i := j*8 +// dst[i+7:i] := ABS(a[i+7:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_epi8 +FORCE_INLINE __m128i _mm_abs_epi8(__m128i a) +{ + return vreinterpretq_m128i_s8(vabsq_s8(vreinterpretq_s8_m128i(a))); +} + +// Compute the absolute value of packed signed 16-bit integers in a, and store +// the unsigned results in dst. +// +// FOR j := 0 to 3 +// i := j*16 +// dst[i+15:i] := ABS(a[i+15:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_pi16 +FORCE_INLINE __m64 _mm_abs_pi16(__m64 a) +{ + return vreinterpret_m64_s16(vabs_s16(vreinterpret_s16_m64(a))); +} + +// Compute the absolute value of packed signed 32-bit integers in a, and store +// the unsigned results in dst. +// +// FOR j := 0 to 1 +// i := j*32 +// dst[i+31:i] := ABS(a[i+31:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_pi32 +FORCE_INLINE __m64 _mm_abs_pi32(__m64 a) +{ + return vreinterpret_m64_s32(vabs_s32(vreinterpret_s32_m64(a))); +} + +// Compute the absolute value of packed signed 8-bit integers in a, and store +// the unsigned results in dst. +// +// FOR j := 0 to 7 +// i := j*8 +// dst[i+7:i] := ABS(a[i+7:i]) +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_abs_pi8 +FORCE_INLINE __m64 _mm_abs_pi8(__m64 a) +{ + return vreinterpret_m64_s8(vabs_s8(vreinterpret_s8_m64(a))); +} + +// Concatenate 16-byte blocks in a and b into a 32-byte temporary result, shift +// the result right by imm8 bytes, and store the low 16 bytes in dst. +// +// tmp[255:0] := ((a[127:0] << 128)[255:0] OR b[127:0]) >> (imm8*8) +// dst[127:0] := tmp[127:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_alignr_epi8 +FORCE_INLINE __m128i _mm_alignr_epi8(__m128i a, __m128i b, int imm) +{ + if (_sse2neon_unlikely(imm & ~31)) + return _mm_setzero_si128(); + int idx; + uint8x16_t tmp[2]; + if (imm >= 16) { + idx = imm - 16; + tmp[0] = vreinterpretq_u8_m128i(a); + tmp[1] = vdupq_n_u8(0); + } else { + idx = imm; + tmp[0] = vreinterpretq_u8_m128i(b); + tmp[1] = vreinterpretq_u8_m128i(a); + } + return vreinterpretq_m128i_u8(vld1q_u8(((uint8_t const *) tmp) + idx)); +} + +// Concatenate 8-byte blocks in a and b into a 16-byte temporary result, shift +// the result right by imm8 bytes, and store the low 8 bytes in dst. +// +// tmp[127:0] := ((a[63:0] << 64)[127:0] OR b[63:0]) >> (imm8*8) +// dst[63:0] := tmp[63:0] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_alignr_pi8 +#define _mm_alignr_pi8(a, b, imm) \ + __extension__({ \ + __m64 ret; \ + if (_sse2neon_unlikely((imm) >= 16)) { \ + ret = vreinterpret_m64_s8(vdup_n_s8(0)); \ + } else { \ + uint8x8_t tmp_low, tmp_high; \ + if ((imm) >= 8) { \ + const int idx = (imm) -8; \ + tmp_low = vreinterpret_u8_m64(a); \ + tmp_high = vdup_n_u8(0); \ + ret = vreinterpret_m64_u8(vext_u8(tmp_low, tmp_high, idx)); \ + } else { \ + const int idx = (imm); \ + tmp_low = vreinterpret_u8_m64(b); \ + tmp_high = vreinterpret_u8_m64(a); \ + ret = vreinterpret_m64_u8(vext_u8(tmp_low, tmp_high, idx)); \ + } \ + } \ + ret; \ + }) + +// Computes pairwise add of each argument as a 16-bit signed or unsigned integer +// values a and b. +FORCE_INLINE __m128i _mm_hadd_epi16(__m128i _a, __m128i _b) +{ + int16x8_t a = vreinterpretq_s16_m128i(_a); + int16x8_t b = vreinterpretq_s16_m128i(_b); +#if defined(__aarch64__) + return vreinterpretq_m128i_s16(vpaddq_s16(a, b)); +#else + return vreinterpretq_m128i_s16( + vcombine_s16(vpadd_s16(vget_low_s16(a), vget_high_s16(a)), + vpadd_s16(vget_low_s16(b), vget_high_s16(b)))); +#endif +} + +// Computes pairwise add of each argument as a 32-bit signed or unsigned integer +// values a and b. +FORCE_INLINE __m128i _mm_hadd_epi32(__m128i _a, __m128i _b) +{ + int32x4_t a = vreinterpretq_s32_m128i(_a); + int32x4_t b = vreinterpretq_s32_m128i(_b); + return vreinterpretq_m128i_s32( + vcombine_s32(vpadd_s32(vget_low_s32(a), vget_high_s32(a)), + vpadd_s32(vget_low_s32(b), vget_high_s32(b)))); +} + +// Horizontally add adjacent pairs of 16-bit integers in a and b, and pack the +// signed 16-bit results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hadd_pi16 +FORCE_INLINE __m64 _mm_hadd_pi16(__m64 a, __m64 b) +{ + return vreinterpret_m64_s16( + vpadd_s16(vreinterpret_s16_m64(a), vreinterpret_s16_m64(b))); +} + +// Horizontally add adjacent pairs of 32-bit integers in a and b, and pack the +// signed 32-bit results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hadd_pi32 +FORCE_INLINE __m64 _mm_hadd_pi32(__m64 a, __m64 b) +{ + return vreinterpret_m64_s32( + vpadd_s32(vreinterpret_s32_m64(a), vreinterpret_s32_m64(b))); +} + +// Computes saturated pairwise sub of each argument as a 16-bit signed +// integer values a and b. +FORCE_INLINE __m128i _mm_hadds_epi16(__m128i _a, __m128i _b) +{ +#if defined(__aarch64__) + int16x8_t a = vreinterpretq_s16_m128i(_a); + int16x8_t b = vreinterpretq_s16_m128i(_b); + return vreinterpretq_s64_s16( + vqaddq_s16(vuzp1q_s16(a, b), vuzp2q_s16(a, b))); +#else + int32x4_t a = vreinterpretq_s32_m128i(_a); + int32x4_t b = vreinterpretq_s32_m128i(_b); + // Interleave using vshrn/vmovn + // [a0|a2|a4|a6|b0|b2|b4|b6] + // [a1|a3|a5|a7|b1|b3|b5|b7] + int16x8_t ab0246 = vcombine_s16(vmovn_s32(a), vmovn_s32(b)); + int16x8_t ab1357 = vcombine_s16(vshrn_n_s32(a, 16), vshrn_n_s32(b, 16)); + // Saturated add + return vreinterpretq_m128i_s16(vqaddq_s16(ab0246, ab1357)); +#endif +} + +// Horizontally add adjacent pairs of signed 16-bit integers in a and b using +// saturation, and pack the signed 16-bit results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hadds_pi16 +FORCE_INLINE __m64 _mm_hadds_pi16(__m64 _a, __m64 _b) +{ + int16x4_t a = vreinterpret_s16_m64(_a); + int16x4_t b = vreinterpret_s16_m64(_b); +#if defined(__aarch64__) + return vreinterpret_s64_s16(vqadd_s16(vuzp1_s16(a, b), vuzp2_s16(a, b))); +#else + int16x4x2_t res = vuzp_s16(a, b); + return vreinterpret_s64_s16(vqadd_s16(res.val[0], res.val[1])); +#endif +} + +// Horizontally subtract adjacent pairs of 16-bit integers in a and b, and pack +// the signed 16-bit results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsub_epi16 +FORCE_INLINE __m128i _mm_hsub_epi16(__m128i _a, __m128i _b) +{ + int16x8_t a = vreinterpretq_s16_m128i(_a); + int16x8_t b = vreinterpretq_s16_m128i(_b); +#if defined(__aarch64__) + return vreinterpretq_m128i_s16( + vsubq_s16(vuzp1q_s16(a, b), vuzp2q_s16(a, b))); +#else + int16x8x2_t c = vuzpq_s16(a, b); + return vreinterpretq_m128i_s16(vsubq_s16(c.val[0], c.val[1])); +#endif +} + +// Horizontally subtract adjacent pairs of 32-bit integers in a and b, and pack +// the signed 32-bit results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsub_epi32 +FORCE_INLINE __m128i _mm_hsub_epi32(__m128i _a, __m128i _b) +{ + int32x4_t a = vreinterpretq_s32_m128i(_a); + int32x4_t b = vreinterpretq_s32_m128i(_b); +#if defined(__aarch64__) + return vreinterpretq_m128i_s32( + vsubq_s32(vuzp1q_s32(a, b), vuzp2q_s32(a, b))); +#else + int32x4x2_t c = vuzpq_s32(a, b); + return vreinterpretq_m128i_s32(vsubq_s32(c.val[0], c.val[1])); +#endif +} + +// Horizontally subtract adjacent pairs of 16-bit integers in a and b, and pack +// the signed 16-bit results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsub_pi16 +FORCE_INLINE __m64 _mm_hsub_pi16(__m64 _a, __m64 _b) +{ + int16x4_t a = vreinterpret_s16_m64(_a); + int16x4_t b = vreinterpret_s16_m64(_b); +#if defined(__aarch64__) + return vreinterpret_m64_s16(vsub_s16(vuzp1_s16(a, b), vuzp2_s16(a, b))); +#else + int16x4x2_t c = vuzp_s16(a, b); + return vreinterpret_m64_s16(vsub_s16(c.val[0], c.val[1])); +#endif +} + +// Horizontally subtract adjacent pairs of 32-bit integers in a and b, and pack +// the signed 32-bit results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_hsub_pi32 +FORCE_INLINE __m64 _mm_hsub_pi32(__m64 _a, __m64 _b) +{ + int32x2_t a = vreinterpret_s32_m64(_a); + int32x2_t b = vreinterpret_s32_m64(_b); +#if defined(__aarch64__) + return vreinterpret_m64_s32(vsub_s32(vuzp1_s32(a, b), vuzp2_s32(a, b))); +#else + int32x2x2_t c = vuzp_s32(a, b); + return vreinterpret_m64_s32(vsub_s32(c.val[0], c.val[1])); +#endif +} + +// Computes saturated pairwise difference of each argument as a 16-bit signed +// integer values a and b. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsubs_epi16 +FORCE_INLINE __m128i _mm_hsubs_epi16(__m128i _a, __m128i _b) +{ + int16x8_t a = vreinterpretq_s16_m128i(_a); + int16x8_t b = vreinterpretq_s16_m128i(_b); +#if defined(__aarch64__) + return vreinterpretq_m128i_s16( + vqsubq_s16(vuzp1q_s16(a, b), vuzp2q_s16(a, b))); +#else + int16x8x2_t c = vuzpq_s16(a, b); + return vreinterpretq_m128i_s16(vqsubq_s16(c.val[0], c.val[1])); +#endif +} + +// Horizontally subtract adjacent pairs of signed 16-bit integers in a and b +// using saturation, and pack the signed 16-bit results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsubs_pi16 +FORCE_INLINE __m64 _mm_hsubs_pi16(__m64 _a, __m64 _b) +{ + int16x4_t a = vreinterpret_s16_m64(_a); + int16x4_t b = vreinterpret_s16_m64(_b); +#if defined(__aarch64__) + return vreinterpret_m64_s16(vqsub_s16(vuzp1_s16(a, b), vuzp2_s16(a, b))); +#else + int16x4x2_t c = vuzp_s16(a, b); + return vreinterpret_m64_s16(vqsub_s16(c.val[0], c.val[1])); +#endif +} + +// Vertically multiply each unsigned 8-bit integer from a with the corresponding +// signed 8-bit integer from b, producing intermediate signed 16-bit integers. +// Horizontally add adjacent pairs of intermediate signed 16-bit integers, +// and pack the saturated results in dst. +// +// FOR j := 0 to 7 +// i := j*16 +// dst[i+15:i] := Saturate_To_Int16( a[i+15:i+8]*b[i+15:i+8] + +// a[i+7:i]*b[i+7:i] ) +// ENDFOR +FORCE_INLINE __m128i _mm_maddubs_epi16(__m128i _a, __m128i _b) +{ +#if defined(__aarch64__) + uint8x16_t a = vreinterpretq_u8_m128i(_a); + int8x16_t b = vreinterpretq_s8_m128i(_b); + int16x8_t tl = vmulq_s16(vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(a))), + vmovl_s8(vget_low_s8(b))); + int16x8_t th = vmulq_s16(vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(a))), + vmovl_s8(vget_high_s8(b))); + return vreinterpretq_m128i_s16( + vqaddq_s16(vuzp1q_s16(tl, th), vuzp2q_s16(tl, th))); +#else + // This would be much simpler if x86 would choose to zero extend OR sign + // extend, not both. This could probably be optimized better. + uint16x8_t a = vreinterpretq_u16_m128i(_a); + int16x8_t b = vreinterpretq_s16_m128i(_b); + + // Zero extend a + int16x8_t a_odd = vreinterpretq_s16_u16(vshrq_n_u16(a, 8)); + int16x8_t a_even = vreinterpretq_s16_u16(vbicq_u16(a, vdupq_n_u16(0xff00))); + + // Sign extend by shifting left then shifting right. + int16x8_t b_even = vshrq_n_s16(vshlq_n_s16(b, 8), 8); + int16x8_t b_odd = vshrq_n_s16(b, 8); + + // multiply + int16x8_t prod1 = vmulq_s16(a_even, b_even); + int16x8_t prod2 = vmulq_s16(a_odd, b_odd); + + // saturated add + return vreinterpretq_m128i_s16(vqaddq_s16(prod1, prod2)); +#endif +} + +// Vertically multiply each unsigned 8-bit integer from a with the corresponding +// signed 8-bit integer from b, producing intermediate signed 16-bit integers. +// Horizontally add adjacent pairs of intermediate signed 16-bit integers, and +// pack the saturated results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_maddubs_pi16 +FORCE_INLINE __m64 _mm_maddubs_pi16(__m64 _a, __m64 _b) +{ + uint16x4_t a = vreinterpret_u16_m64(_a); + int16x4_t b = vreinterpret_s16_m64(_b); + + // Zero extend a + int16x4_t a_odd = vreinterpret_s16_u16(vshr_n_u16(a, 8)); + int16x4_t a_even = vreinterpret_s16_u16(vand_u16(a, vdup_n_u16(0xff))); + + // Sign extend by shifting left then shifting right. + int16x4_t b_even = vshr_n_s16(vshl_n_s16(b, 8), 8); + int16x4_t b_odd = vshr_n_s16(b, 8); + + // multiply + int16x4_t prod1 = vmul_s16(a_even, b_even); + int16x4_t prod2 = vmul_s16(a_odd, b_odd); + + // saturated add + return vreinterpret_m64_s16(vqadd_s16(prod1, prod2)); +} + +// Multiply packed signed 16-bit integers in a and b, producing intermediate +// signed 32-bit integers. Shift right by 15 bits while rounding up, and store +// the packed 16-bit integers in dst. +// +// r0 := Round(((int32_t)a0 * (int32_t)b0) >> 15) +// r1 := Round(((int32_t)a1 * (int32_t)b1) >> 15) +// r2 := Round(((int32_t)a2 * (int32_t)b2) >> 15) +// ... +// r7 := Round(((int32_t)a7 * (int32_t)b7) >> 15) +FORCE_INLINE __m128i _mm_mulhrs_epi16(__m128i a, __m128i b) +{ + // Has issues due to saturation + // return vreinterpretq_m128i_s16(vqrdmulhq_s16(a, b)); + + // Multiply + int32x4_t mul_lo = vmull_s16(vget_low_s16(vreinterpretq_s16_m128i(a)), + vget_low_s16(vreinterpretq_s16_m128i(b))); + int32x4_t mul_hi = vmull_s16(vget_high_s16(vreinterpretq_s16_m128i(a)), + vget_high_s16(vreinterpretq_s16_m128i(b))); + + // Rounding narrowing shift right + // narrow = (int16_t)((mul + 16384) >> 15); + int16x4_t narrow_lo = vrshrn_n_s32(mul_lo, 15); + int16x4_t narrow_hi = vrshrn_n_s32(mul_hi, 15); + + // Join together + return vreinterpretq_m128i_s16(vcombine_s16(narrow_lo, narrow_hi)); +} + +// Multiply packed signed 16-bit integers in a and b, producing intermediate +// signed 32-bit integers. Truncate each intermediate integer to the 18 most +// significant bits, round by adding 1, and store bits [16:1] to dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mulhrs_pi16 +FORCE_INLINE __m64 _mm_mulhrs_pi16(__m64 a, __m64 b) +{ + int32x4_t mul_extend = + vmull_s16((vreinterpret_s16_m64(a)), (vreinterpret_s16_m64(b))); + + // Rounding narrowing shift right + return vreinterpret_m64_s16(vrshrn_n_s32(mul_extend, 15)); +} + +// Shuffle packed 8-bit integers in a according to shuffle control mask in the +// corresponding 8-bit element of b, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_shuffle_epi8 +FORCE_INLINE __m128i _mm_shuffle_epi8(__m128i a, __m128i b) +{ + int8x16_t tbl = vreinterpretq_s8_m128i(a); // input a + uint8x16_t idx = vreinterpretq_u8_m128i(b); // input b + uint8x16_t idx_masked = + vandq_u8(idx, vdupq_n_u8(0x8F)); // avoid using meaningless bits +#if defined(__aarch64__) + return vreinterpretq_m128i_s8(vqtbl1q_s8(tbl, idx_masked)); +#elif defined(__GNUC__) + int8x16_t ret; + // %e and %f represent the even and odd D registers + // respectively. + __asm__ __volatile__( + "vtbl.8 %e[ret], {%e[tbl], %f[tbl]}, %e[idx]\n" + "vtbl.8 %f[ret], {%e[tbl], %f[tbl]}, %f[idx]\n" + : [ret] "=&w"(ret) + : [tbl] "w"(tbl), [idx] "w"(idx_masked)); + return vreinterpretq_m128i_s8(ret); +#else + // use this line if testing on aarch64 + int8x8x2_t a_split = {vget_low_s8(tbl), vget_high_s8(tbl)}; + return vreinterpretq_m128i_s8( + vcombine_s8(vtbl2_s8(a_split, vget_low_u8(idx_masked)), + vtbl2_s8(a_split, vget_high_u8(idx_masked)))); +#endif +} + +// Shuffle packed 8-bit integers in a according to shuffle control mask in the +// corresponding 8-bit element of b, and store the results in dst. +// +// FOR j := 0 to 7 +// i := j*8 +// IF b[i+7] == 1 +// dst[i+7:i] := 0 +// ELSE +// index[2:0] := b[i+2:i] +// dst[i+7:i] := a[index*8+7:index*8] +// FI +// ENDFOR +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_shuffle_pi8 +FORCE_INLINE __m64 _mm_shuffle_pi8(__m64 a, __m64 b) +{ + const int8x8_t controlMask = + vand_s8(vreinterpret_s8_m64(b), vdup_n_s8((int8_t) (0x1 << 7 | 0x07))); + int8x8_t res = vtbl1_s8(vreinterpret_s8_m64(a), controlMask); + return vreinterpret_m64_s8(res); } // Negate packed 16-bit integers in a when the corresponding signed @@ -3212,6 +7166,45 @@ FORCE_INLINE __m128i _mm_sign_epi32(__m128i _a, __m128i _b) return vreinterpretq_m128i_s32(res); } +// Negate packed 8-bit integers in a when the corresponding signed +// 8-bit integer in b is negative, and store the results in dst. +// Element in dst are zeroed out when the corresponding element +// in b is zero. +// +// for i in 0..15 +// if b[i] < 0 +// r[i] := -a[i] +// else if b[i] == 0 +// r[i] := 0 +// else +// r[i] := a[i] +// fi +// done +FORCE_INLINE __m128i _mm_sign_epi8(__m128i _a, __m128i _b) +{ + int8x16_t a = vreinterpretq_s8_m128i(_a); + int8x16_t b = vreinterpretq_s8_m128i(_b); + + // signed shift right: faster than vclt + // (b < 0) ? 0xFF : 0 + uint8x16_t ltMask = vreinterpretq_u8_s8(vshrq_n_s8(b, 7)); + + // (b == 0) ? 0xFF : 0 +#if defined(__aarch64__) + int8x16_t zeroMask = vreinterpretq_s8_u8(vceqzq_s8(b)); +#else + int8x16_t zeroMask = vreinterpretq_s8_u8(vceqq_s8(b, vdupq_n_s8(0))); +#endif + + // bitwise select either a or negative 'a' (vnegq_s8(a) return negative 'a') + // based on ltMask + int8x16_t masked = vbslq_s8(ltMask, vnegq_s8(a), a); + // res = masked & (~zeroMask) + int8x16_t res = vbicq_s8(masked, zeroMask); + + return vreinterpretq_m128i_s8(res); +} + // Negate packed 16-bit integers in a when the corresponding signed 16-bit // integer in b is negative, and store the results in dst. Element in dst are // zeroed out when the corresponding element in b is zero. @@ -3244,7 +7237,7 @@ FORCE_INLINE __m64 _mm_sign_pi16(__m64 _a, __m64 _b) int16x4_t zeroMask = vreinterpret_s16_u16(vceq_s16(b, vdup_n_s16(0))); #endif - // bitwise select either a or nagative 'a' (vneg_s16(a) return nagative 'a') + // bitwise select either a or negative 'a' (vneg_s16(a) return negative 'a') // based on ltMask int16x4_t masked = vbsl_s16(ltMask, vneg_s16(a), a); // res = masked & (~zeroMask) @@ -3285,7 +7278,7 @@ FORCE_INLINE __m64 _mm_sign_pi32(__m64 _a, __m64 _b) int32x2_t zeroMask = vreinterpret_s32_u32(vceq_s32(b, vdup_n_s32(0))); #endif - // bitwise select either a or nagative 'a' (vneg_s32(a) return nagative 'a') + // bitwise select either a or negative 'a' (vneg_s32(a) return negative 'a') // based on ltMask int32x2_t masked = vbsl_s32(ltMask, vneg_s32(a), a); // res = masked & (~zeroMask) @@ -3326,7 +7319,7 @@ FORCE_INLINE __m64 _mm_sign_pi8(__m64 _a, __m64 _b) int8x8_t zeroMask = vreinterpret_s8_u8(vceq_s8(b, vdup_n_s8(0))); #endif - // bitwise select either a or nagative 'a' (vneg_s8(a) return nagative 'a') + // bitwise select either a or negative 'a' (vneg_s8(a) return negative 'a') // based on ltMask int8x8_t masked = vbsl_s8(ltMask, vneg_s8(a), a); // res = masked & (~zeroMask) @@ -3335,1423 +7328,346 @@ FORCE_INLINE __m64 _mm_sign_pi8(__m64 _a, __m64 _b) return vreinterpret_m64_s8(res); } -// Average packed unsigned 16-bit integers in a and b, and store the results in -// dst. -// -// FOR j := 0 to 3 -// i := j*16 -// dst[i+15:i] := (a[i+15:i] + b[i+15:i] + 1) >> 1 -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_avg_pu16 -FORCE_INLINE __m64 _mm_avg_pu16(__m64 a, __m64 b) -{ - return vreinterpret_m64_u16( - vrhadd_u16(vreinterpret_u16_m64(a), vreinterpret_u16_m64(b))); -} +/* SSE4.1 */ -// Average packed unsigned 8-bit integers in a and b, and store the results in -// dst. +// Blend packed 16-bit integers from a and b using control mask imm8, and store +// the results in dst. // // FOR j := 0 to 7 -// i := j*8 -// dst[i+7:i] := (a[i+7:i] + b[i+7:i] + 1) >> 1 +// i := j*16 +// IF imm8[j] +// dst[i+15:i] := b[i+15:i] +// ELSE +// dst[i+15:i] := a[i+15:i] +// FI // ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_avg_pu8 -FORCE_INLINE __m64 _mm_avg_pu8(__m64 a, __m64 b) +// FORCE_INLINE __m128i _mm_blend_epi16(__m128i a, __m128i b, +// __constrange(0,255) int imm) +#define _mm_blend_epi16(a, b, imm) \ + __extension__({ \ + const uint16_t _mask[8] = {((imm) & (1 << 0)) ? (uint16_t) -1 : 0x0, \ + ((imm) & (1 << 1)) ? (uint16_t) -1 : 0x0, \ + ((imm) & (1 << 2)) ? (uint16_t) -1 : 0x0, \ + ((imm) & (1 << 3)) ? (uint16_t) -1 : 0x0, \ + ((imm) & (1 << 4)) ? (uint16_t) -1 : 0x0, \ + ((imm) & (1 << 5)) ? (uint16_t) -1 : 0x0, \ + ((imm) & (1 << 6)) ? (uint16_t) -1 : 0x0, \ + ((imm) & (1 << 7)) ? (uint16_t) -1 : 0x0}; \ + uint16x8_t _mask_vec = vld1q_u16(_mask); \ + uint16x8_t _a = vreinterpretq_u16_m128i(a); \ + uint16x8_t _b = vreinterpretq_u16_m128i(b); \ + vreinterpretq_m128i_u16(vbslq_u16(_mask_vec, _b, _a)); \ + }) + +// Blend packed double-precision (64-bit) floating-point elements from a and b +// using control mask imm8, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_blend_pd +#define _mm_blend_pd(a, b, imm) \ + __extension__({ \ + const uint64_t _mask[2] = { \ + ((imm) & (1 << 0)) ? ~UINT64_C(0) : UINT64_C(0), \ + ((imm) & (1 << 1)) ? ~UINT64_C(0) : UINT64_C(0)}; \ + uint64x2_t _mask_vec = vld1q_u64(_mask); \ + uint64x2_t _a = vreinterpretq_u64_m128d(a); \ + uint64x2_t _b = vreinterpretq_u64_m128d(b); \ + vreinterpretq_m128d_u64(vbslq_u64(_mask_vec, _b, _a)); \ + }) + +// Blend packed single-precision (32-bit) floating-point elements from a and b +// using mask, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_blend_ps +FORCE_INLINE __m128 _mm_blend_ps(__m128 _a, __m128 _b, const char imm8) { - return vreinterpret_m64_u8( - vrhadd_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))); + const uint32_t ALIGN_STRUCT(16) + data[4] = {((imm8) & (1 << 0)) ? UINT32_MAX : 0, + ((imm8) & (1 << 1)) ? UINT32_MAX : 0, + ((imm8) & (1 << 2)) ? UINT32_MAX : 0, + ((imm8) & (1 << 3)) ? UINT32_MAX : 0}; + uint32x4_t mask = vld1q_u32(data); + float32x4_t a = vreinterpretq_f32_m128(_a); + float32x4_t b = vreinterpretq_f32_m128(_b); + return vreinterpretq_m128_f32(vbslq_f32(mask, b, a)); } -// Average packed unsigned 8-bit integers in a and b, and store the results in +// Blend packed 8-bit integers from a and b using mask, and store the results in // dst. // -// FOR j := 0 to 7 -// i := j*8 -// dst[i+7:i] := (a[i+7:i] + b[i+7:i] + 1) >> 1 -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pavgb -#define _m_pavgb(a, b) _mm_avg_pu8(a, b) - -// Average packed unsigned 16-bit integers in a and b, and store the results in -// dst. -// -// FOR j := 0 to 3 -// i := j*16 -// dst[i+15:i] := (a[i+15:i] + b[i+15:i] + 1) >> 1 -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pavgw -#define _m_pavgw(a, b) _mm_avg_pu16(a, b) - -// Extract a 16-bit integer from a, selected with imm8, and store the result in -// the lower element of dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pextrw -#define _m_pextrw(a, imm) _mm_extract_pi16(a, imm) - -// Copy a to dst, and insert the 16-bit integer i into dst at the location -// specified by imm8. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=m_pinsrw -#define _m_pinsrw(a, i, imm) _mm_insert_pi16(a, i, imm) - -// Compare packed signed 16-bit integers in a and b, and store packed maximum -// values in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pmaxsw -#define _m_pmaxsw(a, b) _mm_max_pi16(a, b) - -// Compare packed unsigned 8-bit integers in a and b, and store packed maximum -// values in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pmaxub -#define _m_pmaxub(a, b) _mm_max_pu8(a, b) - -// Compare packed signed 16-bit integers in a and b, and store packed minimum -// values in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pminsw -#define _m_pminsw(a, b) _mm_min_pi16(a, b) - -// Compare packed unsigned 8-bit integers in a and b, and store packed minimum -// values in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pminub -#define _m_pminub(a, b) _mm_min_pu8(a, b) - -// Create mask from the most significant bit of each 8-bit element in a, and -// store the result in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pmovmskb -#define _m_pmovmskb(a) _mm_movemask_pi8(a) - -// Multiply the packed unsigned 16-bit integers in a and b, producing -// intermediate 32-bit integers, and store the high 16 bits of the intermediate -// integers in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pmulhuw -#define _m_pmulhuw(a, b) _mm_mulhi_pu16(a, b) - -// Compute the absolute differences of packed unsigned 8-bit integers in a and -// b, then horizontally sum each consecutive 8 differences to produce four -// unsigned 16-bit integers, and pack these unsigned 16-bit integers in the low -// 16 bits of dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=m_psadbw -#define _m_psadbw(a, b) _mm_sad_pu8(a, b) - -// Computes the average of the 16 unsigned 8-bit integers in a and the 16 -// unsigned 8-bit integers in b and rounds. -// -// r0 := (a0 + b0) / 2 -// r1 := (a1 + b1) / 2 -// ... -// r15 := (a15 + b15) / 2 -// -// https://msdn.microsoft.com/en-us/library/vstudio/8zwh554a(v%3dvs.90).aspx -FORCE_INLINE __m128i _mm_avg_epu8(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_u8( - vrhaddq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); -} - -// Shift a left by imm8 bytes while shifting in zeros, and store the results in -// dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_bslli_si128 -#define _mm_bslli_si128(a, imm) _mm_slli_si128(a, imm) - -// Shift a right by imm8 bytes while shifting in zeros, and store the results in -// dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_bsrli_si128 -#define _mm_bsrli_si128(a, imm) _mm_srli_si128(a, imm) - -// Computes the average of the 8 unsigned 16-bit integers in a and the 8 -// unsigned 16-bit integers in b and rounds. -// -// r0 := (a0 + b0) / 2 -// r1 := (a1 + b1) / 2 -// ... -// r7 := (a7 + b7) / 2 -// -// https://msdn.microsoft.com/en-us/library/vstudio/y13ca3c8(v=vs.90).aspx -FORCE_INLINE __m128i _mm_avg_epu16(__m128i a, __m128i b) -{ - return (__m128i) vrhaddq_u16(vreinterpretq_u16_m128i(a), - vreinterpretq_u16_m128i(b)); -} - -// Adds the four single-precision, floating-point values of a and b. -// -// r0 := a0 + b0 -// r1 := a1 + b1 -// r2 := a2 + b2 -// r3 := a3 + b3 -// -// https://msdn.microsoft.com/en-us/library/vstudio/c9848chc(v=vs.100).aspx -FORCE_INLINE __m128 _mm_add_ps(__m128 a, __m128 b) -{ - return vreinterpretq_m128_f32( - vaddq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); -} - -// Add packed double-precision (64-bit) floating-point elements in a and b, and -// store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_add_pd -FORCE_INLINE __m128d _mm_add_pd(__m128d a, __m128d b) -{ -#if defined(__aarch64__) - return vreinterpretq_m128d_f64( - vaddq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); -#else - double *da = (double *) &a; - double *db = (double *) &b; - double c[2]; - c[0] = da[0] + db[0]; - c[1] = da[1] + db[1]; - return vld1q_f32((float32_t *) c); -#endif -} - -// Add the lower double-precision (64-bit) floating-point element in a and b, -// store the result in the lower element of dst, and copy the upper element from -// a to the upper element of dst. -// -// dst[63:0] := a[63:0] + b[63:0] -// dst[127:64] := a[127:64] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_add_sd -FORCE_INLINE __m128d _mm_add_sd(__m128d a, __m128d b) -{ -#if defined(__aarch64__) - return _mm_move_sd(a, _mm_add_pd(a, b)); -#else - double *da = (double *) &a; - double *db = (double *) &b; - double c[2]; - c[0] = da[0] + db[0]; - c[1] = da[1]; - return vld1q_f32((float32_t *) c); -#endif -} - -// Add 64-bit integers a and b, and store the result in dst. -// -// dst[63:0] := a[63:0] + b[63:0] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_add_si64 -FORCE_INLINE __m64 _mm_add_si64(__m64 a, __m64 b) -{ - return vreinterpret_m64_s64( - vadd_s64(vreinterpret_s64_m64(a), vreinterpret_s64_m64(b))); -} - -// adds the scalar single-precision floating point values of a and b. -// https://msdn.microsoft.com/en-us/library/be94x2y6(v=vs.100).aspx -FORCE_INLINE __m128 _mm_add_ss(__m128 a, __m128 b) -{ - float32_t b0 = vgetq_lane_f32(vreinterpretq_f32_m128(b), 0); - float32x4_t value = vsetq_lane_f32(b0, vdupq_n_f32(0), 0); - // the upper values in the result must be the remnants of . - return vreinterpretq_m128_f32(vaddq_f32(a, value)); -} - -// Adds the 4 signed or unsigned 64-bit integers in a to the 4 signed or -// unsigned 32-bit integers in b. -// https://msdn.microsoft.com/en-us/library/vstudio/09xs4fkk(v=vs.100).aspx -FORCE_INLINE __m128i _mm_add_epi64(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_s64( - vaddq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b))); -} - -// Adds the 4 signed or unsigned 32-bit integers in a to the 4 signed or -// unsigned 32-bit integers in b. -// -// r0 := a0 + b0 -// r1 := a1 + b1 -// r2 := a2 + b2 -// r3 := a3 + b3 -// -// https://msdn.microsoft.com/en-us/library/vstudio/09xs4fkk(v=vs.100).aspx -FORCE_INLINE __m128i _mm_add_epi32(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_s32( - vaddq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); -} - -// Adds the 8 signed or unsigned 16-bit integers in a to the 8 signed or -// unsigned 16-bit integers in b. -// https://msdn.microsoft.com/en-us/library/fceha5k4(v=vs.100).aspx -FORCE_INLINE __m128i _mm_add_epi16(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_s16( - vaddq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); -} - -// Adds the 16 signed or unsigned 8-bit integers in a to the 16 signed or -// unsigned 8-bit integers in b. -// https://technet.microsoft.com/en-us/subscriptions/yc7tcyzs(v=vs.90) -FORCE_INLINE __m128i _mm_add_epi8(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_s8( - vaddq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); -} - -// Adds the 8 signed 16-bit integers in a to the 8 signed 16-bit integers in b -// and saturates. -// -// r0 := SignedSaturate(a0 + b0) -// r1 := SignedSaturate(a1 + b1) -// ... -// r7 := SignedSaturate(a7 + b7) -// -// https://msdn.microsoft.com/en-us/library/1a306ef8(v=vs.100).aspx -FORCE_INLINE __m128i _mm_adds_epi16(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_s16( - vqaddq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); -} - -// Add packed signed 8-bit integers in a and b using saturation, and store the -// results in dst. -// // FOR j := 0 to 15 -// i := j*8 -// dst[i+7:i] := Saturate8( a[i+7:i] + b[i+7:i] ) +// i := j*8 +// IF mask[i+7] +// dst[i+7:i] := b[i+7:i] +// ELSE +// dst[i+7:i] := a[i+7:i] +// FI // ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_adds_epi8 -FORCE_INLINE __m128i _mm_adds_epi8(__m128i a, __m128i b) +FORCE_INLINE __m128i _mm_blendv_epi8(__m128i _a, __m128i _b, __m128i _mask) { - return vreinterpretq_m128i_s8( - vqaddq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); -} - -// Adds the 16 unsigned 8-bit integers in a to the 16 unsigned 8-bit integers in -// b and saturates.. -// https://msdn.microsoft.com/en-us/library/9hahyddy(v=vs.100).aspx -FORCE_INLINE __m128i _mm_adds_epu8(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_u8( - vqaddq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); -} - -// Multiplies the 8 signed or unsigned 16-bit integers from a by the 8 signed or -// unsigned 16-bit integers from b. -// -// r0 := (a0 * b0)[15:0] -// r1 := (a1 * b1)[15:0] -// ... -// r7 := (a7 * b7)[15:0] -// -// https://msdn.microsoft.com/en-us/library/vstudio/9ks1472s(v=vs.100).aspx -FORCE_INLINE __m128i _mm_mullo_epi16(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_s16( - vmulq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); -} - -// Multiplies the 4 signed or unsigned 32-bit integers from a by the 4 signed or -// unsigned 32-bit integers from b. -// https://msdn.microsoft.com/en-us/library/vstudio/bb531409(v=vs.100).aspx -FORCE_INLINE __m128i _mm_mullo_epi32(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_s32( - vmulq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); -} - -// Multiply the packed unsigned 16-bit integers in a and b, producing -// intermediate 32-bit integers, and store the high 16 bits of the intermediate -// integers in dst. -// -// FOR j := 0 to 3 -// i := j*16 -// tmp[31:0] := a[i+15:i] * b[i+15:i] -// dst[i+15:i] := tmp[31:16] -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_pmulhuw -#define _m_pmulhuw(a, b) _mm_mulhi_pu16(a, b) - -// Multiplies the four single-precision, floating-point values of a and b. -// -// r0 := a0 * b0 -// r1 := a1 * b1 -// r2 := a2 * b2 -// r3 := a3 * b3 -// -// https://msdn.microsoft.com/en-us/library/vstudio/22kbk6t9(v=vs.100).aspx -FORCE_INLINE __m128 _mm_mul_ps(__m128 a, __m128 b) -{ - return vreinterpretq_m128_f32( - vmulq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); -} - -// Multiply packed double-precision (64-bit) floating-point elements in a and b, -// and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mul_pd -FORCE_INLINE __m128d _mm_mul_pd(__m128d a, __m128d b) -{ -#if defined(__aarch64__) - return vreinterpretq_m128d_f64( - vmulq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); -#else - double *da = (double *) &a; - double *db = (double *) &b; - double c[2]; - c[0] = da[0] * db[0]; - c[1] = da[1] * db[1]; - return vld1q_f32((float32_t *) c); -#endif -} - -// Multiply the lower double-precision (64-bit) floating-point element in a and -// b, store the result in the lower element of dst, and copy the upper element -// from a to the upper element of dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_mul_sd -FORCE_INLINE __m128d _mm_mul_sd(__m128d a, __m128d b) -{ - return _mm_move_sd(a, _mm_mul_pd(a, b)); -} - -// Multiply the lower single-precision (32-bit) floating-point element in a and -// b, store the result in the lower element of dst, and copy the upper 3 packed -// elements from a to the upper elements of dst. -// -// dst[31:0] := a[31:0] * b[31:0] -// dst[127:32] := a[127:32] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mul_ss -FORCE_INLINE __m128 _mm_mul_ss(__m128 a, __m128 b) -{ - return _mm_move_ss(a, _mm_mul_ps(a, b)); -} - -// Multiply the low unsigned 32-bit integers from each packed 64-bit element in -// a and b, and store the unsigned 64-bit results in dst. -// -// r0 := (a0 & 0xFFFFFFFF) * (b0 & 0xFFFFFFFF) -// r1 := (a2 & 0xFFFFFFFF) * (b2 & 0xFFFFFFFF) -FORCE_INLINE __m128i _mm_mul_epu32(__m128i a, __m128i b) -{ - // vmull_u32 upcasts instead of masking, so we downcast. - uint32x2_t a_lo = vmovn_u64(vreinterpretq_u64_m128i(a)); - uint32x2_t b_lo = vmovn_u64(vreinterpretq_u64_m128i(b)); - return vreinterpretq_m128i_u64(vmull_u32(a_lo, b_lo)); -} - -// Multiply the low unsigned 32-bit integers from a and b, and store the -// unsigned 64-bit result in dst. -// -// dst[63:0] := a[31:0] * b[31:0] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mul_su32 -FORCE_INLINE __m64 _mm_mul_su32(__m64 a, __m64 b) -{ - return vreinterpret_m64_u64(vget_low_u64( - vmull_u32(vreinterpret_u32_m64(a), vreinterpret_u32_m64(b)))); -} - -// Multiply the low signed 32-bit integers from each packed 64-bit element in -// a and b, and store the signed 64-bit results in dst. -// -// r0 := (int64_t)(int32_t)a0 * (int64_t)(int32_t)b0 -// r1 := (int64_t)(int32_t)a2 * (int64_t)(int32_t)b2 -FORCE_INLINE __m128i _mm_mul_epi32(__m128i a, __m128i b) -{ - // vmull_s32 upcasts instead of masking, so we downcast. - int32x2_t a_lo = vmovn_s64(vreinterpretq_s64_m128i(a)); - int32x2_t b_lo = vmovn_s64(vreinterpretq_s64_m128i(b)); - return vreinterpretq_m128i_s64(vmull_s32(a_lo, b_lo)); -} - -// Multiplies the 8 signed 16-bit integers from a by the 8 signed 16-bit -// integers from b. -// -// r0 := (a0 * b0) + (a1 * b1) -// r1 := (a2 * b2) + (a3 * b3) -// r2 := (a4 * b4) + (a5 * b5) -// r3 := (a6 * b6) + (a7 * b7) -// https://msdn.microsoft.com/en-us/library/yht36sa6(v=vs.90).aspx -FORCE_INLINE __m128i _mm_madd_epi16(__m128i a, __m128i b) -{ - int32x4_t low = vmull_s16(vget_low_s16(vreinterpretq_s16_m128i(a)), - vget_low_s16(vreinterpretq_s16_m128i(b))); - int32x4_t high = vmull_s16(vget_high_s16(vreinterpretq_s16_m128i(a)), - vget_high_s16(vreinterpretq_s16_m128i(b))); - - int32x2_t low_sum = vpadd_s32(vget_low_s32(low), vget_high_s32(low)); - int32x2_t high_sum = vpadd_s32(vget_low_s32(high), vget_high_s32(high)); - - return vreinterpretq_m128i_s32(vcombine_s32(low_sum, high_sum)); -} - -// Conditionally store 8-bit integer elements from a into memory using mask -// (elements are not stored when the highest bit is not set in the corresponding -// element) and a non-temporal memory hint. mem_addr does not need to be aligned -// on any particular boundary. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_maskmoveu_si128 -FORCE_INLINE void _mm_maskmoveu_si128(__m128i a, __m128i mask, char *mem_addr) -{ - int8x16_t shr_mask = vshrq_n_s8(vreinterpretq_s8_m128i(mask), 7); - __m128 b = _mm_load_ps((const float *) mem_addr); - int8x16_t masked = - vbslq_s8(vreinterpretq_u8_s8(shr_mask), vreinterpretq_s8_m128i(a), - vreinterpretq_s8_m128(b)); - vst1q_s8((int8_t *) mem_addr, masked); -} - -// Multiply packed signed 16-bit integers in a and b, producing intermediate -// signed 32-bit integers. Shift right by 15 bits while rounding up, and store -// the packed 16-bit integers in dst. -// -// r0 := Round(((int32_t)a0 * (int32_t)b0) >> 15) -// r1 := Round(((int32_t)a1 * (int32_t)b1) >> 15) -// r2 := Round(((int32_t)a2 * (int32_t)b2) >> 15) -// ... -// r7 := Round(((int32_t)a7 * (int32_t)b7) >> 15) -FORCE_INLINE __m128i _mm_mulhrs_epi16(__m128i a, __m128i b) -{ - // Has issues due to saturation - // return vreinterpretq_m128i_s16(vqrdmulhq_s16(a, b)); - - // Multiply - int32x4_t mul_lo = vmull_s16(vget_low_s16(vreinterpretq_s16_m128i(a)), - vget_low_s16(vreinterpretq_s16_m128i(b))); - int32x4_t mul_hi = vmull_s16(vget_high_s16(vreinterpretq_s16_m128i(a)), - vget_high_s16(vreinterpretq_s16_m128i(b))); - - // Rounding narrowing shift right - // narrow = (int16_t)((mul + 16384) >> 15); - int16x4_t narrow_lo = vrshrn_n_s32(mul_lo, 15); - int16x4_t narrow_hi = vrshrn_n_s32(mul_hi, 15); - - // Join together - return vreinterpretq_m128i_s16(vcombine_s16(narrow_lo, narrow_hi)); -} - -// Vertically multiply each unsigned 8-bit integer from a with the corresponding -// signed 8-bit integer from b, producing intermediate signed 16-bit integers. -// Horizontally add adjacent pairs of intermediate signed 16-bit integers, -// and pack the saturated results in dst. -// -// FOR j := 0 to 7 -// i := j*16 -// dst[i+15:i] := Saturate_To_Int16( a[i+15:i+8]*b[i+15:i+8] + -// a[i+7:i]*b[i+7:i] ) -// ENDFOR -FORCE_INLINE __m128i _mm_maddubs_epi16(__m128i _a, __m128i _b) -{ -#if defined(__aarch64__) + // Use a signed shift right to create a mask with the sign bit + uint8x16_t mask = + vreinterpretq_u8_s8(vshrq_n_s8(vreinterpretq_s8_m128i(_mask), 7)); uint8x16_t a = vreinterpretq_u8_m128i(_a); - int8x16_t b = vreinterpretq_s8_m128i(_b); - int16x8_t tl = vmulq_s16(vreinterpretq_s16_u16(vmovl_u8(vget_low_u8(a))), - vmovl_s8(vget_low_s8(b))); - int16x8_t th = vmulq_s16(vreinterpretq_s16_u16(vmovl_u8(vget_high_u8(a))), - vmovl_s8(vget_high_s8(b))); - return vreinterpretq_m128i_s16( - vqaddq_s16(vuzp1q_s16(tl, th), vuzp2q_s16(tl, th))); + uint8x16_t b = vreinterpretq_u8_m128i(_b); + return vreinterpretq_m128i_u8(vbslq_u8(mask, b, a)); +} + +// Blend packed double-precision (64-bit) floating-point elements from a and b +// using mask, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_blendv_pd +FORCE_INLINE __m128d _mm_blendv_pd(__m128d _a, __m128d _b, __m128d _mask) +{ + uint64x2_t mask = + vreinterpretq_u64_s64(vshrq_n_s64(vreinterpretq_s64_m128d(_mask), 63)); +#if defined(__aarch64__) + float64x2_t a = vreinterpretq_f64_m128d(_a); + float64x2_t b = vreinterpretq_f64_m128d(_b); + return vreinterpretq_m128d_f64(vbslq_f64(mask, b, a)); #else - // This would be much simpler if x86 would choose to zero extend OR sign - // extend, not both. This could probably be optimized better. - uint16x8_t a = vreinterpretq_u16_m128i(_a); - int16x8_t b = vreinterpretq_s16_m128i(_b); - - // Zero extend a - int16x8_t a_odd = vreinterpretq_s16_u16(vshrq_n_u16(a, 8)); - int16x8_t a_even = vreinterpretq_s16_u16(vbicq_u16(a, vdupq_n_u16(0xff00))); - - // Sign extend by shifting left then shifting right. - int16x8_t b_even = vshrq_n_s16(vshlq_n_s16(b, 8), 8); - int16x8_t b_odd = vshrq_n_s16(b, 8); - - // multiply - int16x8_t prod1 = vmulq_s16(a_even, b_even); - int16x8_t prod2 = vmulq_s16(a_odd, b_odd); - - // saturated add - return vreinterpretq_m128i_s16(vqaddq_s16(prod1, prod2)); + uint64x2_t a = vreinterpretq_u64_m128d(_a); + uint64x2_t b = vreinterpretq_u64_m128d(_b); + return vreinterpretq_m128d_u64(vbslq_u64(mask, b, a)); #endif } -// Computes the fused multiple add product of 32-bit floating point numbers. -// -// Return Value -// Multiplies A and B, and adds C to the temporary result before returning it. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_fmadd -FORCE_INLINE __m128 _mm_fmadd_ps(__m128 a, __m128 b, __m128 c) +// Blend packed single-precision (32-bit) floating-point elements from a and b +// using mask, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_blendv_ps +FORCE_INLINE __m128 _mm_blendv_ps(__m128 _a, __m128 _b, __m128 _mask) +{ + // Use a signed shift right to create a mask with the sign bit + uint32x4_t mask = + vreinterpretq_u32_s32(vshrq_n_s32(vreinterpretq_s32_m128(_mask), 31)); + float32x4_t a = vreinterpretq_f32_m128(_a); + float32x4_t b = vreinterpretq_f32_m128(_b); + return vreinterpretq_m128_f32(vbslq_f32(mask, b, a)); +} + +// Round the packed double-precision (64-bit) floating-point elements in a up +// to an integer value, and store the results as packed double-precision +// floating-point elements in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_ceil_pd +FORCE_INLINE __m128d _mm_ceil_pd(__m128d a) { #if defined(__aarch64__) - return vreinterpretq_m128_f32(vfmaq_f32(vreinterpretq_f32_m128(c), - vreinterpretq_f32_m128(b), - vreinterpretq_f32_m128(a))); + return vreinterpretq_m128d_f64(vrndpq_f64(vreinterpretq_f64_m128d(a))); #else - return _mm_add_ps(_mm_mul_ps(a, b), c); + double *f = (double *) &a; + return _mm_set_pd(ceil(f[1]), ceil(f[0])); #endif } -// Alternatively add and subtract packed double-precision (64-bit) -// floating-point elements in a to/from packed elements in b, and store the -// results in dst. -// -// FOR j := 0 to 1 -// i := j*64 -// IF ((j & 1) == 0) -// dst[i+63:i] := a[i+63:i] - b[i+63:i] -// ELSE -// dst[i+63:i] := a[i+63:i] + b[i+63:i] -// FI -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_addsub_pd -FORCE_INLINE __m128d _mm_addsub_pd(__m128d a, __m128d b) +// Round the packed single-precision (32-bit) floating-point elements in a up to +// an integer value, and store the results as packed single-precision +// floating-point elements in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_ceil_ps +FORCE_INLINE __m128 _mm_ceil_ps(__m128 a) { - __m128d mask = _mm_set_pd(1.0f, -1.0f); -#if defined(__aarch64__) - return vreinterpretq_m128d_f64(vfmaq_f64(vreinterpretq_f64_m128d(a), - vreinterpretq_f64_m128d(b), - vreinterpretq_f64_m128d(mask))); +#if defined(__aarch64__) || defined(__ARM_FEATURE_DIRECTED_ROUNDING) + return vreinterpretq_m128_f32(vrndpq_f32(vreinterpretq_f32_m128(a))); #else - return _mm_add_pd(_mm_mul_pd(b, mask), a); + float *f = (float *) &a; + return _mm_set_ps(ceilf(f[3]), ceilf(f[2]), ceilf(f[1]), ceilf(f[0])); #endif } -// Alternatively add and subtract packed single-precision (32-bit) -// floating-point elements in a to/from packed elements in b, and store the -// results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=addsub_ps -FORCE_INLINE __m128 _mm_addsub_ps(__m128 a, __m128 b) +// Round the lower double-precision (64-bit) floating-point element in b up to +// an integer value, store the result as a double-precision floating-point +// element in the lower element of dst, and copy the upper element from a to the +// upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_ceil_sd +FORCE_INLINE __m128d _mm_ceil_sd(__m128d a, __m128d b) { - __m128 mask = {-1.0f, 1.0f, -1.0f, 1.0f}; - return _mm_fmadd_ps(b, mask, a); + return _mm_move_sd(a, _mm_ceil_pd(b)); } -// Horizontally add adjacent pairs of double-precision (64-bit) floating-point -// elements in a and b, and pack the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hadd_pd -FORCE_INLINE __m128d _mm_hadd_pd(__m128d a, __m128d b) -{ -#if defined(__aarch64__) - return vreinterpretq_m128d_f64( - vpaddq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); -#else - double *da = (double *) &a; - double *db = (double *) &b; - double c[] = {da[0] + da[1], db[0] + db[1]}; - return vreinterpretq_m128d_u64(vld1q_u64((uint64_t *) c)); -#endif -} - -// Compute the absolute differences of packed unsigned 8-bit integers in a and -// b, then horizontally sum each consecutive 8 differences to produce two -// unsigned 16-bit integers, and pack these unsigned 16-bit integers in the low -// 16 bits of 64-bit elements in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sad_epu8 -FORCE_INLINE __m128i _mm_sad_epu8(__m128i a, __m128i b) -{ - uint16x8_t t = vpaddlq_u8(vabdq_u8((uint8x16_t) a, (uint8x16_t) b)); - uint16_t r0 = t[0] + t[1] + t[2] + t[3]; - uint16_t r4 = t[4] + t[5] + t[6] + t[7]; - uint16x8_t r = vsetq_lane_u16(r0, vdupq_n_u16(0), 0); - return (__m128i) vsetq_lane_u16(r4, r, 4); -} - -// Compute the absolute differences of packed unsigned 8-bit integers in a and -// b, then horizontally sum each consecutive 8 differences to produce four -// unsigned 16-bit integers, and pack these unsigned 16-bit integers in the low -// 16 bits of dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_sad_pu8 -FORCE_INLINE __m64 _mm_sad_pu8(__m64 a, __m64 b) -{ - uint16x4_t t = - vpaddl_u8(vabd_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))); - uint16_t r0 = t[0] + t[1] + t[2] + t[3]; - return vreinterpret_m64_u16(vset_lane_u16(r0, vdup_n_u16(0), 0)); -} - -// Compute the absolute differences of packed unsigned 8-bit integers in a and -// b, then horizontally sum each consecutive 8 differences to produce four -// unsigned 16-bit integers, and pack these unsigned 16-bit integers in the low -// 16 bits of dst. +// Round the lower single-precision (32-bit) floating-point element in b up to +// an integer value, store the result as a single-precision floating-point +// element in the lower element of dst, and copy the upper 3 packed elements +// from a to the upper elements of dst. // -// FOR j := 0 to 7 -// i := j*8 -// tmp[i+7:i] := ABS(a[i+7:i] - b[i+7:i]) -// ENDFOR -// dst[15:0] := tmp[7:0] + tmp[15:8] + tmp[23:16] + tmp[31:24] + tmp[39:32] + -// tmp[47:40] + tmp[55:48] + tmp[63:56] dst[63:16] := 0 -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_psadbw -#define _m_psadbw(a, b) _mm_sad_pu8(a, b) - -// Divides the four single-precision, floating-point values of a and b. -// -// r0 := a0 / b0 -// r1 := a1 / b1 -// r2 := a2 / b2 -// r3 := a3 / b3 -// -// https://msdn.microsoft.com/en-us/library/edaw8147(v=vs.100).aspx -FORCE_INLINE __m128 _mm_div_ps(__m128 a, __m128 b) -{ -#if defined(__aarch64__) && !SSE2NEON_PRECISE_DIV - return vreinterpretq_m128_f32( - vdivq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); -#else - float32x4_t recip = vrecpeq_f32(vreinterpretq_f32_m128(b)); - recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(b))); -#if SSE2NEON_PRECISE_DIV - // Additional Netwon-Raphson iteration for accuracy - recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(b))); -#endif - return vreinterpretq_m128_f32(vmulq_f32(vreinterpretq_f32_m128(a), recip)); -#endif -} - -// Divides the scalar single-precision floating point value of a by b. -// https://msdn.microsoft.com/en-us/library/4y73xa49(v=vs.100).aspx -FORCE_INLINE __m128 _mm_div_ss(__m128 a, __m128 b) -{ - float32_t value = - vgetq_lane_f32(vreinterpretq_f32_m128(_mm_div_ps(a, b)), 0); - return vreinterpretq_m128_f32( - vsetq_lane_f32(value, vreinterpretq_f32_m128(a), 0)); -} - -// Divide packed double-precision (64-bit) floating-point elements in a by -// packed elements in b, and store the results in dst. -// -// FOR j := 0 to 1 -// i := 64*j -// dst[i+63:i] := a[i+63:i] / b[i+63:i] -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_div_pd -FORCE_INLINE __m128d _mm_div_pd(__m128d a, __m128d b) -{ -#if defined(__aarch64__) - return vreinterpretq_m128d_f64( - vdivq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); -#else - double *da = (double *) &a; - double *db = (double *) &b; - double c[2]; - c[0] = da[0] / db[0]; - c[1] = da[1] / db[1]; - return vld1q_f32((float32_t *) c); -#endif -} - -// Divide the lower double-precision (64-bit) floating-point element in a by the -// lower double-precision (64-bit) floating-point element in b, store the result -// in the lower element of dst, and copy the upper element from a to the upper -// element of dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_div_sd -FORCE_INLINE __m128d _mm_div_sd(__m128d a, __m128d b) -{ -#if defined(__aarch64__) - float64x2_t tmp = - vdivq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b)); - return vreinterpretq_m128d_f64( - vsetq_lane_f64(vgetq_lane_f64(vreinterpretq_f64_m128d(a), 1), tmp, 1)); -#else - return _mm_move_sd(a, _mm_div_pd(a, b)); -#endif -} - -// Compute the approximate reciprocal of packed single-precision (32-bit) -// floating-point elements in a, and store the results in dst. The maximum -// relative error for this approximation is less than 1.5*2^-12. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_rcp_ps -FORCE_INLINE __m128 _mm_rcp_ps(__m128 in) -{ - float32x4_t recip = vrecpeq_f32(vreinterpretq_f32_m128(in)); - recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(in))); -#if SSE2NEON_PRECISE_DIV - // Additional Netwon-Raphson iteration for accuracy - recip = vmulq_f32(recip, vrecpsq_f32(recip, vreinterpretq_f32_m128(in))); -#endif - return vreinterpretq_m128_f32(recip); -} - -// Compute the approximate reciprocal of the lower single-precision (32-bit) -// floating-point element in a, store the result in the lower element of dst, -// and copy the upper 3 packed elements from a to the upper elements of dst. The -// maximum relative error for this approximation is less than 1.5*2^-12. -// -// dst[31:0] := (1.0 / a[31:0]) +// dst[31:0] := CEIL(b[31:0]) // dst[127:32] := a[127:32] // -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_rcp_ss -FORCE_INLINE __m128 _mm_rcp_ss(__m128 a) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_ceil_ss +FORCE_INLINE __m128 _mm_ceil_ss(__m128 a, __m128 b) { - return _mm_move_ss(a, _mm_rcp_ps(a)); + return _mm_move_ss(a, _mm_ceil_ps(b)); } -// Computes the approximations of square roots of the four single-precision, -// floating-point values of a. First computes reciprocal square roots and then -// reciprocals of the four values. -// -// r0 := sqrt(a0) -// r1 := sqrt(a1) -// r2 := sqrt(a2) -// r3 := sqrt(a3) -// -// https://msdn.microsoft.com/en-us/library/vstudio/8z67bwwk(v=vs.100).aspx -FORCE_INLINE __m128 _mm_sqrt_ps(__m128 in) -{ -#if SSE2NEON_PRECISE_SQRT - float32x4_t recip = vrsqrteq_f32(vreinterpretq_f32_m128(in)); - - // Test for vrsqrteq_f32(0) -> positive infinity case. - // Change to zero, so that s * 1/sqrt(s) result is zero too. - const uint32x4_t pos_inf = vdupq_n_u32(0x7F800000); - const uint32x4_t div_by_zero = - vceqq_u32(pos_inf, vreinterpretq_u32_f32(recip)); - recip = vreinterpretq_f32_u32( - vandq_u32(vmvnq_u32(div_by_zero), vreinterpretq_u32_f32(recip))); - - // Additional Netwon-Raphson iteration for accuracy - recip = vmulq_f32( - vrsqrtsq_f32(vmulq_f32(recip, recip), vreinterpretq_f32_m128(in)), - recip); - recip = vmulq_f32( - vrsqrtsq_f32(vmulq_f32(recip, recip), vreinterpretq_f32_m128(in)), - recip); - - // sqrt(s) = s * 1/sqrt(s) - return vreinterpretq_m128_f32(vmulq_f32(vreinterpretq_f32_m128(in), recip)); -#elif defined(__aarch64__) - return vreinterpretq_m128_f32(vsqrtq_f32(vreinterpretq_f32_m128(in))); -#else - float32x4_t recipsq = vrsqrteq_f32(vreinterpretq_f32_m128(in)); - float32x4_t sq = vrecpeq_f32(recipsq); - return vreinterpretq_m128_f32(sq); -#endif -} - -// Computes the approximation of the square root of the scalar single-precision -// floating point value of in. -// https://msdn.microsoft.com/en-us/library/ahfsc22d(v=vs.100).aspx -FORCE_INLINE __m128 _mm_sqrt_ss(__m128 in) -{ - float32_t value = - vgetq_lane_f32(vreinterpretq_f32_m128(_mm_sqrt_ps(in)), 0); - return vreinterpretq_m128_f32( - vsetq_lane_f32(value, vreinterpretq_f32_m128(in), 0)); -} - -// Computes the approximations of the reciprocal square roots of the four -// single-precision floating point values of in. -// The current precision is 1% error. -// https://msdn.microsoft.com/en-us/library/22hfsh53(v=vs.100).aspx -FORCE_INLINE __m128 _mm_rsqrt_ps(__m128 in) -{ - float32x4_t out = vrsqrteq_f32(vreinterpretq_f32_m128(in)); -#if SSE2NEON_PRECISE_SQRT - // Additional Netwon-Raphson iteration for accuracy - out = vmulq_f32( - out, vrsqrtsq_f32(vmulq_f32(vreinterpretq_f32_m128(in), out), out)); - out = vmulq_f32( - out, vrsqrtsq_f32(vmulq_f32(vreinterpretq_f32_m128(in), out), out)); -#endif - return vreinterpretq_m128_f32(out); -} - -// Compute the approximate reciprocal square root of the lower single-precision -// (32-bit) floating-point element in a, store the result in the lower element -// of dst, and copy the upper 3 packed elements from a to the upper elements of -// dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_rsqrt_ss -FORCE_INLINE __m128 _mm_rsqrt_ss(__m128 in) -{ - return vsetq_lane_f32(vgetq_lane_f32(_mm_rsqrt_ps(in), 0), in, 0); -} - -// Compare packed signed 16-bit integers in a and b, and store packed maximum -// values in dst. -// -// FOR j := 0 to 3 -// i := j*16 -// dst[i+15:i] := MAX(a[i+15:i], b[i+15:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pi16 -FORCE_INLINE __m64 _mm_max_pi16(__m64 a, __m64 b) -{ - return vreinterpret_m64_s16( - vmax_s16(vreinterpret_s16_m64(a), vreinterpret_s16_m64(b))); -} - -// Compare packed signed 16-bit integers in a and b, and store packed maximum -// values in dst. -// -// FOR j := 0 to 3 -// i := j*16 -// dst[i+15:i] := MAX(a[i+15:i], b[i+15:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pi16 -#define _m_pmaxsw(a, b) _mm_max_pi16(a, b) - -// Computes the maximums of the four single-precision, floating-point values of -// a and b. -// https://msdn.microsoft.com/en-us/library/vstudio/ff5d607a(v=vs.100).aspx -FORCE_INLINE __m128 _mm_max_ps(__m128 a, __m128 b) -{ -#if SSE2NEON_PRECISE_MINMAX - float32x4_t _a = vreinterpretq_f32_m128(a); - float32x4_t _b = vreinterpretq_f32_m128(b); - return vbslq_f32(vcltq_f32(_b, _a), _a, _b); -#else - return vreinterpretq_m128_f32( - vmaxq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); -#endif -} - -// Compare packed unsigned 8-bit integers in a and b, and store packed maximum -// values in dst. -// -// FOR j := 0 to 7 -// i := j*8 -// dst[i+7:i] := MAX(a[i+7:i], b[i+7:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pu8 -FORCE_INLINE __m64 _mm_max_pu8(__m64 a, __m64 b) -{ - return vreinterpret_m64_u8( - vmax_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))); -} - -// Compare packed unsigned 8-bit integers in a and b, and store packed maximum -// values in dst. -// -// FOR j := 0 to 7 -// i := j*8 -// dst[i+7:i] := MAX(a[i+7:i], b[i+7:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pu8 -#define _m_pmaxub(a, b) _mm_max_pu8(a, b) - -// Compare packed signed 16-bit integers in a and b, and store packed minimum -// values in dst. -// -// FOR j := 0 to 3 -// i := j*16 -// dst[i+15:i] := MIN(a[i+15:i], b[i+15:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pi16 -FORCE_INLINE __m64 _mm_min_pi16(__m64 a, __m64 b) -{ - return vreinterpret_m64_s16( - vmin_s16(vreinterpret_s16_m64(a), vreinterpret_s16_m64(b))); -} - -// Compare packed signed 16-bit integers in a and b, and store packed minimum -// values in dst. -// -// FOR j := 0 to 3 -// i := j*16 -// dst[i+15:i] := MIN(a[i+15:i], b[i+15:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pi16 -#define _m_pminsw(a, b) _mm_min_pi16(a, b) - -// Computes the minima of the four single-precision, floating-point values of a -// and b. -// https://msdn.microsoft.com/en-us/library/vstudio/wh13kadz(v=vs.100).aspx -FORCE_INLINE __m128 _mm_min_ps(__m128 a, __m128 b) -{ -#if SSE2NEON_PRECISE_MINMAX - float32x4_t _a = vreinterpretq_f32_m128(a); - float32x4_t _b = vreinterpretq_f32_m128(b); - return vbslq_f32(vcltq_f32(_a, _b), _a, _b); -#else - return vreinterpretq_m128_f32( - vminq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); -#endif -} - -// Compare packed unsigned 8-bit integers in a and b, and store packed minimum -// values in dst. -// -// FOR j := 0 to 7 -// i := j*8 -// dst[i+7:i] := MIN(a[i+7:i], b[i+7:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pu8 -FORCE_INLINE __m64 _mm_min_pu8(__m64 a, __m64 b) -{ - return vreinterpret_m64_u8( - vmin_u8(vreinterpret_u8_m64(a), vreinterpret_u8_m64(b))); -} - -// Compare packed unsigned 8-bit integers in a and b, and store packed minimum -// values in dst. -// -// FOR j := 0 to 7 -// i := j*8 -// dst[i+7:i] := MIN(a[i+7:i], b[i+7:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pu8 -#define _m_pminub(a, b) _mm_min_pu8(a, b) - -// Computes the maximum of the two lower scalar single-precision floating point -// values of a and b. -// https://msdn.microsoft.com/en-us/library/s6db5esz(v=vs.100).aspx -FORCE_INLINE __m128 _mm_max_ss(__m128 a, __m128 b) -{ - float32_t value = vgetq_lane_f32(_mm_max_ps(a, b), 0); - return vreinterpretq_m128_f32( - vsetq_lane_f32(value, vreinterpretq_f32_m128(a), 0)); -} - -// Computes the minimum of the two lower scalar single-precision floating point -// values of a and b. -// https://msdn.microsoft.com/en-us/library/0a9y7xaa(v=vs.100).aspx -FORCE_INLINE __m128 _mm_min_ss(__m128 a, __m128 b) -{ - float32_t value = vgetq_lane_f32(_mm_min_ps(a, b), 0); - return vreinterpretq_m128_f32( - vsetq_lane_f32(value, vreinterpretq_f32_m128(a), 0)); -} - -// Computes the pairwise maxima of the 16 unsigned 8-bit integers from a and the -// 16 unsigned 8-bit integers from b. -// https://msdn.microsoft.com/en-us/library/st6634za(v=vs.100).aspx -FORCE_INLINE __m128i _mm_max_epu8(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_u8( - vmaxq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); -} - -// Compare packed double-precision (64-bit) floating-point elements in a and b, -// and store packed maximum values in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_pd -FORCE_INLINE __m128d _mm_max_pd(__m128d a, __m128d b) +// Compare packed 64-bit integers in a and b for equality, and store the results +// in dst +FORCE_INLINE __m128i _mm_cmpeq_epi64(__m128i a, __m128i b) { #if defined(__aarch64__) - return vreinterpretq_m128d_f64( - vmaxq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); + return vreinterpretq_m128i_u64( + vceqq_u64(vreinterpretq_u64_m128i(a), vreinterpretq_u64_m128i(b))); #else - uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); - uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); - uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); - uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); - uint64_t d[2]; - d[0] = (*(double *) &a0) > (*(double *) &b0) ? a0 : b0; - d[1] = (*(double *) &a1) > (*(double *) &b1) ? a1 : b1; - - return vreinterpretq_m128d_u64(vld1q_u64(d)); + // ARMv7 lacks vceqq_u64 + // (a == b) -> (a_lo == b_lo) && (a_hi == b_hi) + uint32x4_t cmp = + vceqq_u32(vreinterpretq_u32_m128i(a), vreinterpretq_u32_m128i(b)); + uint32x4_t swapped = vrev64q_u32(cmp); + return vreinterpretq_m128i_u32(vandq_u32(cmp, swapped)); #endif } -// Compare the lower double-precision (64-bit) floating-point elements in a and -// b, store the maximum value in the lower element of dst, and copy the upper -// element from a to the upper element of dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_sd -FORCE_INLINE __m128d _mm_max_sd(__m128d a, __m128d b) -{ -#if defined(__aarch64__) - return _mm_move_sd(a, _mm_max_pd(a, b)); -#else - double *da = (double *) &a; - double *db = (double *) &b; - double c[2] = {fmax(da[0], db[0]), da[1]}; - return vld1q_f32((float32_t *) c); -#endif -} - -// Computes the pairwise minima of the 16 unsigned 8-bit integers from a and the -// 16 unsigned 8-bit integers from b. -// https://msdn.microsoft.com/ko-kr/library/17k8cf58(v=vs.100).aspxx -FORCE_INLINE __m128i _mm_min_epu8(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_u8( - vminq_u8(vreinterpretq_u8_m128i(a), vreinterpretq_u8_m128i(b))); -} - -// Compare packed double-precision (64-bit) floating-point elements in a and b, -// and store packed minimum values in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_pd -FORCE_INLINE __m128d _mm_min_pd(__m128d a, __m128d b) -{ -#if defined(__aarch64__) - return vreinterpretq_m128d_f64( - vminq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); -#else - uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); - uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); - uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); - uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); - uint64_t d[2]; - d[0] = (*(double *) &a0) < (*(double *) &b0) ? a0 : b0; - d[1] = (*(double *) &a1) < (*(double *) &b1) ? a1 : b1; - return vreinterpretq_m128d_u64(vld1q_u64(d)); -#endif -} - -// Compare the lower double-precision (64-bit) floating-point elements in a and -// b, store the minimum value in the lower element of dst, and copy the upper -// element from a to the upper element of dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_sd -FORCE_INLINE __m128d _mm_min_sd(__m128d a, __m128d b) -{ -#if defined(__aarch64__) - return _mm_move_sd(a, _mm_min_pd(a, b)); -#else - double *da = (double *) &a; - double *db = (double *) &b; - double c[2] = {fmin(da[0], db[0]), da[1]}; - return vld1q_f32((float32_t *) c); -#endif -} - -// Computes the pairwise minima of the 8 signed 16-bit integers from a and the 8 -// signed 16-bit integers from b. -// https://msdn.microsoft.com/en-us/library/vstudio/6te997ew(v=vs.100).aspx -FORCE_INLINE __m128i _mm_min_epi16(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_s16( - vminq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); -} - -// Compare packed signed 8-bit integers in a and b, and store packed maximum -// values in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epi8 -FORCE_INLINE __m128i _mm_max_epi8(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_s8( - vmaxq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); -} - -// Compare packed unsigned 16-bit integers in a and b, and store packed maximum -// values in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epu16 -FORCE_INLINE __m128i _mm_max_epu16(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_u16( - vmaxq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); -} - -// Compare packed signed 8-bit integers in a and b, and store packed minimum -// values in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_epi8 -FORCE_INLINE __m128i _mm_min_epi8(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_s8( - vminq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); -} - -// Compare packed unsigned 16-bit integers in a and b, and store packed minimum -// values in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_epu16 -FORCE_INLINE __m128i _mm_min_epu16(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_u16( - vminq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); -} - -// Computes the pairwise maxima of the 8 signed 16-bit integers from a and the 8 -// signed 16-bit integers from b. -// https://msdn.microsoft.com/en-us/LIBRary/3x060h7c(v=vs.100).aspx -FORCE_INLINE __m128i _mm_max_epi16(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_s16( - vmaxq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); -} - -// epi versions of min/max -// Computes the pariwise maximums of the four signed 32-bit integer values of a -// and b. -// -// A 128-bit parameter that can be defined with the following equations: -// r0 := (a0 > b0) ? a0 : b0 -// r1 := (a1 > b1) ? a1 : b1 -// r2 := (a2 > b2) ? a2 : b2 -// r3 := (a3 > b3) ? a3 : b3 -// -// https://msdn.microsoft.com/en-us/library/vstudio/bb514055(v=vs.100).aspx -FORCE_INLINE __m128i _mm_max_epi32(__m128i a, __m128i b) +// Converts the four signed 16-bit integers in the lower 64 bits to four signed +// 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepi16_epi32(__m128i a) { return vreinterpretq_m128i_s32( - vmaxq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); + vmovl_s16(vget_low_s16(vreinterpretq_s16_m128i(a)))); } -// Computes the pariwise minima of the four signed 32-bit integer values of a -// and b. -// -// A 128-bit parameter that can be defined with the following equations: -// r0 := (a0 < b0) ? a0 : b0 -// r1 := (a1 < b1) ? a1 : b1 -// r2 := (a2 < b2) ? a2 : b2 -// r3 := (a3 < b3) ? a3 : b3 -// -// https://msdn.microsoft.com/en-us/library/vstudio/bb531476(v=vs.100).aspx -FORCE_INLINE __m128i _mm_min_epi32(__m128i a, __m128i b) +// Converts the two signed 16-bit integers in the lower 32 bits two signed +// 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepi16_epi64(__m128i a) { - return vreinterpretq_m128i_s32( - vminq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); + int16x8_t s16x8 = vreinterpretq_s16_m128i(a); /* xxxx xxxx xxxx 0B0A */ + int32x4_t s32x4 = vmovl_s16(vget_low_s16(s16x8)); /* 000x 000x 000B 000A */ + int64x2_t s64x2 = vmovl_s32(vget_low_s32(s32x4)); /* 0000 000B 0000 000A */ + return vreinterpretq_m128i_s64(s64x2); } -// Compare packed unsigned 32-bit integers in a and b, and store packed maximum -// values in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epu32 -FORCE_INLINE __m128i _mm_max_epu32(__m128i a, __m128i b) +// Converts the two signed 32-bit integers in the lower 64 bits to two signed +// 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepi32_epi64(__m128i a) +{ + return vreinterpretq_m128i_s64( + vmovl_s32(vget_low_s32(vreinterpretq_s32_m128i(a)))); +} + +// Converts the four unsigned 8-bit integers in the lower 16 bits to four +// unsigned 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepi8_epi16(__m128i a) +{ + int8x16_t s8x16 = vreinterpretq_s8_m128i(a); /* xxxx xxxx xxxx DCBA */ + int16x8_t s16x8 = vmovl_s8(vget_low_s8(s8x16)); /* 0x0x 0x0x 0D0C 0B0A */ + return vreinterpretq_m128i_s16(s16x8); +} + +// Converts the four unsigned 8-bit integers in the lower 32 bits to four +// unsigned 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepi8_epi32(__m128i a) +{ + int8x16_t s8x16 = vreinterpretq_s8_m128i(a); /* xxxx xxxx xxxx DCBA */ + int16x8_t s16x8 = vmovl_s8(vget_low_s8(s8x16)); /* 0x0x 0x0x 0D0C 0B0A */ + int32x4_t s32x4 = vmovl_s16(vget_low_s16(s16x8)); /* 000D 000C 000B 000A */ + return vreinterpretq_m128i_s32(s32x4); +} + +// Converts the two signed 8-bit integers in the lower 32 bits to four +// signed 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepi8_epi64(__m128i a) +{ + int8x16_t s8x16 = vreinterpretq_s8_m128i(a); /* xxxx xxxx xxxx xxBA */ + int16x8_t s16x8 = vmovl_s8(vget_low_s8(s8x16)); /* 0x0x 0x0x 0x0x 0B0A */ + int32x4_t s32x4 = vmovl_s16(vget_low_s16(s16x8)); /* 000x 000x 000B 000A */ + int64x2_t s64x2 = vmovl_s32(vget_low_s32(s32x4)); /* 0000 000B 0000 000A */ + return vreinterpretq_m128i_s64(s64x2); +} + +// Converts the four unsigned 16-bit integers in the lower 64 bits to four +// unsigned 32-bit integers. +FORCE_INLINE __m128i _mm_cvtepu16_epi32(__m128i a) { return vreinterpretq_m128i_u32( - vmaxq_u32(vreinterpretq_u32_m128i(a), vreinterpretq_u32_m128i(b))); + vmovl_u16(vget_low_u16(vreinterpretq_u16_m128i(a)))); } -// Compare packed unsigned 32-bit integers in a and b, and store packed minimum -// values in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epu32 -FORCE_INLINE __m128i _mm_min_epu32(__m128i a, __m128i b) +// Converts the two unsigned 16-bit integers in the lower 32 bits to two +// unsigned 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepu16_epi64(__m128i a) { - return vreinterpretq_m128i_u32( - vminq_u32(vreinterpretq_u32_m128i(a), vreinterpretq_u32_m128i(b))); + uint16x8_t u16x8 = vreinterpretq_u16_m128i(a); /* xxxx xxxx xxxx 0B0A */ + uint32x4_t u32x4 = vmovl_u16(vget_low_u16(u16x8)); /* 000x 000x 000B 000A */ + uint64x2_t u64x2 = vmovl_u32(vget_low_u32(u32x4)); /* 0000 000B 0000 000A */ + return vreinterpretq_m128i_u64(u64x2); } -// Multiply the packed unsigned 16-bit integers in a and b, producing -// intermediate 32-bit integers, and store the high 16 bits of the intermediate -// integers in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mulhi_pu16 -FORCE_INLINE __m64 _mm_mulhi_pu16(__m64 a, __m64 b) +// Converts the two unsigned 32-bit integers in the lower 64 bits to two +// unsigned 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepu32_epi64(__m128i a) { - return vreinterpret_m64_u16(vshrn_n_u32( - vmull_u16(vreinterpret_u16_m64(a), vreinterpret_u16_m64(b)), 16)); + return vreinterpretq_m128i_u64( + vmovl_u32(vget_low_u32(vreinterpretq_u32_m128i(a)))); } -// Multiplies the 8 signed 16-bit integers from a by the 8 signed 16-bit -// integers from b. -// -// r0 := (a0 * b0)[31:16] -// r1 := (a1 * b1)[31:16] -// ... -// r7 := (a7 * b7)[31:16] -// -// https://msdn.microsoft.com/en-us/library/vstudio/59hddw1d(v=vs.100).aspx -FORCE_INLINE __m128i _mm_mulhi_epi16(__m128i a, __m128i b) +// Zero extend packed unsigned 8-bit integers in a to packed 16-bit integers, +// and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtepu8_epi16 +FORCE_INLINE __m128i _mm_cvtepu8_epi16(__m128i a) { - /* FIXME: issue with large values because of result saturation */ - // int16x8_t ret = vqdmulhq_s16(vreinterpretq_s16_m128i(a), - // vreinterpretq_s16_m128i(b)); /* =2*a*b */ return - // vreinterpretq_m128i_s16(vshrq_n_s16(ret, 1)); - int16x4_t a3210 = vget_low_s16(vreinterpretq_s16_m128i(a)); - int16x4_t b3210 = vget_low_s16(vreinterpretq_s16_m128i(b)); - int32x4_t ab3210 = vmull_s16(a3210, b3210); /* 3333222211110000 */ - int16x4_t a7654 = vget_high_s16(vreinterpretq_s16_m128i(a)); - int16x4_t b7654 = vget_high_s16(vreinterpretq_s16_m128i(b)); - int32x4_t ab7654 = vmull_s16(a7654, b7654); /* 7777666655554444 */ - uint16x8x2_t r = - vuzpq_u16(vreinterpretq_u16_s32(ab3210), vreinterpretq_u16_s32(ab7654)); - return vreinterpretq_m128i_u16(r.val[1]); + uint8x16_t u8x16 = vreinterpretq_u8_m128i(a); /* xxxx xxxx HGFE DCBA */ + uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0H0G 0F0E 0D0C 0B0A */ + return vreinterpretq_m128i_u16(u16x8); } -// Multiply the packed unsigned 16-bit integers in a and b, producing -// intermediate 32-bit integers, and store the high 16 bits of the intermediate -// integers in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mulhi_epu16 -FORCE_INLINE __m128i _mm_mulhi_epu16(__m128i a, __m128i b) +// Converts the four unsigned 8-bit integers in the lower 32 bits to four +// unsigned 32-bit integers. +// https://msdn.microsoft.com/en-us/library/bb531467%28v=vs.100%29.aspx +FORCE_INLINE __m128i _mm_cvtepu8_epi32(__m128i a) { - uint16x4_t a3210 = vget_low_u16(vreinterpretq_u16_m128i(a)); - uint16x4_t b3210 = vget_low_u16(vreinterpretq_u16_m128i(b)); - uint32x4_t ab3210 = vmull_u16(a3210, b3210); -#if defined(__aarch64__) - uint32x4_t ab7654 = - vmull_high_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b)); - uint16x8_t r = vuzp2q_u16(vreinterpretq_u16_u32(ab3210), - vreinterpretq_u16_u32(ab7654)); - return vreinterpretq_m128i_u16(r); -#else - uint16x4_t a7654 = vget_high_u16(vreinterpretq_u16_m128i(a)); - uint16x4_t b7654 = vget_high_u16(vreinterpretq_u16_m128i(b)); - uint32x4_t ab7654 = vmull_u16(a7654, b7654); - uint16x8x2_t r = - vuzpq_u16(vreinterpretq_u16_u32(ab3210), vreinterpretq_u16_u32(ab7654)); - return vreinterpretq_m128i_u16(r.val[1]); + uint8x16_t u8x16 = vreinterpretq_u8_m128i(a); /* xxxx xxxx xxxx DCBA */ + uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0x0x 0x0x 0D0C 0B0A */ + uint32x4_t u32x4 = vmovl_u16(vget_low_u16(u16x8)); /* 000D 000C 000B 000A */ + return vreinterpretq_m128i_u32(u32x4); +} + +// Converts the two unsigned 8-bit integers in the lower 16 bits to two +// unsigned 64-bit integers. +FORCE_INLINE __m128i _mm_cvtepu8_epi64(__m128i a) +{ + uint8x16_t u8x16 = vreinterpretq_u8_m128i(a); /* xxxx xxxx xxxx xxBA */ + uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0x0x 0x0x 0x0x 0B0A */ + uint32x4_t u32x4 = vmovl_u16(vget_low_u16(u16x8)); /* 000x 000x 000B 000A */ + uint64x2_t u64x2 = vmovl_u32(vget_low_u32(u32x4)); /* 0000 000B 0000 000A */ + return vreinterpretq_m128i_u64(u64x2); +} + +// Conditionally multiply the packed double-precision (64-bit) floating-point +// elements in a and b using the high 4 bits in imm8, sum the four products, and +// conditionally store the sum in dst using the low 4 bits of imm8. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_dp_pd +FORCE_INLINE __m128d _mm_dp_pd(__m128d a, __m128d b, const int imm) +{ + // Generate mask value from constant immediate bit value + const int64_t bit0Mask = imm & 0x01 ? UINT64_MAX : 0; + const int64_t bit1Mask = imm & 0x02 ? UINT64_MAX : 0; +#if !SSE2NEON_PRECISE_DP + const int64_t bit4Mask = imm & 0x10 ? UINT64_MAX : 0; + const int64_t bit5Mask = imm & 0x20 ? UINT64_MAX : 0; #endif -} - -// Computes pairwise add of each argument as single-precision, floating-point -// values a and b. -// https://msdn.microsoft.com/en-us/library/yd9wecaa.aspx -FORCE_INLINE __m128 _mm_hadd_ps(__m128 a, __m128 b) -{ -#if defined(__aarch64__) - return vreinterpretq_m128_f32( - vpaddq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); + // Conditional multiplication +#if !SSE2NEON_PRECISE_DP + __m128d mul = _mm_mul_pd(a, b); + const __m128d mulMask = + _mm_castsi128_pd(_mm_set_epi64x(bit5Mask, bit4Mask)); + __m128d tmp = _mm_and_pd(mul, mulMask); #else - float32x2_t a10 = vget_low_f32(vreinterpretq_f32_m128(a)); - float32x2_t a32 = vget_high_f32(vreinterpretq_f32_m128(a)); - float32x2_t b10 = vget_low_f32(vreinterpretq_f32_m128(b)); - float32x2_t b32 = vget_high_f32(vreinterpretq_f32_m128(b)); - return vreinterpretq_m128_f32( - vcombine_f32(vpadd_f32(a10, a32), vpadd_f32(b10, b32))); -#endif -} - -// Computes pairwise add of each argument as a 16-bit signed or unsigned integer -// values a and b. -FORCE_INLINE __m128i _mm_hadd_epi16(__m128i _a, __m128i _b) -{ - int16x8_t a = vreinterpretq_s16_m128i(_a); - int16x8_t b = vreinterpretq_s16_m128i(_b); #if defined(__aarch64__) - return vreinterpretq_m128i_s16(vpaddq_s16(a, b)); + double d0 = (imm & 0x10) ? vgetq_lane_f64(vreinterpretq_f64_m128d(a), 0) * + vgetq_lane_f64(vreinterpretq_f64_m128d(b), 0) + : 0; + double d1 = (imm & 0x20) ? vgetq_lane_f64(vreinterpretq_f64_m128d(a), 1) * + vgetq_lane_f64(vreinterpretq_f64_m128d(b), 1) + : 0; #else - return vreinterpretq_m128i_s16( - vcombine_s16(vpadd_s16(vget_low_s16(a), vget_high_s16(a)), - vpadd_s16(vget_low_s16(b), vget_high_s16(b)))); + double d0 = (imm & 0x10) ? ((double *) &a)[0] * ((double *) &b)[0] : 0; + double d1 = (imm & 0x20) ? ((double *) &a)[1] * ((double *) &b)[1] : 0; #endif -} - -// Horizontally subtract adjacent pairs of double-precision (64-bit) -// floating-point elements in a and b, and pack the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsub_pd -FORCE_INLINE __m128d _mm_hsub_pd(__m128d _a, __m128d _b) -{ + __m128d tmp = _mm_set_pd(d1, d0); +#endif + // Sum the products #if defined(__aarch64__) - return vreinterpretq_m128d_f64(vsubq_f64( - vuzp1q_f64(vreinterpretq_f64_m128d(_a), vreinterpretq_f64_m128d(_b)), - vuzp2q_f64(vreinterpretq_f64_m128d(_a), vreinterpretq_f64_m128d(_b)))); + double sum = vpaddd_f64(vreinterpretq_f64_m128d(tmp)); #else - double *da = (double *) &_a; - double *db = (double *) &_b; - double c[] = {da[0] - da[1], db[0] - db[1]}; - return vreinterpretq_m128d_u64(vld1q_u64((uint64_t *) c)); + double sum = *((double *) &tmp) + *(((double *) &tmp) + 1); #endif -} - -// Horizontally substract adjacent pairs of single-precision (32-bit) -// floating-point elements in a and b, and pack the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsub_ps -FORCE_INLINE __m128 _mm_hsub_ps(__m128 _a, __m128 _b) -{ -#if defined(__aarch64__) - return vreinterpretq_m128_f32(vsubq_f32( - vuzp1q_f32(vreinterpretq_f32_m128(_a), vreinterpretq_f32_m128(_b)), - vuzp2q_f32(vreinterpretq_f32_m128(_a), vreinterpretq_f32_m128(_b)))); -#else - float32x4x2_t c = - vuzpq_f32(vreinterpretq_f32_m128(_a), vreinterpretq_f32_m128(_b)); - return vreinterpretq_m128_f32(vsubq_f32(c.val[0], c.val[1])); -#endif -} - -// Horizontally add adjacent pairs of 16-bit integers in a and b, and pack the -// signed 16-bit results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hadd_pi16 -FORCE_INLINE __m64 _mm_hadd_pi16(__m64 a, __m64 b) -{ - return vreinterpret_m64_s16( - vpadd_s16(vreinterpret_s16_m64(a), vreinterpret_s16_m64(b))); -} - -// Horizontally add adjacent pairs of 32-bit integers in a and b, and pack the -// signed 32-bit results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hadd_pi32 -FORCE_INLINE __m64 _mm_hadd_pi32(__m64 a, __m64 b) -{ - return vreinterpret_m64_s32( - vpadd_s32(vreinterpret_s32_m64(a), vreinterpret_s32_m64(b))); -} - -// Computes pairwise difference of each argument as a 16-bit signed or unsigned -// integer values a and b. -FORCE_INLINE __m128i _mm_hsub_epi16(__m128i _a, __m128i _b) -{ - int32x4_t a = vreinterpretq_s32_m128i(_a); - int32x4_t b = vreinterpretq_s32_m128i(_b); - // Interleave using vshrn/vmovn - // [a0|a2|a4|a6|b0|b2|b4|b6] - // [a1|a3|a5|a7|b1|b3|b5|b7] - int16x8_t ab0246 = vcombine_s16(vmovn_s32(a), vmovn_s32(b)); - int16x8_t ab1357 = vcombine_s16(vshrn_n_s32(a, 16), vshrn_n_s32(b, 16)); - // Subtract - return vreinterpretq_m128i_s16(vsubq_s16(ab0246, ab1357)); -} - -// Computes saturated pairwise sub of each argument as a 16-bit signed -// integer values a and b. -FORCE_INLINE __m128i _mm_hadds_epi16(__m128i _a, __m128i _b) -{ -#if defined(__aarch64__) - int16x8_t a = vreinterpretq_s16_m128i(_a); - int16x8_t b = vreinterpretq_s16_m128i(_b); - return vreinterpretq_s64_s16( - vqaddq_s16(vuzp1q_s16(a, b), vuzp2q_s16(a, b))); -#else - int32x4_t a = vreinterpretq_s32_m128i(_a); - int32x4_t b = vreinterpretq_s32_m128i(_b); - // Interleave using vshrn/vmovn - // [a0|a2|a4|a6|b0|b2|b4|b6] - // [a1|a3|a5|a7|b1|b3|b5|b7] - int16x8_t ab0246 = vcombine_s16(vmovn_s32(a), vmovn_s32(b)); - int16x8_t ab1357 = vcombine_s16(vshrn_n_s32(a, 16), vshrn_n_s32(b, 16)); - // Saturated add - return vreinterpretq_m128i_s16(vqaddq_s16(ab0246, ab1357)); -#endif -} - -// Computes saturated pairwise difference of each argument as a 16-bit signed -// integer values a and b. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_hsubs_epi16 -FORCE_INLINE __m128i _mm_hsubs_epi16(__m128i _a, __m128i _b) -{ -#if defined(__aarch64__) - int16x8_t a = vreinterpretq_s16_m128i(_a); - int16x8_t b = vreinterpretq_s16_m128i(_b); - return vreinterpretq_s64_s16( - vqsubq_s16(vuzp1q_s16(a, b), vuzp2q_s16(a, b))); -#else - int32x4_t a = vreinterpretq_s32_m128i(_a); - int32x4_t b = vreinterpretq_s32_m128i(_b); - // Interleave using vshrn/vmovn - // [a0|a2|a4|a6|b0|b2|b4|b6] - // [a1|a3|a5|a7|b1|b3|b5|b7] - int16x8_t ab0246 = vcombine_s16(vmovn_s32(a), vmovn_s32(b)); - int16x8_t ab1357 = vcombine_s16(vshrn_n_s32(a, 16), vshrn_n_s32(b, 16)); - // Saturated subtract - return vreinterpretq_m128i_s16(vqsubq_s16(ab0246, ab1357)); -#endif -} - -// Computes pairwise add of each argument as a 32-bit signed or unsigned integer -// values a and b. -FORCE_INLINE __m128i _mm_hadd_epi32(__m128i _a, __m128i _b) -{ - int32x4_t a = vreinterpretq_s32_m128i(_a); - int32x4_t b = vreinterpretq_s32_m128i(_b); - return vreinterpretq_m128i_s32( - vcombine_s32(vpadd_s32(vget_low_s32(a), vget_high_s32(a)), - vpadd_s32(vget_low_s32(b), vget_high_s32(b)))); -} - -// Computes pairwise difference of each argument as a 32-bit signed or unsigned -// integer values a and b. -FORCE_INLINE __m128i _mm_hsub_epi32(__m128i _a, __m128i _b) -{ - int64x2_t a = vreinterpretq_s64_m128i(_a); - int64x2_t b = vreinterpretq_s64_m128i(_b); - // Interleave using vshrn/vmovn - // [a0|a2|b0|b2] - // [a1|a2|b1|b3] - int32x4_t ab02 = vcombine_s32(vmovn_s64(a), vmovn_s64(b)); - int32x4_t ab13 = vcombine_s32(vshrn_n_s64(a, 32), vshrn_n_s64(b, 32)); - // Subtract - return vreinterpretq_m128i_s32(vsubq_s32(ab02, ab13)); -} - -// Kahan summation for accurate summation of floating-point numbers. -// http://blog.zachbjornson.com/2019/08/11/fast-float-summation.html -FORCE_INLINE void _sse2neon_kadd_f32(float *sum, float *c, float y) -{ - y -= *c; - float t = *sum + y; - *c = (t - *sum) - y; - *sum = t; + // Conditionally store the sum + const __m128d sumMask = + _mm_castsi128_pd(_mm_set_epi64x(bit1Mask, bit0Mask)); + __m128d res = _mm_and_pd(_mm_set_pd1(sum), sumMask); + return res; } // Conditionally multiply the packed single-precision (32-bit) floating-point @@ -4798,1611 +7714,64 @@ FORCE_INLINE __m128 _mm_dp_ps(__m128 a, __m128 b, const int imm) return vreinterpretq_m128_f32(res); } -/* Compare operations */ - -// Compares for less than -// https://msdn.microsoft.com/en-us/library/vstudio/f330yhc8(v=vs.100).aspx -FORCE_INLINE __m128 _mm_cmplt_ps(__m128 a, __m128 b) -{ - return vreinterpretq_m128_u32( - vcltq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); -} - -// Compares for less than -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/fy94wye7(v=vs.100) -FORCE_INLINE __m128 _mm_cmplt_ss(__m128 a, __m128 b) -{ - return _mm_move_ss(a, _mm_cmplt_ps(a, b)); -} - -// Compares for greater than. -// -// r0 := (a0 > b0) ? 0xffffffff : 0x0 -// r1 := (a1 > b1) ? 0xffffffff : 0x0 -// r2 := (a2 > b2) ? 0xffffffff : 0x0 -// r3 := (a3 > b3) ? 0xffffffff : 0x0 -// -// https://msdn.microsoft.com/en-us/library/vstudio/11dy102s(v=vs.100).aspx -FORCE_INLINE __m128 _mm_cmpgt_ps(__m128 a, __m128 b) -{ - return vreinterpretq_m128_u32( - vcgtq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); -} - -// Compares for greater than. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/1xyyyy9e(v=vs.100) -FORCE_INLINE __m128 _mm_cmpgt_ss(__m128 a, __m128 b) -{ - return _mm_move_ss(a, _mm_cmpgt_ps(a, b)); -} - -// Compares for greater than or equal. -// https://msdn.microsoft.com/en-us/library/vstudio/fs813y2t(v=vs.100).aspx -FORCE_INLINE __m128 _mm_cmpge_ps(__m128 a, __m128 b) -{ - return vreinterpretq_m128_u32( - vcgeq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); -} - -// Compares for greater than or equal. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/kesh3ddc(v=vs.100) -FORCE_INLINE __m128 _mm_cmpge_ss(__m128 a, __m128 b) -{ - return _mm_move_ss(a, _mm_cmpge_ps(a, b)); -} - -// Compares for less than or equal. -// -// r0 := (a0 <= b0) ? 0xffffffff : 0x0 -// r1 := (a1 <= b1) ? 0xffffffff : 0x0 -// r2 := (a2 <= b2) ? 0xffffffff : 0x0 -// r3 := (a3 <= b3) ? 0xffffffff : 0x0 -// -// https://msdn.microsoft.com/en-us/library/vstudio/1s75w83z(v=vs.100).aspx -FORCE_INLINE __m128 _mm_cmple_ps(__m128 a, __m128 b) -{ - return vreinterpretq_m128_u32( - vcleq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); -} - -// Compares for less than or equal. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/a7x0hbhw(v=vs.100) -FORCE_INLINE __m128 _mm_cmple_ss(__m128 a, __m128 b) -{ - return _mm_move_ss(a, _mm_cmple_ps(a, b)); -} - -// Compares for equality. -// https://msdn.microsoft.com/en-us/library/vstudio/36aectz5(v=vs.100).aspx -FORCE_INLINE __m128 _mm_cmpeq_ps(__m128 a, __m128 b) -{ - return vreinterpretq_m128_u32( - vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); -} - -// Compares for equality. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/k423z28e(v=vs.100) -FORCE_INLINE __m128 _mm_cmpeq_ss(__m128 a, __m128 b) -{ - return _mm_move_ss(a, _mm_cmpeq_ps(a, b)); -} - -// Compares for inequality. -// https://msdn.microsoft.com/en-us/library/sf44thbx(v=vs.100).aspx -FORCE_INLINE __m128 _mm_cmpneq_ps(__m128 a, __m128 b) -{ - return vreinterpretq_m128_u32(vmvnq_u32( - vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)))); -} - -// Compares for inequality. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/ekya8fh4(v=vs.100) -FORCE_INLINE __m128 _mm_cmpneq_ss(__m128 a, __m128 b) -{ - return _mm_move_ss(a, _mm_cmpneq_ps(a, b)); -} - -// Compares for not greater than or equal. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/wsexys62(v=vs.100) -FORCE_INLINE __m128 _mm_cmpnge_ps(__m128 a, __m128 b) -{ - return _mm_cmplt_ps(a, b); -} - -// Compares for not greater than or equal. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/fk2y80s8(v=vs.100) -FORCE_INLINE __m128 _mm_cmpnge_ss(__m128 a, __m128 b) -{ - return _mm_cmplt_ss(a, b); -} - -// Compares for not greater than. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/d0xh7w0s(v=vs.100) -FORCE_INLINE __m128 _mm_cmpngt_ps(__m128 a, __m128 b) -{ - return _mm_cmple_ps(a, b); -} - -// Compares for not greater than. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/z7x9ydwh(v=vs.100) -FORCE_INLINE __m128 _mm_cmpngt_ss(__m128 a, __m128 b) -{ - return _mm_cmple_ss(a, b); -} - -// Compares for not less than or equal. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/6a330kxw(v=vs.100) -FORCE_INLINE __m128 _mm_cmpnle_ps(__m128 a, __m128 b) -{ - return _mm_cmpgt_ps(a, b); -} - -// Compares for not less than or equal. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/z7x9ydwh(v=vs.100) -FORCE_INLINE __m128 _mm_cmpnle_ss(__m128 a, __m128 b) -{ - return _mm_cmpgt_ss(a, b); -} - -// Compares for not less than. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/4686bbdw(v=vs.100) -FORCE_INLINE __m128 _mm_cmpnlt_ps(__m128 a, __m128 b) -{ - return _mm_cmpge_ps(a, b); -} - -// Compares for not less than. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/56b9z2wf(v=vs.100) -FORCE_INLINE __m128 _mm_cmpnlt_ss(__m128 a, __m128 b) -{ - return _mm_cmpge_ss(a, b); -} - -// Compares the 16 signed or unsigned 8-bit integers in a and the 16 signed or -// unsigned 8-bit integers in b for equality. -// https://msdn.microsoft.com/en-us/library/windows/desktop/bz5xk21a(v=vs.90).aspx -FORCE_INLINE __m128i _mm_cmpeq_epi8(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_u8( - vceqq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); -} - -// Compare packed double-precision (64-bit) floating-point elements in a and b -// for equality, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpeq_pd -FORCE_INLINE __m128d _mm_cmpeq_pd(__m128d a, __m128d b) -{ -#if defined(__aarch64__) - return vreinterpretq_m128d_u64( - vceqq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); -#else - // (a == b) -> (a_lo == b_lo) && (a_hi == b_hi) - uint32x4_t cmp = - vceqq_u32(vreinterpretq_u32_m128d(a), vreinterpretq_u32_m128d(b)); - uint32x4_t swapped = vrev64q_u32(cmp); - return vreinterpretq_m128d_u32(vandq_u32(cmp, swapped)); -#endif -} - -// Compare the lower double-precision (64-bit) floating-point elements in a and -// b for equality, store the result in the lower element of dst, and copy the -// upper element from a to the upper element of dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpeq_sd -FORCE_INLINE __m128d _mm_cmpeq_sd(__m128d a, __m128d b) -{ - return _mm_move_sd(a, _mm_cmpeq_pd(a, b)); -} - -// Compare packed double-precision (64-bit) floating-point elements in a and b -// for greater-than-or-equal, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpge_pd -FORCE_INLINE __m128d _mm_cmpge_pd(__m128d a, __m128d b) -{ -#if defined(__aarch64__) - return vreinterpretq_m128d_u64( - vcgeq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); -#else - uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); - uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); - uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); - uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); - uint64_t d[2]; - d[0] = (*(double *) &a0) >= (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0); - d[1] = (*(double *) &a1) >= (*(double *) &b1) ? ~UINT64_C(0) : UINT64_C(0); - - return vreinterpretq_m128d_u64(vld1q_u64(d)); -#endif -} - -// Compare the lower double-precision (64-bit) floating-point elements in a and -// b for greater-than-or-equal, store the result in the lower element of dst, -// and copy the upper element from a to the upper element of dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpge_sd -FORCE_INLINE __m128d _mm_cmpge_sd(__m128d a, __m128d b) -{ -#if defined(__aarch64__) - return _mm_move_sd(a, _mm_cmpge_pd(a, b)); -#else - // expand "_mm_cmpge_pd()" to reduce unnecessary operations - uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); - uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); - uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); - uint64_t d[2]; - d[0] = (*(double *) &a0) >= (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0); - d[1] = a1; - - return vreinterpretq_m128d_u64(vld1q_u64(d)); -#endif -} - -// Compares the 8 signed or unsigned 16-bit integers in a and the 8 signed or -// unsigned 16-bit integers in b for equality. -// https://msdn.microsoft.com/en-us/library/2ay060te(v=vs.100).aspx -FORCE_INLINE __m128i _mm_cmpeq_epi16(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_u16( - vceqq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); -} - -// Compare packed 32-bit integers in a and b for equality, and store the results -// in dst -FORCE_INLINE __m128i _mm_cmpeq_epi32(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_u32( - vceqq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); -} - -// Compare packed 64-bit integers in a and b for equality, and store the results -// in dst -FORCE_INLINE __m128i _mm_cmpeq_epi64(__m128i a, __m128i b) -{ -#if defined(__aarch64__) - return vreinterpretq_m128i_u64( - vceqq_u64(vreinterpretq_u64_m128i(a), vreinterpretq_u64_m128i(b))); -#else - // ARMv7 lacks vceqq_u64 - // (a == b) -> (a_lo == b_lo) && (a_hi == b_hi) - uint32x4_t cmp = - vceqq_u32(vreinterpretq_u32_m128i(a), vreinterpretq_u32_m128i(b)); - uint32x4_t swapped = vrev64q_u32(cmp); - return vreinterpretq_m128i_u32(vandq_u32(cmp, swapped)); -#endif -} - -// Compares the 16 signed 8-bit integers in a and the 16 signed 8-bit integers -// in b for lesser than. -// https://msdn.microsoft.com/en-us/library/windows/desktop/9s46csht(v=vs.90).aspx -FORCE_INLINE __m128i _mm_cmplt_epi8(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_u8( - vcltq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); -} - -// Compare packed double-precision (64-bit) floating-point elements in a and b -// for less-than, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmplt_pd -FORCE_INLINE __m128d _mm_cmplt_pd(__m128d a, __m128d b) -{ -#if defined(__aarch64__) - return vreinterpretq_m128d_u64( - vcltq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); -#else - uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); - uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); - uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); - uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); - uint64_t d[2]; - d[0] = (*(double *) &a0) < (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0); - d[1] = (*(double *) &a1) < (*(double *) &b1) ? ~UINT64_C(0) : UINT64_C(0); - - return vreinterpretq_m128d_u64(vld1q_u64(d)); -#endif -} - -// Compare the lower double-precision (64-bit) floating-point elements in a and -// b for less-than, store the result in the lower element of dst, and copy the -// upper element from a to the upper element of dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmplt_sd -FORCE_INLINE __m128d _mm_cmplt_sd(__m128d a, __m128d b) -{ -#if defined(__aarch64__) - return _mm_move_sd(a, _mm_cmplt_pd(a, b)); -#else - uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); - uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); - uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); - uint64_t d[2]; - d[0] = (*(double *) &a0) < (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0); - d[1] = a1; - - return vreinterpretq_m128d_u64(vld1q_u64(d)); -#endif -} - -// Compare packed double-precision (64-bit) floating-point elements in a and b -// for not-equal, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpneq_pd -FORCE_INLINE __m128d _mm_cmpneq_pd(__m128d a, __m128d b) -{ -#if defined(__aarch64__) - return vreinterpretq_m128d_s32(vmvnq_s32(vreinterpretq_s32_u64( - vceqq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))))); -#else - // (a == b) -> (a_lo == b_lo) && (a_hi == b_hi) - uint32x4_t cmp = - vceqq_u32(vreinterpretq_u32_m128d(a), vreinterpretq_u32_m128d(b)); - uint32x4_t swapped = vrev64q_u32(cmp); - return vreinterpretq_m128d_u32(vmvnq_u32(vandq_u32(cmp, swapped))); -#endif -} - -// Compare the lower double-precision (64-bit) floating-point elements in a and -// b for not-equal, store the result in the lower element of dst, and copy the -// upper element from a to the upper element of dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpneq_sd -FORCE_INLINE __m128d _mm_cmpneq_sd(__m128d a, __m128d b) -{ - return _mm_move_sd(a, _mm_cmpneq_pd(a, b)); -} - -// Compare packed double-precision (64-bit) floating-point elements in a and b -// for not-greater-than-or-equal, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpnge_pd -FORCE_INLINE __m128d _mm_cmpnge_pd(__m128d a, __m128d b) -{ - return _mm_cmplt_pd(a, b); -} - -// Compare the lower double-precision (64-bit) floating-point elements in a and -// b for not-greater-than-or-equal, store the result in the lower element of -// dst, and copy the upper element from a to the upper element of dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpnge_sd -FORCE_INLINE __m128d _mm_cmpnge_sd(__m128d a, __m128d b) -{ - return _mm_cmplt_sd(a, b); -} - -// Compare the lower double-precision (64-bit) floating-point element in a and b -// for equality, and return the boolean result (0 or 1). -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_comieq_sd -FORCE_INLINE int _mm_comieq_sd(__m128d a, __m128d b) -{ -#if defined(__aarch64__) - return !!vgetq_lane_u64(vceqq_f64(a, b), 0); -#else - uint32x4_t a_not_nan = - vceqq_u32(vreinterpretq_u32_m128d(a), vreinterpretq_u32_m128d(a)); - uint32x4_t b_not_nan = - vceqq_u32(vreinterpretq_u32_m128d(b), vreinterpretq_u32_m128d(b)); - uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); - uint32x4_t a_eq_b = - vceqq_u32(vreinterpretq_u32_m128d(a), vreinterpretq_u32_m128d(b)); - uint64x2_t and_results = vandq_u64(vreinterpretq_u64_u32(a_and_b_not_nan), - vreinterpretq_u64_u32(a_eq_b)); - return !!vgetq_lane_u64(and_results, 0); -#endif -} - -// Compares the 16 signed 8-bit integers in a and the 16 signed 8-bit integers -// in b for greater than. -// -// r0 := (a0 > b0) ? 0xff : 0x0 -// r1 := (a1 > b1) ? 0xff : 0x0 -// ... -// r15 := (a15 > b15) ? 0xff : 0x0 -// -// https://msdn.microsoft.com/zh-tw/library/wf45zt2b(v=vs.100).aspx -FORCE_INLINE __m128i _mm_cmpgt_epi8(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_u8( - vcgtq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); -} - -// Compare packed double-precision (64-bit) floating-point elements in a and b -// for greater-than, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpgt_pd -FORCE_INLINE __m128d _mm_cmpgt_pd(__m128d a, __m128d b) -{ -#if defined(__aarch64__) - return vreinterpretq_m128d_u64( - vcgtq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); -#else - uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); - uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); - uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); - uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); - uint64_t d[2]; - d[0] = (*(double *) &a0) > (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0); - d[1] = (*(double *) &a1) > (*(double *) &b1) ? ~UINT64_C(0) : UINT64_C(0); - - return vreinterpretq_m128d_u64(vld1q_u64(d)); -#endif -} - -// Compare the lower double-precision (64-bit) floating-point elements in a and -// b for greater-than, store the result in the lower element of dst, and copy -// the upper element from a to the upper element of dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmpgt_sd -FORCE_INLINE __m128d _mm_cmpgt_sd(__m128d a, __m128d b) -{ -#if defined(__aarch64__) - return _mm_move_sd(a, _mm_cmpgt_pd(a, b)); -#else - // expand "_mm_cmpge_pd()" to reduce unnecessary operations - uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); - uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); - uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); - uint64_t d[2]; - d[0] = (*(double *) &a0) > (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0); - d[1] = a1; - - return vreinterpretq_m128d_u64(vld1q_u64(d)); -#endif -} - -// Compare packed double-precision (64-bit) floating-point elements in a and b -// for less-than-or-equal, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmple_pd -FORCE_INLINE __m128d _mm_cmple_pd(__m128d a, __m128d b) -{ -#if defined(__aarch64__) - return vreinterpretq_m128d_u64( - vcleq_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); -#else - uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); - uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); - uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); - uint64_t b1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(b)); - uint64_t d[2]; - d[0] = (*(double *) &a0) <= (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0); - d[1] = (*(double *) &a1) <= (*(double *) &b1) ? ~UINT64_C(0) : UINT64_C(0); - - return vreinterpretq_m128d_u64(vld1q_u64(d)); -#endif -} - -// Compare the lower double-precision (64-bit) floating-point elements in a and -// b for less-than-or-equal, store the result in the lower element of dst, and -// copy the upper element from a to the upper element of dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cmple_sd -FORCE_INLINE __m128d _mm_cmple_sd(__m128d a, __m128d b) -{ -#if defined(__aarch64__) - return _mm_move_sd(a, _mm_cmple_pd(a, b)); -#else - // expand "_mm_cmpge_pd()" to reduce unnecessary operations - uint64_t a0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(a)); - uint64_t a1 = (uint64_t) vget_high_u64(vreinterpretq_u64_m128d(a)); - uint64_t b0 = (uint64_t) vget_low_u64(vreinterpretq_u64_m128d(b)); - uint64_t d[2]; - d[0] = (*(double *) &a0) <= (*(double *) &b0) ? ~UINT64_C(0) : UINT64_C(0); - d[1] = a1; - - return vreinterpretq_m128d_u64(vld1q_u64(d)); -#endif -} - -// Compares the 8 signed 16-bit integers in a and the 8 signed 16-bit integers -// in b for less than. -// -// r0 := (a0 < b0) ? 0xffff : 0x0 -// r1 := (a1 < b1) ? 0xffff : 0x0 -// ... -// r7 := (a7 < b7) ? 0xffff : 0x0 -// -// https://technet.microsoft.com/en-us/library/t863edb2(v=vs.100).aspx -FORCE_INLINE __m128i _mm_cmplt_epi16(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_u16( - vcltq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); -} - -// Compares the 8 signed 16-bit integers in a and the 8 signed 16-bit integers -// in b for greater than. -// -// r0 := (a0 > b0) ? 0xffff : 0x0 -// r1 := (a1 > b1) ? 0xffff : 0x0 -// ... -// r7 := (a7 > b7) ? 0xffff : 0x0 -// -// https://technet.microsoft.com/en-us/library/xd43yfsa(v=vs.100).aspx -FORCE_INLINE __m128i _mm_cmpgt_epi16(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_u16( - vcgtq_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); -} - - -// Compares the 4 signed 32-bit integers in a and the 4 signed 32-bit integers -// in b for less than. -// https://msdn.microsoft.com/en-us/library/vstudio/4ak0bf5d(v=vs.100).aspx -FORCE_INLINE __m128i _mm_cmplt_epi32(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_u32( - vcltq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); -} - -// Compares the 4 signed 32-bit integers in a and the 4 signed 32-bit integers -// in b for greater than. -// https://msdn.microsoft.com/en-us/library/vstudio/1s9f2z0y(v=vs.100).aspx -FORCE_INLINE __m128i _mm_cmpgt_epi32(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_u32( - vcgtq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); -} - -// Compares the 2 signed 64-bit integers in a and the 2 signed 64-bit integers -// in b for greater than. -FORCE_INLINE __m128i _mm_cmpgt_epi64(__m128i a, __m128i b) -{ -#if defined(__aarch64__) - return vreinterpretq_m128i_u64( - vcgtq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b))); -#else - return vreinterpretq_m128i_s64(vshrq_n_s64( - vqsubq_s64(vreinterpretq_s64_m128i(b), vreinterpretq_s64_m128i(a)), - 63)); -#endif -} - -// Compares the four 32-bit floats in a and b to check if any values are NaN. -// Ordered compare between each value returns true for "orderable" and false for -// "not orderable" (NaN). -// https://msdn.microsoft.com/en-us/library/vstudio/0h9w00fx(v=vs.100).aspx see -// also: -// http://stackoverflow.com/questions/8627331/what-does-ordered-unordered-comparison-mean -// http://stackoverflow.com/questions/29349621/neon-isnanval-intrinsics -FORCE_INLINE __m128 _mm_cmpord_ps(__m128 a, __m128 b) -{ - // Note: NEON does not have ordered compare builtin - // Need to compare a eq a and b eq b to check for NaN - // Do AND of results to get final - uint32x4_t ceqaa = - vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); - uint32x4_t ceqbb = - vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); - return vreinterpretq_m128_u32(vandq_u32(ceqaa, ceqbb)); -} - -// Compares for ordered. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/343t62da(v=vs.100) -FORCE_INLINE __m128 _mm_cmpord_ss(__m128 a, __m128 b) -{ - return _mm_move_ss(a, _mm_cmpord_ps(a, b)); -} - -// Compares for unordered. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/khy6fk1t(v=vs.100) -FORCE_INLINE __m128 _mm_cmpunord_ps(__m128 a, __m128 b) -{ - uint32x4_t f32a = - vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); - uint32x4_t f32b = - vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); - return vreinterpretq_m128_u32(vmvnq_u32(vandq_u32(f32a, f32b))); -} - -// Compares for unordered. -// https://docs.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/2as2387b(v=vs.100) -FORCE_INLINE __m128 _mm_cmpunord_ss(__m128 a, __m128 b) -{ - return _mm_move_ss(a, _mm_cmpunord_ps(a, b)); -} - -// Compares the lower single-precision floating point scalar values of a and b -// using a less than operation. : -// https://msdn.microsoft.com/en-us/library/2kwe606b(v=vs.90).aspx Important -// note!! The documentation on MSDN is incorrect! If either of the values is a -// NAN the docs say you will get a one, but in fact, it will return a zero!! -FORCE_INLINE int _mm_comilt_ss(__m128 a, __m128 b) -{ - uint32x4_t a_not_nan = - vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); - uint32x4_t b_not_nan = - vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); - uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); - uint32x4_t a_lt_b = - vcltq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); - return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_lt_b), 0) != 0) ? 1 : 0; -} - -// Compares the lower single-precision floating point scalar values of a and b -// using a greater than operation. : -// https://msdn.microsoft.com/en-us/library/b0738e0t(v=vs.100).aspx -FORCE_INLINE int _mm_comigt_ss(__m128 a, __m128 b) -{ - // return vgetq_lane_u32(vcgtq_f32(vreinterpretq_f32_m128(a), - // vreinterpretq_f32_m128(b)), 0); - uint32x4_t a_not_nan = - vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); - uint32x4_t b_not_nan = - vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); - uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); - uint32x4_t a_gt_b = - vcgtq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); - return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_gt_b), 0) != 0) ? 1 : 0; -} - -// Compares the lower single-precision floating point scalar values of a and b -// using a less than or equal operation. : -// https://msdn.microsoft.com/en-us/library/1w4t7c57(v=vs.90).aspx -FORCE_INLINE int _mm_comile_ss(__m128 a, __m128 b) -{ - // return vgetq_lane_u32(vcleq_f32(vreinterpretq_f32_m128(a), - // vreinterpretq_f32_m128(b)), 0); - uint32x4_t a_not_nan = - vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); - uint32x4_t b_not_nan = - vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); - uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); - uint32x4_t a_le_b = - vcleq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); - return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_le_b), 0) != 0) ? 1 : 0; -} - -// Compares the lower single-precision floating point scalar values of a and b -// using a greater than or equal operation. : -// https://msdn.microsoft.com/en-us/library/8t80des6(v=vs.100).aspx -FORCE_INLINE int _mm_comige_ss(__m128 a, __m128 b) -{ - // return vgetq_lane_u32(vcgeq_f32(vreinterpretq_f32_m128(a), - // vreinterpretq_f32_m128(b)), 0); - uint32x4_t a_not_nan = - vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); - uint32x4_t b_not_nan = - vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); - uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); - uint32x4_t a_ge_b = - vcgeq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); - return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_ge_b), 0) != 0) ? 1 : 0; -} - -// Compares the lower single-precision floating point scalar values of a and b -// using an equality operation. : -// https://msdn.microsoft.com/en-us/library/93yx2h2b(v=vs.100).aspx -FORCE_INLINE int _mm_comieq_ss(__m128 a, __m128 b) -{ - // return vgetq_lane_u32(vceqq_f32(vreinterpretq_f32_m128(a), - // vreinterpretq_f32_m128(b)), 0); - uint32x4_t a_not_nan = - vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); - uint32x4_t b_not_nan = - vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); - uint32x4_t a_and_b_not_nan = vandq_u32(a_not_nan, b_not_nan); - uint32x4_t a_eq_b = - vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b)); - return (vgetq_lane_u32(vandq_u32(a_and_b_not_nan, a_eq_b), 0) != 0) ? 1 : 0; -} - -// Compares the lower single-precision floating point scalar values of a and b -// using an inequality operation. : -// https://msdn.microsoft.com/en-us/library/bafh5e0a(v=vs.90).aspx -FORCE_INLINE int _mm_comineq_ss(__m128 a, __m128 b) -{ - // return !vgetq_lane_u32(vceqq_f32(vreinterpretq_f32_m128(a), - // vreinterpretq_f32_m128(b)), 0); - uint32x4_t a_not_nan = - vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(a)); - uint32x4_t b_not_nan = - vceqq_f32(vreinterpretq_f32_m128(b), vreinterpretq_f32_m128(b)); - uint32x4_t a_or_b_nan = vmvnq_u32(vandq_u32(a_not_nan, b_not_nan)); - uint32x4_t a_neq_b = vmvnq_u32( - vceqq_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); - return (vgetq_lane_u32(vorrq_u32(a_or_b_nan, a_neq_b), 0) != 0) ? 1 : 0; -} - -// according to the documentation, these intrinsics behave the same as the -// non-'u' versions. We'll just alias them here. -#define _mm_ucomieq_ss _mm_comieq_ss -#define _mm_ucomige_ss _mm_comige_ss -#define _mm_ucomigt_ss _mm_comigt_ss -#define _mm_ucomile_ss _mm_comile_ss -#define _mm_ucomilt_ss _mm_comilt_ss -#define _mm_ucomineq_ss _mm_comineq_ss - -/* Conversions */ - -// Convert packed signed 32-bit integers in b to packed single-precision -// (32-bit) floating-point elements, store the results in the lower 2 elements -// of dst, and copy the upper 2 packed elements from a to the upper elements of -// dst. -// -// dst[31:0] := Convert_Int32_To_FP32(b[31:0]) -// dst[63:32] := Convert_Int32_To_FP32(b[63:32]) -// dst[95:64] := a[95:64] -// dst[127:96] := a[127:96] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_pi2ps -FORCE_INLINE __m128 _mm_cvt_pi2ps(__m128 a, __m64 b) -{ - return vreinterpretq_m128_f32( - vcombine_f32(vcvt_f32_s32(vreinterpret_s32_m64(b)), - vget_high_f32(vreinterpretq_f32_m128(a)))); -} - -// Convert the signed 32-bit integer b to a single-precision (32-bit) -// floating-point element, store the result in the lower element of dst, and -// copy the upper 3 packed elements from a to the upper elements of dst. -// -// dst[31:0] := Convert_Int32_To_FP32(b[31:0]) -// dst[127:32] := a[127:32] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_si2ss -FORCE_INLINE __m128 _mm_cvt_si2ss(__m128 a, int b) -{ - return vreinterpretq_m128_f32( - vsetq_lane_f32((float) b, vreinterpretq_f32_m128(a), 0)); -} - -// Convert the signed 32-bit integer b to a single-precision (32-bit) -// floating-point element, store the result in the lower element of dst, and -// copy the upper 3 packed elements from a to the upper elements of dst. -// -// dst[31:0] := Convert_Int32_To_FP32(b[31:0]) -// dst[127:32] := a[127:32] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi32_ss -#define _mm_cvtsi32_ss(a, b) _mm_cvt_si2ss(a, b) - -// Convert the signed 64-bit integer b to a single-precision (32-bit) -// floating-point element, store the result in the lower element of dst, and -// copy the upper 3 packed elements from a to the upper elements of dst. -// -// dst[31:0] := Convert_Int64_To_FP32(b[63:0]) -// dst[127:32] := a[127:32] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi64_ss -FORCE_INLINE __m128 _mm_cvtsi64_ss(__m128 a, int64_t b) -{ - return vreinterpretq_m128_f32( - vsetq_lane_f32((float) b, vreinterpretq_f32_m128(a), 0)); -} - -// Convert the lower single-precision (32-bit) floating-point element in a to a -// 32-bit integer, and store the result in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_ss2si -FORCE_INLINE int _mm_cvt_ss2si(__m128 a) -{ -#if defined(__aarch64__) - return vgetq_lane_s32(vcvtnq_s32_f32(vreinterpretq_f32_m128(a)), 0); -#else - float32_t data = vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); - float32_t diff = data - floor(data); - if (diff > 0.5) - return (int32_t) ceil(data); - if (unlikely(diff == 0.5)) { - int32_t f = (int32_t) floor(data); - int32_t c = (int32_t) ceil(data); - return c & 1 ? f : c; - } - return (int32_t) floor(data); -#endif -} - -// Convert packed 16-bit integers in a to packed single-precision (32-bit) -// floating-point elements, and store the results in dst. -// -// FOR j := 0 to 3 -// i := j*16 -// m := j*32 -// dst[m+31:m] := Convert_Int16_To_FP32(a[i+15:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi16_ps -FORCE_INLINE __m128 _mm_cvtpi16_ps(__m64 a) -{ - return vreinterpretq_m128_f32( - vcvtq_f32_s32(vmovl_s16(vreinterpret_s16_m64(a)))); -} - -// Convert packed 32-bit integers in b to packed single-precision (32-bit) -// floating-point elements, store the results in the lower 2 elements of dst, -// and copy the upper 2 packed elements from a to the upper elements of dst. -// -// dst[31:0] := Convert_Int32_To_FP32(b[31:0]) -// dst[63:32] := Convert_Int32_To_FP32(b[63:32]) -// dst[95:64] := a[95:64] -// dst[127:96] := a[127:96] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi32_ps -FORCE_INLINE __m128 _mm_cvtpi32_ps(__m128 a, __m64 b) -{ - return vreinterpretq_m128_f32( - vcombine_f32(vcvt_f32_s32(vreinterpret_s32_m64(b)), - vget_high_f32(vreinterpretq_f32_m128(a)))); -} - -// Convert packed signed 32-bit integers in a to packed single-precision -// (32-bit) floating-point elements, store the results in the lower 2 elements -// of dst, then covert the packed signed 32-bit integers in b to -// single-precision (32-bit) floating-point element, and store the results in -// the upper 2 elements of dst. -// -// dst[31:0] := Convert_Int32_To_FP32(a[31:0]) -// dst[63:32] := Convert_Int32_To_FP32(a[63:32]) -// dst[95:64] := Convert_Int32_To_FP32(b[31:0]) -// dst[127:96] := Convert_Int32_To_FP32(b[63:32]) -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi32x2_ps -FORCE_INLINE __m128 _mm_cvtpi32x2_ps(__m64 a, __m64 b) -{ - return vreinterpretq_m128_f32(vcvtq_f32_s32( - vcombine_s32(vreinterpret_s32_m64(a), vreinterpret_s32_m64(b)))); -} - -// Convert the lower packed 8-bit integers in a to packed single-precision -// (32-bit) floating-point elements, and store the results in dst. -// -// FOR j := 0 to 3 -// i := j*8 -// m := j*32 -// dst[m+31:m] := Convert_Int8_To_FP32(a[i+7:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi8_ps -FORCE_INLINE __m128 _mm_cvtpi8_ps(__m64 a) -{ - return vreinterpretq_m128_f32(vcvtq_f32_s32( - vmovl_s16(vget_low_s16(vmovl_s8(vreinterpret_s8_m64(a)))))); -} - -// Convert packed unsigned 16-bit integers in a to packed single-precision -// (32-bit) floating-point elements, and store the results in dst. -// -// FOR j := 0 to 3 -// i := j*16 -// m := j*32 -// dst[m+31:m] := Convert_UInt16_To_FP32(a[i+15:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpu16_ps -FORCE_INLINE __m128 _mm_cvtpu16_ps(__m64 a) -{ - return vreinterpretq_m128_f32( - vcvtq_f32_u32(vmovl_u16(vreinterpret_u16_m64(a)))); -} - -// Convert the lower packed unsigned 8-bit integers in a to packed -// single-precision (32-bit) floating-point elements, and store the results in -// dst. -// -// FOR j := 0 to 3 -// i := j*8 -// m := j*32 -// dst[m+31:m] := Convert_UInt8_To_FP32(a[i+7:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpu8_ps -FORCE_INLINE __m128 _mm_cvtpu8_ps(__m64 a) -{ - return vreinterpretq_m128_f32(vcvtq_f32_u32( - vmovl_u16(vget_low_u16(vmovl_u8(vreinterpret_u8_m64(a)))))); -} - -// Converts the four single-precision, floating-point values of a to signed -// 32-bit integer values using truncate. -// https://msdn.microsoft.com/en-us/library/vstudio/1h005y6x(v=vs.100).aspx -FORCE_INLINE __m128i _mm_cvttps_epi32(__m128 a) -{ - return vreinterpretq_m128i_s32(vcvtq_s32_f32(vreinterpretq_f32_m128(a))); -} - -// Convert the lower double-precision (64-bit) floating-point element in a to a -// 64-bit integer with truncation, and store the result in dst. -// -// dst[63:0] := Convert_FP64_To_Int64_Truncate(a[63:0]) -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttsd_si64 -FORCE_INLINE int64_t _mm_cvttsd_si64(__m128d a) -{ -#if defined(__aarch64__) - return vgetq_lane_s64(vcvtq_s64_f64(vreinterpretq_f64_m128d(a)), 0); -#else - double ret = *((double *) &a); - return (int64_t) ret; -#endif -} - -// Convert the lower double-precision (64-bit) floating-point element in a to a -// 64-bit integer with truncation, and store the result in dst. -// -// dst[63:0] := Convert_FP64_To_Int64_Truncate(a[63:0]) -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvttsd_si64x -#define _mm_cvttsd_si64x(a) _mm_cvttsd_si64(a) - -// Converts the four signed 32-bit integer values of a to single-precision, -// floating-point values -// https://msdn.microsoft.com/en-us/library/vstudio/36bwxcx5(v=vs.100).aspx -FORCE_INLINE __m128 _mm_cvtepi32_ps(__m128i a) -{ - return vreinterpretq_m128_f32(vcvtq_f32_s32(vreinterpretq_s32_m128i(a))); -} - -// Convert packed signed 32-bit integers in a to packed double-precision -// (64-bit) floating-point elements, and store the results in dst. -// -// FOR j := 0 to 1 -// i := j*32 -// m := j*64 -// dst[m+63:m] := Convert_Int32_To_FP64(a[i+31:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtepi32_pd -FORCE_INLINE __m128d _mm_cvtepi32_pd(__m128i a) -{ -#if defined(__aarch64__) - return vreinterpretq_m128d_f64( - vcvtq_f64_s64(vmovl_s32(vget_low_s32(vreinterpretq_s32_m128i(a))))); -#else - double a0 = (double) vgetq_lane_s32(vreinterpretq_s32_m128i(a), 0); - double a1 = (double) vgetq_lane_s32(vreinterpretq_s32_m128i(a), 1); - return _mm_set_pd(a1, a0); -#endif -} - -// Convert packed signed 32-bit integers in a to packed double-precision -// (64-bit) floating-point elements, and store the results in dst. -// -// FOR j := 0 to 1 -// i := j*32 -// m := j*64 -// dst[m+63:m] := Convert_Int32_To_FP64(a[i+31:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpi32_pd -FORCE_INLINE __m128d _mm_cvtpi32_pd(__m64 a) -{ -#if defined(__aarch64__) - return vreinterpretq_m128d_f64( - vcvtq_f64_s64(vmovl_s32(vreinterpret_s32_m64(a)))); -#else - double a0 = (double) vget_lane_s32(vreinterpret_s32_m64(a), 0); - double a1 = (double) vget_lane_s32(vreinterpret_s32_m64(a), 1); - return _mm_set_pd(a1, a0); -#endif -} - -// Converts the four unsigned 8-bit integers in the lower 16 bits to four -// unsigned 32-bit integers. -FORCE_INLINE __m128i _mm_cvtepu8_epi16(__m128i a) -{ - uint8x16_t u8x16 = vreinterpretq_u8_m128i(a); /* xxxx xxxx xxxx DCBA */ - uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0x0x 0x0x 0D0C 0B0A */ - return vreinterpretq_m128i_u16(u16x8); -} - -// Converts the four unsigned 8-bit integers in the lower 32 bits to four -// unsigned 32-bit integers. -// https://msdn.microsoft.com/en-us/library/bb531467%28v=vs.100%29.aspx -FORCE_INLINE __m128i _mm_cvtepu8_epi32(__m128i a) -{ - uint8x16_t u8x16 = vreinterpretq_u8_m128i(a); /* xxxx xxxx xxxx DCBA */ - uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0x0x 0x0x 0D0C 0B0A */ - uint32x4_t u32x4 = vmovl_u16(vget_low_u16(u16x8)); /* 000D 000C 000B 000A */ - return vreinterpretq_m128i_u32(u32x4); -} - -// Converts the two unsigned 8-bit integers in the lower 16 bits to two -// unsigned 64-bit integers. -FORCE_INLINE __m128i _mm_cvtepu8_epi64(__m128i a) -{ - uint8x16_t u8x16 = vreinterpretq_u8_m128i(a); /* xxxx xxxx xxxx xxBA */ - uint16x8_t u16x8 = vmovl_u8(vget_low_u8(u8x16)); /* 0x0x 0x0x 0x0x 0B0A */ - uint32x4_t u32x4 = vmovl_u16(vget_low_u16(u16x8)); /* 000x 000x 000B 000A */ - uint64x2_t u64x2 = vmovl_u32(vget_low_u32(u32x4)); /* 0000 000B 0000 000A */ - return vreinterpretq_m128i_u64(u64x2); -} - -// Converts the four unsigned 8-bit integers in the lower 16 bits to four -// unsigned 32-bit integers. -FORCE_INLINE __m128i _mm_cvtepi8_epi16(__m128i a) -{ - int8x16_t s8x16 = vreinterpretq_s8_m128i(a); /* xxxx xxxx xxxx DCBA */ - int16x8_t s16x8 = vmovl_s8(vget_low_s8(s8x16)); /* 0x0x 0x0x 0D0C 0B0A */ - return vreinterpretq_m128i_s16(s16x8); -} - -// Converts the four unsigned 8-bit integers in the lower 32 bits to four -// unsigned 32-bit integers. -FORCE_INLINE __m128i _mm_cvtepi8_epi32(__m128i a) -{ - int8x16_t s8x16 = vreinterpretq_s8_m128i(a); /* xxxx xxxx xxxx DCBA */ - int16x8_t s16x8 = vmovl_s8(vget_low_s8(s8x16)); /* 0x0x 0x0x 0D0C 0B0A */ - int32x4_t s32x4 = vmovl_s16(vget_low_s16(s16x8)); /* 000D 000C 000B 000A */ - return vreinterpretq_m128i_s32(s32x4); -} - -// Converts the two signed 8-bit integers in the lower 32 bits to four -// signed 64-bit integers. -FORCE_INLINE __m128i _mm_cvtepi8_epi64(__m128i a) -{ - int8x16_t s8x16 = vreinterpretq_s8_m128i(a); /* xxxx xxxx xxxx xxBA */ - int16x8_t s16x8 = vmovl_s8(vget_low_s8(s8x16)); /* 0x0x 0x0x 0x0x 0B0A */ - int32x4_t s32x4 = vmovl_s16(vget_low_s16(s16x8)); /* 000x 000x 000B 000A */ - int64x2_t s64x2 = vmovl_s32(vget_low_s32(s32x4)); /* 0000 000B 0000 000A */ - return vreinterpretq_m128i_s64(s64x2); -} - -// Converts the four signed 16-bit integers in the lower 64 bits to four signed -// 32-bit integers. -FORCE_INLINE __m128i _mm_cvtepi16_epi32(__m128i a) -{ - return vreinterpretq_m128i_s32( - vmovl_s16(vget_low_s16(vreinterpretq_s16_m128i(a)))); -} - -// Converts the two signed 16-bit integers in the lower 32 bits two signed -// 32-bit integers. -FORCE_INLINE __m128i _mm_cvtepi16_epi64(__m128i a) -{ - int16x8_t s16x8 = vreinterpretq_s16_m128i(a); /* xxxx xxxx xxxx 0B0A */ - int32x4_t s32x4 = vmovl_s16(vget_low_s16(s16x8)); /* 000x 000x 000B 000A */ - int64x2_t s64x2 = vmovl_s32(vget_low_s32(s32x4)); /* 0000 000B 0000 000A */ - return vreinterpretq_m128i_s64(s64x2); -} - -// Converts the four unsigned 16-bit integers in the lower 64 bits to four -// unsigned 32-bit integers. -FORCE_INLINE __m128i _mm_cvtepu16_epi32(__m128i a) -{ - return vreinterpretq_m128i_u32( - vmovl_u16(vget_low_u16(vreinterpretq_u16_m128i(a)))); -} - -// Converts the two unsigned 16-bit integers in the lower 32 bits to two -// unsigned 64-bit integers. -FORCE_INLINE __m128i _mm_cvtepu16_epi64(__m128i a) -{ - uint16x8_t u16x8 = vreinterpretq_u16_m128i(a); /* xxxx xxxx xxxx 0B0A */ - uint32x4_t u32x4 = vmovl_u16(vget_low_u16(u16x8)); /* 000x 000x 000B 000A */ - uint64x2_t u64x2 = vmovl_u32(vget_low_u32(u32x4)); /* 0000 000B 0000 000A */ - return vreinterpretq_m128i_u64(u64x2); -} - -// Converts the two unsigned 32-bit integers in the lower 64 bits to two -// unsigned 64-bit integers. -FORCE_INLINE __m128i _mm_cvtepu32_epi64(__m128i a) -{ - return vreinterpretq_m128i_u64( - vmovl_u32(vget_low_u32(vreinterpretq_u32_m128i(a)))); -} - -// Converts the two signed 32-bit integers in the lower 64 bits to two signed -// 64-bit integers. -FORCE_INLINE __m128i _mm_cvtepi32_epi64(__m128i a) -{ - return vreinterpretq_m128i_s64( - vmovl_s32(vget_low_s32(vreinterpretq_s32_m128i(a)))); -} - -// Converts the four single-precision, floating-point values of a to signed -// 32-bit integer values. -// -// r0 := (int) a0 -// r1 := (int) a1 -// r2 := (int) a2 -// r3 := (int) a3 -// -// https://msdn.microsoft.com/en-us/library/vstudio/xdc42k5e(v=vs.100).aspx -// *NOTE*. The default rounding mode on SSE is 'round to even', which ARMv7-A -// does not support! It is supported on ARMv8-A however. -FORCE_INLINE __m128i _mm_cvtps_epi32(__m128 a) -{ -#if defined(__aarch64__) - return vreinterpretq_m128i_s32(vcvtnq_s32_f32(a)); -#else - uint32x4_t signmask = vdupq_n_u32(0x80000000); - float32x4_t half = vbslq_f32(signmask, vreinterpretq_f32_m128(a), - vdupq_n_f32(0.5f)); /* +/- 0.5 */ - int32x4_t r_normal = vcvtq_s32_f32(vaddq_f32( - vreinterpretq_f32_m128(a), half)); /* round to integer: [a + 0.5]*/ - int32x4_t r_trunc = - vcvtq_s32_f32(vreinterpretq_f32_m128(a)); /* truncate to integer: [a] */ - int32x4_t plusone = vreinterpretq_s32_u32(vshrq_n_u32( - vreinterpretq_u32_s32(vnegq_s32(r_trunc)), 31)); /* 1 or 0 */ - int32x4_t r_even = vbicq_s32(vaddq_s32(r_trunc, plusone), - vdupq_n_s32(1)); /* ([a] + {0,1}) & ~1 */ - float32x4_t delta = vsubq_f32( - vreinterpretq_f32_m128(a), - vcvtq_f32_s32(r_trunc)); /* compute delta: delta = (a - [a]) */ - uint32x4_t is_delta_half = vceqq_f32(delta, half); /* delta == +/- 0.5 */ - return vreinterpretq_m128i_s32(vbslq_s32(is_delta_half, r_even, r_normal)); -#endif -} - -// Convert packed single-precision (32-bit) floating-point elements in a to -// packed 16-bit integers, and store the results in dst. Note: this intrinsic -// will generate 0x7FFF, rather than 0x8000, for input values between 0x7FFF and -// 0x7FFFFFFF. -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtps_pi16 -FORCE_INLINE __m64 _mm_cvtps_pi16(__m128 a) -{ - return vreinterpret_m64_s16( - vmovn_s32(vreinterpretq_s32_m128i(_mm_cvtps_epi32(a)))); -} - -// Copy the lower 32-bit integer in a to dst. -// -// dst[31:0] := a[31:0] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si32 -FORCE_INLINE int _mm_cvtsi128_si32(__m128i a) -{ - return vgetq_lane_s32(vreinterpretq_s32_m128i(a), 0); -} - -// Copy the lower 64-bit integer in a to dst. -// -// dst[63:0] := a[63:0] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si64 -FORCE_INLINE int64_t _mm_cvtsi128_si64(__m128i a) -{ - return vgetq_lane_s64(vreinterpretq_s64_m128i(a), 0); -} - -// Copy the lower 64-bit integer in a to dst. -// -// dst[63:0] := a[63:0] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsi128_si64x -#define _mm_cvtsi128_si64x(a) _mm_cvtsi128_si64(a) - -// Moves 32-bit integer a to the least significant 32 bits of an __m128 object, -// zero extending the upper bits. -// -// r0 := a -// r1 := 0x0 -// r2 := 0x0 -// r3 := 0x0 -// -// https://msdn.microsoft.com/en-us/library/ct3539ha%28v=vs.90%29.aspx -FORCE_INLINE __m128i _mm_cvtsi32_si128(int a) -{ - return vreinterpretq_m128i_s32(vsetq_lane_s32(a, vdupq_n_s32(0), 0)); -} - -// Moves 64-bit integer a to the least significant 64 bits of an __m128 object, -// zero extending the upper bits. -// -// r0 := a -// r1 := 0x0 -FORCE_INLINE __m128i _mm_cvtsi64_si128(int64_t a) -{ - return vreinterpretq_m128i_s64(vsetq_lane_s64(a, vdupq_n_s64(0), 0)); -} - -// Cast vector of type __m128 to type __m128d. This intrinsic is only used for -// compilation and does not generate any instructions, thus it has zero latency. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castps_pd -FORCE_INLINE __m128d _mm_castps_pd(__m128 a) -{ - return vreinterpretq_m128d_s32(vreinterpretq_s32_m128(a)); -} - -// Applies a type cast to reinterpret four 32-bit floating point values passed -// in as a 128-bit parameter as packed 32-bit integers. -// https://msdn.microsoft.com/en-us/library/bb514099.aspx -FORCE_INLINE __m128i _mm_castps_si128(__m128 a) -{ - return vreinterpretq_m128i_s32(vreinterpretq_s32_m128(a)); -} - -// Cast vector of type __m128i to type __m128d. This intrinsic is only used for -// compilation and does not generate any instructions, thus it has zero latency. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castsi128_pd -FORCE_INLINE __m128d _mm_castsi128_pd(__m128i a) -{ -#if defined(__aarch64__) - return vreinterpretq_m128d_f64(vreinterpretq_f64_m128i(a)); -#else - return vreinterpretq_m128d_f32(vreinterpretq_f32_m128i(a)); -#endif -} - -// Applies a type cast to reinterpret four 32-bit integers passed in as a -// 128-bit parameter as packed 32-bit floating point values. -// https://msdn.microsoft.com/en-us/library/bb514029.aspx -FORCE_INLINE __m128 _mm_castsi128_ps(__m128i a) -{ - return vreinterpretq_m128_s32(vreinterpretq_s32_m128i(a)); -} - -// Loads 128-bit value. : -// https://msdn.microsoft.com/en-us/library/atzzad1h(v=vs.80).aspx -FORCE_INLINE __m128i _mm_load_si128(const __m128i *p) -{ - return vreinterpretq_m128i_s32(vld1q_s32((const int32_t *) p)); -} - -// Load a double-precision (64-bit) floating-point element from memory into both -// elements of dst. -// -// dst[63:0] := MEM[mem_addr+63:mem_addr] -// dst[127:64] := MEM[mem_addr+63:mem_addr] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load1_pd -FORCE_INLINE __m128d _mm_load1_pd(const double *p) -{ -#if defined(__aarch64__) - return vreinterpretq_m128d_f64(vld1q_dup_f64(p)); -#else - return vreinterpretq_m128d_s64(vdupq_n_s64(*(const int64_t *) p)); -#endif -} - -// Load a double-precision (64-bit) floating-point element from memory into both -// elements of dst. -// -// dst[63:0] := MEM[mem_addr+63:mem_addr] -// dst[127:64] := MEM[mem_addr+63:mem_addr] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_pd1 -#define _mm_load_pd1 _mm_load1_pd - -// Load a double-precision (64-bit) floating-point element from memory into both -// elements of dst. -// -// dst[63:0] := MEM[mem_addr+63:mem_addr] -// dst[127:64] := MEM[mem_addr+63:mem_addr] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loaddup_pd -#define _mm_loaddup_pd _mm_load1_pd - -// Load a double-precision (64-bit) floating-point element from memory into the -// upper element of dst, and copy the lower element from a to dst. mem_addr does -// not need to be aligned on any particular boundary. -// -// dst[63:0] := a[63:0] -// dst[127:64] := MEM[mem_addr+63:mem_addr] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadh_pd -FORCE_INLINE __m128d _mm_loadh_pd(__m128d a, const double *p) -{ -#if defined(__aarch64__) - return vreinterpretq_m128d_f64( - vcombine_f64(vget_low_f64(vreinterpretq_f64_m128d(a)), vld1_f64(p))); -#else - return vreinterpretq_m128d_f32(vcombine_f32( - vget_low_f32(vreinterpretq_f32_m128d(a)), vld1_f32((const float *) p))); -#endif -} - -// Load a double-precision (64-bit) floating-point element from memory into both -// elements of dst. -// -// dst[63:0] := MEM[mem_addr+63:mem_addr] -// dst[127:64] := MEM[mem_addr+63:mem_addr] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_load_pd1 -#define _mm_load_pd1 _mm_load1_pd - -// Load a double-precision (64-bit) floating-point element from memory into both -// elements of dst. -// -// dst[63:0] := MEM[mem_addr+63:mem_addr] -// dst[127:64] := MEM[mem_addr+63:mem_addr] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loaddup_pd -#define _mm_loaddup_pd _mm_load1_pd - -// Loads 128-bit value. : -// https://msdn.microsoft.com/zh-cn/library/f4k12ae8(v=vs.90).aspx -FORCE_INLINE __m128i _mm_loadu_si128(const __m128i *p) -{ - return vreinterpretq_m128i_s32(vld1q_s32((const int32_t *) p)); -} - -// Load unaligned 32-bit integer from memory into the first element of dst. -// -// dst[31:0] := MEM[mem_addr+31:mem_addr] -// dst[MAX:32] := 0 -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_loadu_si32 -FORCE_INLINE __m128i _mm_loadu_si32(const void *p) -{ - return vreinterpretq_m128i_s32( - vsetq_lane_s32(*(const int32_t *) p, vdupq_n_s32(0), 0)); -} - -// Convert packed double-precision (64-bit) floating-point elements in a to -// packed single-precision (32-bit) floating-point elements, and store the -// results in dst. -// -// FOR j := 0 to 1 -// i := 32*j -// k := 64*j -// dst[i+31:i] := Convert_FP64_To_FP32(a[k+64:k]) -// ENDFOR -// dst[127:64] := 0 -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtpd_ps -FORCE_INLINE __m128 _mm_cvtpd_ps(__m128d a) -{ -#if defined(__aarch64__) - float32x2_t tmp = vcvt_f32_f64(vreinterpretq_f64_m128d(a)); - return vreinterpretq_m128_f32(vcombine_f32(tmp, vdup_n_f32(0))); -#else - float a0 = (float) ((double *) &a)[0]; - float a1 = (float) ((double *) &a)[1]; - return _mm_set_ps(0, 0, a1, a0); -#endif -} - -// Copy the lower double-precision (64-bit) floating-point element of a to dst. -// -// dst[63:0] := a[63:0] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtsd_f64 -FORCE_INLINE double _mm_cvtsd_f64(__m128d a) -{ -#if defined(__aarch64__) - return (double) vgetq_lane_f64(vreinterpretq_f64_m128d(a), 0); -#else - return ((double *) &a)[0]; -#endif -} - -// Convert packed single-precision (32-bit) floating-point elements in a to -// packed double-precision (64-bit) floating-point elements, and store the -// results in dst. -// -// FOR j := 0 to 1 -// i := 64*j -// k := 32*j -// dst[i+63:i] := Convert_FP32_To_FP64(a[k+31:k]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtps_pd -FORCE_INLINE __m128d _mm_cvtps_pd(__m128 a) -{ -#if defined(__aarch64__) - return vreinterpretq_m128d_f64( - vcvt_f64_f32(vget_low_f32(vreinterpretq_f32_m128(a)))); -#else - double a0 = (double) vgetq_lane_f32(vreinterpretq_f32_m128(a), 0); - double a1 = (double) vgetq_lane_f32(vreinterpretq_f32_m128(a), 1); - return _mm_set_pd(a1, a0); -#endif -} - -// Cast vector of type __m128d to type __m128i. This intrinsic is only used for -// compilation and does not generate any instructions, thus it has zero latency. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castpd_si128 -FORCE_INLINE __m128i _mm_castpd_si128(__m128d a) -{ - return vreinterpretq_m128i_s64(vreinterpretq_s64_m128d(a)); -} - -// Cast vector of type __m128d to type __m128. This intrinsic is only used for -// compilation and does not generate any instructions, thus it has zero latency. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_castpd_ps -FORCE_INLINE __m128 _mm_castpd_ps(__m128d a) -{ - return vreinterpretq_m128_s64(vreinterpretq_s64_m128d(a)); -} - -// Blend packed single-precision (32-bit) floating-point elements from a and b -// using mask, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_blendv_ps -FORCE_INLINE __m128 _mm_blendv_ps(__m128 _a, __m128 _b, __m128 _mask) -{ - // Use a signed shift right to create a mask with the sign bit - uint32x4_t mask = - vreinterpretq_u32_s32(vshrq_n_s32(vreinterpretq_s32_m128(_mask), 31)); - float32x4_t a = vreinterpretq_f32_m128(_a); - float32x4_t b = vreinterpretq_f32_m128(_b); - return vreinterpretq_m128_f32(vbslq_f32(mask, b, a)); -} - -// Blend packed single-precision (32-bit) floating-point elements from a and b -// using mask, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_blend_ps -FORCE_INLINE __m128 _mm_blend_ps(__m128 _a, __m128 _b, const char imm8) -{ - const uint32_t ALIGN_STRUCT(16) - data[4] = {((imm8) & (1 << 0)) ? UINT32_MAX : 0, - ((imm8) & (1 << 1)) ? UINT32_MAX : 0, - ((imm8) & (1 << 2)) ? UINT32_MAX : 0, - ((imm8) & (1 << 3)) ? UINT32_MAX : 0}; - uint32x4_t mask = vld1q_u32(data); - float32x4_t a = vreinterpretq_f32_m128(_a); - float32x4_t b = vreinterpretq_f32_m128(_b); - return vreinterpretq_m128_f32(vbslq_f32(mask, b, a)); -} - -// Blend packed double-precision (64-bit) floating-point elements from a and b -// using mask, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_blendv_pd -FORCE_INLINE __m128d _mm_blendv_pd(__m128d _a, __m128d _b, __m128d _mask) -{ - uint64x2_t mask = - vreinterpretq_u64_s64(vshrq_n_s64(vreinterpretq_s64_m128d(_mask), 63)); -#if defined(__aarch64__) - float64x2_t a = vreinterpretq_f64_m128d(_a); - float64x2_t b = vreinterpretq_f64_m128d(_b); - return vreinterpretq_m128d_f64(vbslq_f64(mask, b, a)); -#else - uint64x2_t a = vreinterpretq_u64_m128d(_a); - uint64x2_t b = vreinterpretq_u64_m128d(_b); - return vreinterpretq_m128d_u64(vbslq_u64(mask, b, a)); -#endif -} - -typedef struct { - uint16_t res0; - uint8_t res1 : 6; - uint8_t bit22 : 1; - uint8_t bit23 : 1; - uint8_t res2; -#if defined(__aarch64__) - uint32_t res3; -#endif -} fpcr_bitfield; - -// Macro: Set the rounding mode bits of the MXCSR control and status register to -// the value in unsigned 32-bit integer a. The rounding mode may contain any of -// the following flags: _MM_ROUND_NEAREST, _MM_ROUND_DOWN, _MM_ROUND_UP, -// _MM_ROUND_TOWARD_ZERO -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_MM_SET_ROUNDING_MODE -FORCE_INLINE void _MM_SET_ROUNDING_MODE(int rounding) -{ - union { - fpcr_bitfield field; -#if defined(__aarch64__) - uint64_t value; -#else - uint32_t value; -#endif - } r; - -#if defined(__aarch64__) - asm volatile("mrs %0, FPCR" : "=r"(r.value)); /* read */ -#else - asm volatile("vmrs %0, FPSCR" : "=r"(r.value)); /* read */ -#endif - - switch (rounding) { - case _MM_ROUND_TOWARD_ZERO: - r.field.bit22 = 1; - r.field.bit23 = 1; - break; - case _MM_ROUND_DOWN: - r.field.bit22 = 0; - r.field.bit23 = 1; - break; - case _MM_ROUND_UP: - r.field.bit22 = 1; - r.field.bit23 = 0; - break; - default: //_MM_ROUND_NEAREST - r.field.bit22 = 0; - r.field.bit23 = 0; - } - -#if defined(__aarch64__) - asm volatile("msr FPCR, %0" ::"r"(r)); /* write */ -#else - asm volatile("vmsr FPSCR, %0" ::"r"(r)); /* write */ -#endif -} - -FORCE_INLINE void _mm_setcsr(unsigned int a) -{ - _MM_SET_ROUNDING_MODE(a); -} - -// Round the packed single-precision (32-bit) floating-point elements in a using -// the rounding parameter, and store the results as packed single-precision +// Extracts the selected signed or unsigned 32-bit integer from a and zero +// extends. +// FORCE_INLINE int _mm_extract_epi32(__m128i a, __constrange(0,4) int imm) +#define _mm_extract_epi32(a, imm) \ + vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm)) + +// Extracts the selected signed or unsigned 64-bit integer from a and zero +// extends. +// FORCE_INLINE __int64 _mm_extract_epi64(__m128i a, __constrange(0,2) int imm) +#define _mm_extract_epi64(a, imm) \ + vgetq_lane_s64(vreinterpretq_s64_m128i(a), (imm)) + +// Extracts the selected signed or unsigned 8-bit integer from a and zero +// extends. +// FORCE_INLINE int _mm_extract_epi8(__m128i a, __constrange(0,16) int imm) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_extract_epi8 +#define _mm_extract_epi8(a, imm) vgetq_lane_u8(vreinterpretq_u8_m128i(a), (imm)) + +// Extracts the selected single-precision (32-bit) floating-point from a. +// FORCE_INLINE int _mm_extract_ps(__m128 a, __constrange(0,4) int imm) +#define _mm_extract_ps(a, imm) vgetq_lane_s32(vreinterpretq_s32_m128(a), (imm)) + +// Round the packed double-precision (64-bit) floating-point elements in a down +// to an integer value, and store the results as packed double-precision // floating-point elements in dst. -// software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_round_ps -FORCE_INLINE __m128 _mm_round_ps(__m128 a, int rounding) +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_floor_pd +FORCE_INLINE __m128d _mm_floor_pd(__m128d a) { #if defined(__aarch64__) - switch (rounding) { - case (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC): - return vreinterpretq_m128_f32(vrndnq_f32(vreinterpretq_f32_m128(a))); - case (_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC): - return vreinterpretq_m128_f32(vrndmq_f32(vreinterpretq_f32_m128(a))); - case (_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC): - return vreinterpretq_m128_f32(vrndpq_f32(vreinterpretq_f32_m128(a))); - case (_MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC): - return vreinterpretq_m128_f32(vrndq_f32(vreinterpretq_f32_m128(a))); - default: //_MM_FROUND_CUR_DIRECTION - return vreinterpretq_m128_f32(vrndiq_f32(vreinterpretq_f32_m128(a))); - } + return vreinterpretq_m128d_f64(vrndmq_f64(vreinterpretq_f64_m128d(a))); #else - float *v_float = (float *) &a; - __m128 zero, neg_inf, pos_inf; - - switch (rounding) { - case (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC): - return _mm_cvtepi32_ps(_mm_cvtps_epi32(a)); - case (_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC): - return (__m128){floorf(v_float[0]), floorf(v_float[1]), - floorf(v_float[2]), floorf(v_float[3])}; - case (_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC): - return (__m128){ceilf(v_float[0]), ceilf(v_float[1]), ceilf(v_float[2]), - ceilf(v_float[3])}; - case (_MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC): - zero = _mm_set_ps(0.0f, 0.0f, 0.0f, 0.0f); - neg_inf = _mm_set_ps(floorf(v_float[0]), floorf(v_float[1]), - floorf(v_float[2]), floorf(v_float[3])); - pos_inf = _mm_set_ps(ceilf(v_float[0]), ceilf(v_float[1]), - ceilf(v_float[2]), ceilf(v_float[3])); - return _mm_blendv_ps(pos_inf, neg_inf, _mm_cmple_ps(a, zero)); - default: //_MM_FROUND_CUR_DIRECTION - return (__m128){roundf(v_float[0]), roundf(v_float[1]), - roundf(v_float[2]), roundf(v_float[3])}; - } + double *f = (double *) &a; + return _mm_set_pd(floor(f[1]), floor(f[0])); #endif } -// Convert packed single-precision (32-bit) floating-point elements in a to -// packed 32-bit integers, and store the results in dst. -// -// FOR j := 0 to 1 -// i := 32*j -// dst[i+31:i] := Convert_FP32_To_Int32(a[i+31:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvt_ps2pi -FORCE_INLINE __m64 _mm_cvt_ps2pi(__m128 a) -{ -#if defined(__aarch64__) - return vreinterpret_m64_s32( - vget_low_s32(vcvtnq_s32_f32(vreinterpretq_f32_m128(a)))); -#else - return vreinterpret_m64_s32( - vcvt_s32_f32(vget_low_f32(vreinterpretq_f32_m128( - _mm_round_ps(a, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC))))); -#endif -} - -// Convert packed single-precision (32-bit) floating-point elements in a to -// packed 32-bit integers, and store the results in dst. -// -// FOR j := 0 to 1 -// i := 32*j -// dst[i+31:i] := Convert_FP32_To_Int32(a[i+31:i]) -// ENDFOR -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_cvtps_pi32 -#define _mm_cvtps_pi32(a) _mm_cvt_ps2pi(a) - -// Round the packed single-precision (32-bit) floating-point elements in a up to -// an integer value, and store the results as packed single-precision -// floating-point elements in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_ceil_ps -FORCE_INLINE __m128 _mm_ceil_ps(__m128 a) -{ - return _mm_round_ps(a, _MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC); -} - -// Round the lower single-precision (32-bit) floating-point element in b up to -// an integer value, store the result as a single-precision floating-point -// element in the lower element of dst, and copy the upper 3 packed elements -// from a to the upper elements of dst. -// -// dst[31:0] := CEIL(b[31:0]) -// dst[127:32] := a[127:32] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_ceil_ss -FORCE_INLINE __m128 _mm_ceil_ss(__m128 a, __m128 b) -{ - return _mm_move_ss( - a, _mm_round_ps(b, _MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC)); -} - // Round the packed single-precision (32-bit) floating-point elements in a down // to an integer value, and store the results as packed single-precision // floating-point elements in dst. // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_floor_ps FORCE_INLINE __m128 _mm_floor_ps(__m128 a) { - return _mm_round_ps(a, _MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC); +#if defined(__aarch64__) || defined(__ARM_FEATURE_DIRECTED_ROUNDING) + return vreinterpretq_m128_f32(vrndmq_f32(vreinterpretq_f32_m128(a))); +#else + float *f = (float *) &a; + return _mm_set_ps(floorf(f[3]), floorf(f[2]), floorf(f[1]), floorf(f[0])); +#endif +} + +// Round the lower double-precision (64-bit) floating-point element in b down to +// an integer value, store the result as a double-precision floating-point +// element in the lower element of dst, and copy the upper element from a to the +// upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_floor_sd +FORCE_INLINE __m128d _mm_floor_sd(__m128d a, __m128d b) +{ + return _mm_move_sd(a, _mm_floor_pd(b)); } // Round the lower single-precision (32-bit) floating-point element in b down to @@ -6416,372 +7785,147 @@ FORCE_INLINE __m128 _mm_floor_ps(__m128 a) // https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_floor_ss FORCE_INLINE __m128 _mm_floor_ss(__m128 a, __m128 b) { - return _mm_move_ss( - a, _mm_round_ps(b, _MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC)); + return _mm_move_ss(a, _mm_floor_ps(b)); } -// Load 128-bits of integer data from unaligned memory into dst. This intrinsic -// may perform better than _mm_loadu_si128 when the data crosses a cache line -// boundary. -// -// dst[127:0] := MEM[mem_addr+127:mem_addr] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_lddqu_si128 -#define _mm_lddqu_si128 _mm_loadu_si128 +// Inserts the least significant 32 bits of b into the selected 32-bit integer +// of a. +// FORCE_INLINE __m128i _mm_insert_epi32(__m128i a, int b, +// __constrange(0,4) int imm) +#define _mm_insert_epi32(a, b, imm) \ + __extension__({ \ + vreinterpretq_m128i_s32( \ + vsetq_lane_s32((b), vreinterpretq_s32_m128i(a), (imm))); \ + }) -/* Miscellaneous Operations */ +// Inserts the least significant 64 bits of b into the selected 64-bit integer +// of a. +// FORCE_INLINE __m128i _mm_insert_epi64(__m128i a, __int64 b, +// __constrange(0,2) int imm) +#define _mm_insert_epi64(a, b, imm) \ + __extension__({ \ + vreinterpretq_m128i_s64( \ + vsetq_lane_s64((b), vreinterpretq_s64_m128i(a), (imm))); \ + }) -// Shifts the 8 signed 16-bit integers in a right by count bits while shifting -// in the sign bit. +// Inserts the least significant 8 bits of b into the selected 8-bit integer +// of a. +// FORCE_INLINE __m128i _mm_insert_epi8(__m128i a, int b, +// __constrange(0,16) int imm) +#define _mm_insert_epi8(a, b, imm) \ + __extension__({ \ + vreinterpretq_m128i_s8( \ + vsetq_lane_s8((b), vreinterpretq_s8_m128i(a), (imm))); \ + }) + +// Copy a to tmp, then insert a single-precision (32-bit) floating-point +// element from b into tmp using the control in imm8. Store tmp to dst using +// the mask in imm8 (elements are zeroed out when the corresponding bit is set). +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=insert_ps +#define _mm_insert_ps(a, b, imm8) \ + __extension__({ \ + float32x4_t tmp1 = \ + vsetq_lane_f32(vgetq_lane_f32(b, (imm8 >> 6) & 0x3), \ + vreinterpretq_f32_m128(a), 0); \ + float32x4_t tmp2 = \ + vsetq_lane_f32(vgetq_lane_f32(tmp1, 0), vreinterpretq_f32_m128(a), \ + ((imm8 >> 4) & 0x3)); \ + const uint32_t data[4] = {((imm8) & (1 << 0)) ? UINT32_MAX : 0, \ + ((imm8) & (1 << 1)) ? UINT32_MAX : 0, \ + ((imm8) & (1 << 2)) ? UINT32_MAX : 0, \ + ((imm8) & (1 << 3)) ? UINT32_MAX : 0}; \ + uint32x4_t mask = vld1q_u32(data); \ + float32x4_t all_zeros = vdupq_n_f32(0); \ + \ + vreinterpretq_m128_f32( \ + vbslq_f32(mask, all_zeros, vreinterpretq_f32_m128(tmp2))); \ + }) + +// epi versions of min/max +// Computes the pariwise maximums of the four signed 32-bit integer values of a +// and b. // -// r0 := a0 >> count -// r1 := a1 >> count -// ... -// r7 := a7 >> count +// A 128-bit parameter that can be defined with the following equations: +// r0 := (a0 > b0) ? a0 : b0 +// r1 := (a1 > b1) ? a1 : b1 +// r2 := (a2 > b2) ? a2 : b2 +// r3 := (a3 > b3) ? a3 : b3 // -// https://msdn.microsoft.com/en-us/library/3c9997dk(v%3dvs.90).aspx -FORCE_INLINE __m128i _mm_sra_epi16(__m128i a, __m128i count) +// https://msdn.microsoft.com/en-us/library/vstudio/bb514055(v=vs.100).aspx +FORCE_INLINE __m128i _mm_max_epi32(__m128i a, __m128i b) { - int64_t c = (int64_t) vget_low_s64((int64x2_t) count); - if (unlikely(c > 15)) - return _mm_cmplt_epi16(a, _mm_setzero_si128()); - return vreinterpretq_m128i_s16(vshlq_s16((int16x8_t) a, vdupq_n_s16(-c))); + return vreinterpretq_m128i_s32( + vmaxq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); } -// Shifts the 4 signed 32-bit integers in a right by count bits while shifting -// in the sign bit. -// -// r0 := a0 >> count -// r1 := a1 >> count -// r2 := a2 >> count -// r3 := a3 >> count -// -// https://msdn.microsoft.com/en-us/library/ce40009e(v%3dvs.100).aspx -FORCE_INLINE __m128i _mm_sra_epi32(__m128i a, __m128i count) -{ - int64_t c = (int64_t) vget_low_s64((int64x2_t) count); - if (unlikely(c > 31)) - return _mm_cmplt_epi32(a, _mm_setzero_si128()); - return vreinterpretq_m128i_s32(vshlq_s32((int32x4_t) a, vdupq_n_s32(-c))); -} - -// Packs the 16 signed 16-bit integers from a and b into 8-bit integers and -// saturates. -// https://msdn.microsoft.com/en-us/library/k4y4f7w5%28v=vs.90%29.aspx -FORCE_INLINE __m128i _mm_packs_epi16(__m128i a, __m128i b) +// Compare packed signed 8-bit integers in a and b, and store packed maximum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epi8 +FORCE_INLINE __m128i _mm_max_epi8(__m128i a, __m128i b) { return vreinterpretq_m128i_s8( - vcombine_s8(vqmovn_s16(vreinterpretq_s16_m128i(a)), - vqmovn_s16(vreinterpretq_s16_m128i(b)))); + vmaxq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); } -// Packs the 16 signed 16 - bit integers from a and b into 8 - bit unsigned -// integers and saturates. -// -// r0 := UnsignedSaturate(a0) -// r1 := UnsignedSaturate(a1) -// ... -// r7 := UnsignedSaturate(a7) -// r8 := UnsignedSaturate(b0) -// r9 := UnsignedSaturate(b1) -// ... -// r15 := UnsignedSaturate(b7) -// -// https://msdn.microsoft.com/en-us/library/07ad1wx4(v=vs.100).aspx -FORCE_INLINE __m128i _mm_packus_epi16(const __m128i a, const __m128i b) -{ - return vreinterpretq_m128i_u8( - vcombine_u8(vqmovun_s16(vreinterpretq_s16_m128i(a)), - vqmovun_s16(vreinterpretq_s16_m128i(b)))); -} - -// Packs the 8 signed 32-bit integers from a and b into signed 16-bit integers -// and saturates. -// -// r0 := SignedSaturate(a0) -// r1 := SignedSaturate(a1) -// r2 := SignedSaturate(a2) -// r3 := SignedSaturate(a3) -// r4 := SignedSaturate(b0) -// r5 := SignedSaturate(b1) -// r6 := SignedSaturate(b2) -// r7 := SignedSaturate(b3) -// -// https://msdn.microsoft.com/en-us/library/393t56f9%28v=vs.90%29.aspx -FORCE_INLINE __m128i _mm_packs_epi32(__m128i a, __m128i b) -{ - return vreinterpretq_m128i_s16( - vcombine_s16(vqmovn_s32(vreinterpretq_s32_m128i(a)), - vqmovn_s32(vreinterpretq_s32_m128i(b)))); -} - -// Packs the 8 unsigned 32-bit integers from a and b into unsigned 16-bit -// integers and saturates. -// -// r0 := UnsignedSaturate(a0) -// r1 := UnsignedSaturate(a1) -// r2 := UnsignedSaturate(a2) -// r3 := UnsignedSaturate(a3) -// r4 := UnsignedSaturate(b0) -// r5 := UnsignedSaturate(b1) -// r6 := UnsignedSaturate(b2) -// r7 := UnsignedSaturate(b3) -FORCE_INLINE __m128i _mm_packus_epi32(__m128i a, __m128i b) +// Compare packed unsigned 16-bit integers in a and b, and store packed maximum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epu16 +FORCE_INLINE __m128i _mm_max_epu16(__m128i a, __m128i b) { return vreinterpretq_m128i_u16( - vcombine_u16(vqmovun_s32(vreinterpretq_s32_m128i(a)), - vqmovun_s32(vreinterpretq_s32_m128i(b)))); + vmaxq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); } -// Interleaves the lower 8 signed or unsigned 8-bit integers in a with the lower -// 8 signed or unsigned 8-bit integers in b. -// -// r0 := a0 -// r1 := b0 -// r2 := a1 -// r3 := b1 -// ... -// r14 := a7 -// r15 := b7 -// -// https://msdn.microsoft.com/en-us/library/xf7k860c%28v=vs.90%29.aspx -FORCE_INLINE __m128i _mm_unpacklo_epi8(__m128i a, __m128i b) +// Compare packed unsigned 32-bit integers in a and b, and store packed maximum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epu32 +FORCE_INLINE __m128i _mm_max_epu32(__m128i a, __m128i b) { -#if defined(__aarch64__) - return vreinterpretq_m128i_s8( - vzip1q_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); -#else - int8x8_t a1 = vreinterpret_s8_s16(vget_low_s16(vreinterpretq_s16_m128i(a))); - int8x8_t b1 = vreinterpret_s8_s16(vget_low_s16(vreinterpretq_s16_m128i(b))); - int8x8x2_t result = vzip_s8(a1, b1); - return vreinterpretq_m128i_s8(vcombine_s8(result.val[0], result.val[1])); -#endif + return vreinterpretq_m128i_u32( + vmaxq_u32(vreinterpretq_u32_m128i(a), vreinterpretq_u32_m128i(b))); } -// Interleaves the lower 4 signed or unsigned 16-bit integers in a with the -// lower 4 signed or unsigned 16-bit integers in b. +// Computes the pariwise minima of the four signed 32-bit integer values of a +// and b. // -// r0 := a0 -// r1 := b0 -// r2 := a1 -// r3 := b1 -// r4 := a2 -// r5 := b2 -// r6 := a3 -// r7 := b3 +// A 128-bit parameter that can be defined with the following equations: +// r0 := (a0 < b0) ? a0 : b0 +// r1 := (a1 < b1) ? a1 : b1 +// r2 := (a2 < b2) ? a2 : b2 +// r3 := (a3 < b3) ? a3 : b3 // -// https://msdn.microsoft.com/en-us/library/btxb17bw%28v=vs.90%29.aspx -FORCE_INLINE __m128i _mm_unpacklo_epi16(__m128i a, __m128i b) +// https://msdn.microsoft.com/en-us/library/vstudio/bb531476(v=vs.100).aspx +FORCE_INLINE __m128i _mm_min_epi32(__m128i a, __m128i b) { -#if defined(__aarch64__) - return vreinterpretq_m128i_s16( - vzip1q_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); -#else - int16x4_t a1 = vget_low_s16(vreinterpretq_s16_m128i(a)); - int16x4_t b1 = vget_low_s16(vreinterpretq_s16_m128i(b)); - int16x4x2_t result = vzip_s16(a1, b1); - return vreinterpretq_m128i_s16(vcombine_s16(result.val[0], result.val[1])); -#endif -} - -// Interleaves the lower 2 signed or unsigned 32 - bit integers in a with the -// lower 2 signed or unsigned 32 - bit integers in b. -// -// r0 := a0 -// r1 := b0 -// r2 := a1 -// r3 := b1 -// -// https://msdn.microsoft.com/en-us/library/x8atst9d(v=vs.100).aspx -FORCE_INLINE __m128i _mm_unpacklo_epi32(__m128i a, __m128i b) -{ -#if defined(__aarch64__) return vreinterpretq_m128i_s32( - vzip1q_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); -#else - int32x2_t a1 = vget_low_s32(vreinterpretq_s32_m128i(a)); - int32x2_t b1 = vget_low_s32(vreinterpretq_s32_m128i(b)); - int32x2x2_t result = vzip_s32(a1, b1); - return vreinterpretq_m128i_s32(vcombine_s32(result.val[0], result.val[1])); -#endif + vminq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); } -FORCE_INLINE __m128i _mm_unpacklo_epi64(__m128i a, __m128i b) +// Compare packed signed 8-bit integers in a and b, and store packed minimum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_epi8 +FORCE_INLINE __m128i _mm_min_epi8(__m128i a, __m128i b) { - int64x1_t a_l = vget_low_s64(vreinterpretq_s64_m128i(a)); - int64x1_t b_l = vget_low_s64(vreinterpretq_s64_m128i(b)); - return vreinterpretq_m128i_s64(vcombine_s64(a_l, b_l)); -} - -// Selects and interleaves the lower two single-precision, floating-point values -// from a and b. -// -// r0 := a0 -// r1 := b0 -// r2 := a1 -// r3 := b1 -// -// https://msdn.microsoft.com/en-us/library/25st103b%28v=vs.90%29.aspx -FORCE_INLINE __m128 _mm_unpacklo_ps(__m128 a, __m128 b) -{ -#if defined(__aarch64__) - return vreinterpretq_m128_f32( - vzip1q_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); -#else - float32x2_t a1 = vget_low_f32(vreinterpretq_f32_m128(a)); - float32x2_t b1 = vget_low_f32(vreinterpretq_f32_m128(b)); - float32x2x2_t result = vzip_f32(a1, b1); - return vreinterpretq_m128_f32(vcombine_f32(result.val[0], result.val[1])); -#endif -} - -// Unpack and interleave double-precision (64-bit) floating-point elements from -// the low half of a and b, and store the results in dst. -// -// DEFINE INTERLEAVE_QWORDS(src1[127:0], src2[127:0]) { -// dst[63:0] := src1[63:0] -// dst[127:64] := src2[63:0] -// RETURN dst[127:0] -// } -// dst[127:0] := INTERLEAVE_QWORDS(a[127:0], b[127:0]) -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_unpacklo_pd -FORCE_INLINE __m128d _mm_unpacklo_pd(__m128d a, __m128d b) -{ -#if defined(__aarch64__) - return vreinterpretq_m128d_f64( - vzip1q_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); -#else - return vreinterpretq_m128d_s64( - vcombine_s64(vget_low_s64(vreinterpretq_s64_m128d(a)), - vget_low_s64(vreinterpretq_s64_m128d(b)))); -#endif -} - -// Unpack and interleave double-precision (64-bit) floating-point elements from -// the high half of a and b, and store the results in dst. -// -// DEFINE INTERLEAVE_HIGH_QWORDS(src1[127:0], src2[127:0]) { -// dst[63:0] := src1[127:64] -// dst[127:64] := src2[127:64] -// RETURN dst[127:0] -// } -// dst[127:0] := INTERLEAVE_HIGH_QWORDS(a[127:0], b[127:0]) -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_unpackhi_pd -FORCE_INLINE __m128d _mm_unpackhi_pd(__m128d a, __m128d b) -{ -#if defined(__aarch64__) - return vreinterpretq_m128d_f64( - vzip2q_f64(vreinterpretq_f64_m128d(a), vreinterpretq_f64_m128d(b))); -#else - return vreinterpretq_m128d_s64( - vcombine_s64(vget_high_s64(vreinterpretq_s64_m128d(a)), - vget_high_s64(vreinterpretq_s64_m128d(b)))); -#endif -} - -// Selects and interleaves the upper two single-precision, floating-point values -// from a and b. -// -// r0 := a2 -// r1 := b2 -// r2 := a3 -// r3 := b3 -// -// https://msdn.microsoft.com/en-us/library/skccxx7d%28v=vs.90%29.aspx -FORCE_INLINE __m128 _mm_unpackhi_ps(__m128 a, __m128 b) -{ -#if defined(__aarch64__) - return vreinterpretq_m128_f32( - vzip2q_f32(vreinterpretq_f32_m128(a), vreinterpretq_f32_m128(b))); -#else - float32x2_t a1 = vget_high_f32(vreinterpretq_f32_m128(a)); - float32x2_t b1 = vget_high_f32(vreinterpretq_f32_m128(b)); - float32x2x2_t result = vzip_f32(a1, b1); - return vreinterpretq_m128_f32(vcombine_f32(result.val[0], result.val[1])); -#endif -} - -// Interleaves the upper 8 signed or unsigned 8-bit integers in a with the upper -// 8 signed or unsigned 8-bit integers in b. -// -// r0 := a8 -// r1 := b8 -// r2 := a9 -// r3 := b9 -// ... -// r14 := a15 -// r15 := b15 -// -// https://msdn.microsoft.com/en-us/library/t5h7783k(v=vs.100).aspx -FORCE_INLINE __m128i _mm_unpackhi_epi8(__m128i a, __m128i b) -{ -#if defined(__aarch64__) return vreinterpretq_m128i_s8( - vzip2q_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); -#else - int8x8_t a1 = - vreinterpret_s8_s16(vget_high_s16(vreinterpretq_s16_m128i(a))); - int8x8_t b1 = - vreinterpret_s8_s16(vget_high_s16(vreinterpretq_s16_m128i(b))); - int8x8x2_t result = vzip_s8(a1, b1); - return vreinterpretq_m128i_s8(vcombine_s8(result.val[0], result.val[1])); -#endif + vminq_s8(vreinterpretq_s8_m128i(a), vreinterpretq_s8_m128i(b))); } -// Interleaves the upper 4 signed or unsigned 16-bit integers in a with the -// upper 4 signed or unsigned 16-bit integers in b. -// -// r0 := a4 -// r1 := b4 -// r2 := a5 -// r3 := b5 -// r4 := a6 -// r5 := b6 -// r6 := a7 -// r7 := b7 -// -// https://msdn.microsoft.com/en-us/library/03196cz7(v=vs.100).aspx -FORCE_INLINE __m128i _mm_unpackhi_epi16(__m128i a, __m128i b) +// Compare packed unsigned 16-bit integers in a and b, and store packed minimum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_min_epu16 +FORCE_INLINE __m128i _mm_min_epu16(__m128i a, __m128i b) { -#if defined(__aarch64__) - return vreinterpretq_m128i_s16( - vzip2q_s16(vreinterpretq_s16_m128i(a), vreinterpretq_s16_m128i(b))); -#else - int16x4_t a1 = vget_high_s16(vreinterpretq_s16_m128i(a)); - int16x4_t b1 = vget_high_s16(vreinterpretq_s16_m128i(b)); - int16x4x2_t result = vzip_s16(a1, b1); - return vreinterpretq_m128i_s16(vcombine_s16(result.val[0], result.val[1])); -#endif + return vreinterpretq_m128i_u16( + vminq_u16(vreinterpretq_u16_m128i(a), vreinterpretq_u16_m128i(b))); } -// Interleaves the upper 2 signed or unsigned 32-bit integers in a with the -// upper 2 signed or unsigned 32-bit integers in b. -// https://msdn.microsoft.com/en-us/library/65sa7cbs(v=vs.100).aspx -FORCE_INLINE __m128i _mm_unpackhi_epi32(__m128i a, __m128i b) +// Compare packed unsigned 32-bit integers in a and b, and store packed minimum +// values in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_max_epu32 +FORCE_INLINE __m128i _mm_min_epu32(__m128i a, __m128i b) { -#if defined(__aarch64__) - return vreinterpretq_m128i_s32( - vzip2q_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); -#else - int32x2_t a1 = vget_high_s32(vreinterpretq_s32_m128i(a)); - int32x2_t b1 = vget_high_s32(vreinterpretq_s32_m128i(b)); - int32x2x2_t result = vzip_s32(a1, b1); - return vreinterpretq_m128i_s32(vcombine_s32(result.val[0], result.val[1])); -#endif -} - -// Interleaves the upper signed or unsigned 64-bit integer in a with the -// upper signed or unsigned 64-bit integer in b. -// -// r0 := a1 -// r1 := b1 -FORCE_INLINE __m128i _mm_unpackhi_epi64(__m128i a, __m128i b) -{ - int64x1_t a_h = vget_high_s64(vreinterpretq_s64_m128i(a)); - int64x1_t b_h = vget_high_s64(vreinterpretq_s64_m128i(b)); - return vreinterpretq_m128i_s64(vcombine_s64(a_h, b_h)); + return vreinterpretq_m128i_u32( + vminq_u32(vreinterpretq_u32_m128i(a), vreinterpretq_u32_m128i(b))); } // Horizontally compute the minimum amongst the packed unsigned 16-bit integers @@ -6837,6 +7981,339 @@ FORCE_INLINE __m128i _mm_minpos_epu16(__m128i a) return dst; } +// Compute the sum of absolute differences (SADs) of quadruplets of unsigned +// 8-bit integers in a compared to those in b, and store the 16-bit results in +// dst. Eight SADs are performed using one quadruplet from b and eight +// quadruplets from a. One quadruplet is selected from b starting at on the +// offset specified in imm8. Eight quadruplets are formed from sequential 8-bit +// integers selected from a starting at the offset specified in imm8. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_mpsadbw_epu8 +FORCE_INLINE __m128i _mm_mpsadbw_epu8(__m128i a, __m128i b, const int imm) +{ + uint8x16_t _a, _b; + + switch (imm & 0x4) { + case 0: + // do nothing + _a = vreinterpretq_u8_m128i(a); + break; + case 4: + _a = vreinterpretq_u8_u32(vextq_u32(vreinterpretq_u32_m128i(a), + vreinterpretq_u32_m128i(a), 1)); + break; + default: +#if defined(__GNUC__) || defined(__clang__) + __builtin_unreachable(); +#endif + break; + } + + switch (imm & 0x3) { + case 0: + _b = vreinterpretq_u8_u32( + vdupq_n_u32(vgetq_lane_u32(vreinterpretq_u32_m128i(b), 0))); + break; + case 1: + _b = vreinterpretq_u8_u32( + vdupq_n_u32(vgetq_lane_u32(vreinterpretq_u32_m128i(b), 1))); + break; + case 2: + _b = vreinterpretq_u8_u32( + vdupq_n_u32(vgetq_lane_u32(vreinterpretq_u32_m128i(b), 2))); + break; + case 3: + _b = vreinterpretq_u8_u32( + vdupq_n_u32(vgetq_lane_u32(vreinterpretq_u32_m128i(b), 3))); + break; + default: +#if defined(__GNUC__) || defined(__clang__) + __builtin_unreachable(); +#endif + break; + } + + int16x8_t c04, c15, c26, c37; + uint8x8_t low_b = vget_low_u8(_b); + c04 = vabsq_s16(vreinterpretq_s16_u16(vsubl_u8(vget_low_u8(_a), low_b))); + _a = vextq_u8(_a, _a, 1); + c15 = vabsq_s16(vreinterpretq_s16_u16(vsubl_u8(vget_low_u8(_a), low_b))); + _a = vextq_u8(_a, _a, 1); + c26 = vabsq_s16(vreinterpretq_s16_u16(vsubl_u8(vget_low_u8(_a), low_b))); + _a = vextq_u8(_a, _a, 1); + c37 = vabsq_s16(vreinterpretq_s16_u16(vsubl_u8(vget_low_u8(_a), low_b))); +#if defined(__aarch64__) + // |0|4|2|6| + c04 = vpaddq_s16(c04, c26); + // |1|5|3|7| + c15 = vpaddq_s16(c15, c37); + + int32x4_t trn1_c = + vtrn1q_s32(vreinterpretq_s32_s16(c04), vreinterpretq_s32_s16(c15)); + int32x4_t trn2_c = + vtrn2q_s32(vreinterpretq_s32_s16(c04), vreinterpretq_s32_s16(c15)); + return vreinterpretq_m128i_s16(vpaddq_s16(vreinterpretq_s16_s32(trn1_c), + vreinterpretq_s16_s32(trn2_c))); +#else + int16x4_t c01, c23, c45, c67; + c01 = vpadd_s16(vget_low_s16(c04), vget_low_s16(c15)); + c23 = vpadd_s16(vget_low_s16(c26), vget_low_s16(c37)); + c45 = vpadd_s16(vget_high_s16(c04), vget_high_s16(c15)); + c67 = vpadd_s16(vget_high_s16(c26), vget_high_s16(c37)); + + return vreinterpretq_m128i_s16( + vcombine_s16(vpadd_s16(c01, c23), vpadd_s16(c45, c67))); +#endif +} + +// Multiply the low signed 32-bit integers from each packed 64-bit element in +// a and b, and store the signed 64-bit results in dst. +// +// r0 := (int64_t)(int32_t)a0 * (int64_t)(int32_t)b0 +// r1 := (int64_t)(int32_t)a2 * (int64_t)(int32_t)b2 +FORCE_INLINE __m128i _mm_mul_epi32(__m128i a, __m128i b) +{ + // vmull_s32 upcasts instead of masking, so we downcast. + int32x2_t a_lo = vmovn_s64(vreinterpretq_s64_m128i(a)); + int32x2_t b_lo = vmovn_s64(vreinterpretq_s64_m128i(b)); + return vreinterpretq_m128i_s64(vmull_s32(a_lo, b_lo)); +} + +// Multiplies the 4 signed or unsigned 32-bit integers from a by the 4 signed or +// unsigned 32-bit integers from b. +// https://msdn.microsoft.com/en-us/library/vstudio/bb531409(v=vs.100).aspx +FORCE_INLINE __m128i _mm_mullo_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_s32( + vmulq_s32(vreinterpretq_s32_m128i(a), vreinterpretq_s32_m128i(b))); +} + +// Packs the 8 unsigned 32-bit integers from a and b into unsigned 16-bit +// integers and saturates. +// +// r0 := UnsignedSaturate(a0) +// r1 := UnsignedSaturate(a1) +// r2 := UnsignedSaturate(a2) +// r3 := UnsignedSaturate(a3) +// r4 := UnsignedSaturate(b0) +// r5 := UnsignedSaturate(b1) +// r6 := UnsignedSaturate(b2) +// r7 := UnsignedSaturate(b3) +FORCE_INLINE __m128i _mm_packus_epi32(__m128i a, __m128i b) +{ + return vreinterpretq_m128i_u16( + vcombine_u16(vqmovun_s32(vreinterpretq_s32_m128i(a)), + vqmovun_s32(vreinterpretq_s32_m128i(b)))); +} + +// Round the packed double-precision (64-bit) floating-point elements in a using +// the rounding parameter, and store the results as packed double-precision +// floating-point elements in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_round_pd +FORCE_INLINE __m128d _mm_round_pd(__m128d a, int rounding) +{ +#if defined(__aarch64__) + switch (rounding) { + case (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC): + return vreinterpretq_m128d_f64(vrndnq_f64(vreinterpretq_f64_m128d(a))); + case (_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC): + return _mm_floor_pd(a); + case (_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC): + return _mm_ceil_pd(a); + case (_MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC): + return vreinterpretq_m128d_f64(vrndq_f64(vreinterpretq_f64_m128d(a))); + default: //_MM_FROUND_CUR_DIRECTION + return vreinterpretq_m128d_f64(vrndiq_f64(vreinterpretq_f64_m128d(a))); + } +#else + double *v_double = (double *) &a; + + if (rounding == (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC) || + (rounding == _MM_FROUND_CUR_DIRECTION && + _MM_GET_ROUNDING_MODE() == _MM_ROUND_NEAREST)) { + double res[2], tmp; + for (int i = 0; i < 2; i++) { + tmp = (v_double[i] < 0) ? -v_double[i] : v_double[i]; + double roundDown = floor(tmp); // Round down value + double roundUp = ceil(tmp); // Round up value + double diffDown = tmp - roundDown; + double diffUp = roundUp - tmp; + if (diffDown < diffUp) { + /* If it's closer to the round down value, then use it */ + res[i] = roundDown; + } else if (diffDown > diffUp) { + /* If it's closer to the round up value, then use it */ + res[i] = roundUp; + } else { + /* If it's equidistant between round up and round down value, + * pick the one which is an even number */ + double half = roundDown / 2; + if (half != floor(half)) { + /* If the round down value is odd, return the round up value + */ + res[i] = roundUp; + } else { + /* If the round up value is odd, return the round down value + */ + res[i] = roundDown; + } + } + res[i] = (v_double[i] < 0) ? -res[i] : res[i]; + } + return _mm_set_pd(res[1], res[0]); + } else if (rounding == (_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC) || + (rounding == _MM_FROUND_CUR_DIRECTION && + _MM_GET_ROUNDING_MODE() == _MM_ROUND_DOWN)) { + return _mm_floor_pd(a); + } else if (rounding == (_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC) || + (rounding == _MM_FROUND_CUR_DIRECTION && + _MM_GET_ROUNDING_MODE() == _MM_ROUND_UP)) { + return _mm_ceil_pd(a); + } + return _mm_set_pd(v_double[1] > 0 ? floor(v_double[1]) : ceil(v_double[1]), + v_double[0] > 0 ? floor(v_double[0]) : ceil(v_double[0])); +#endif +} + +// Round the packed single-precision (32-bit) floating-point elements in a using +// the rounding parameter, and store the results as packed single-precision +// floating-point elements in dst. +// software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_round_ps +FORCE_INLINE __m128 _mm_round_ps(__m128 a, int rounding) +{ +#if defined(__aarch64__) || defined(__ARM_FEATURE_DIRECTED_ROUNDING) + switch (rounding) { + case (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC): + return vreinterpretq_m128_f32(vrndnq_f32(vreinterpretq_f32_m128(a))); + case (_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC): + return _mm_floor_ps(a); + case (_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC): + return _mm_ceil_ps(a); + case (_MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC): + return vreinterpretq_m128_f32(vrndq_f32(vreinterpretq_f32_m128(a))); + default: //_MM_FROUND_CUR_DIRECTION + return vreinterpretq_m128_f32(vrndiq_f32(vreinterpretq_f32_m128(a))); + } +#else + float *v_float = (float *) &a; + + if (rounding == (_MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC) || + (rounding == _MM_FROUND_CUR_DIRECTION && + _MM_GET_ROUNDING_MODE() == _MM_ROUND_NEAREST)) { + uint32x4_t signmask = vdupq_n_u32(0x80000000); + float32x4_t half = vbslq_f32(signmask, vreinterpretq_f32_m128(a), + vdupq_n_f32(0.5f)); /* +/- 0.5 */ + int32x4_t r_normal = vcvtq_s32_f32(vaddq_f32( + vreinterpretq_f32_m128(a), half)); /* round to integer: [a + 0.5]*/ + int32x4_t r_trunc = vcvtq_s32_f32( + vreinterpretq_f32_m128(a)); /* truncate to integer: [a] */ + int32x4_t plusone = vreinterpretq_s32_u32(vshrq_n_u32( + vreinterpretq_u32_s32(vnegq_s32(r_trunc)), 31)); /* 1 or 0 */ + int32x4_t r_even = vbicq_s32(vaddq_s32(r_trunc, plusone), + vdupq_n_s32(1)); /* ([a] + {0,1}) & ~1 */ + float32x4_t delta = vsubq_f32( + vreinterpretq_f32_m128(a), + vcvtq_f32_s32(r_trunc)); /* compute delta: delta = (a - [a]) */ + uint32x4_t is_delta_half = + vceqq_f32(delta, half); /* delta == +/- 0.5 */ + return vreinterpretq_m128_f32( + vcvtq_f32_s32(vbslq_s32(is_delta_half, r_even, r_normal))); + } else if (rounding == (_MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC) || + (rounding == _MM_FROUND_CUR_DIRECTION && + _MM_GET_ROUNDING_MODE() == _MM_ROUND_DOWN)) { + return _mm_floor_ps(a); + } else if (rounding == (_MM_FROUND_TO_POS_INF | _MM_FROUND_NO_EXC) || + (rounding == _MM_FROUND_CUR_DIRECTION && + _MM_GET_ROUNDING_MODE() == _MM_ROUND_UP)) { + return _mm_ceil_ps(a); + } + return _mm_set_ps(v_float[3] > 0 ? floorf(v_float[3]) : ceilf(v_float[3]), + v_float[2] > 0 ? floorf(v_float[2]) : ceilf(v_float[2]), + v_float[1] > 0 ? floorf(v_float[1]) : ceilf(v_float[1]), + v_float[0] > 0 ? floorf(v_float[0]) : ceilf(v_float[0])); +#endif +} + +// Round the lower double-precision (64-bit) floating-point element in b using +// the rounding parameter, store the result as a double-precision floating-point +// element in the lower element of dst, and copy the upper element from a to the +// upper element of dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_round_sd +FORCE_INLINE __m128d _mm_round_sd(__m128d a, __m128d b, int rounding) +{ + return _mm_move_sd(a, _mm_round_pd(b, rounding)); +} + +// Round the lower single-precision (32-bit) floating-point element in b using +// the rounding parameter, store the result as a single-precision floating-point +// element in the lower element of dst, and copy the upper 3 packed elements +// from a to the upper elements of dst. Rounding is done according to the +// rounding[3:0] parameter, which can be one of: +// (_MM_FROUND_TO_NEAREST_INT |_MM_FROUND_NO_EXC) // round to nearest, and +// suppress exceptions +// (_MM_FROUND_TO_NEG_INF |_MM_FROUND_NO_EXC) // round down, and +// suppress exceptions +// (_MM_FROUND_TO_POS_INF |_MM_FROUND_NO_EXC) // round up, and suppress +// exceptions +// (_MM_FROUND_TO_ZERO |_MM_FROUND_NO_EXC) // truncate, and suppress +// exceptions _MM_FROUND_CUR_DIRECTION // use MXCSR.RC; see +// _MM_SET_ROUNDING_MODE +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_round_ss +FORCE_INLINE __m128 _mm_round_ss(__m128 a, __m128 b, int rounding) +{ + return _mm_move_ss(a, _mm_round_ps(b, rounding)); +} + +// Load 128-bits of integer data from memory into dst using a non-temporal +// memory hint. mem_addr must be aligned on a 16-byte boundary or a +// general-protection exception may be generated. +// +// dst[127:0] := MEM[mem_addr+127:mem_addr] +// +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_load_si128 +FORCE_INLINE __m128i _mm_stream_load_si128(__m128i *p) +{ +#if __has_builtin(__builtin_nontemporal_store) + return __builtin_nontemporal_load(p); +#else + return vreinterpretq_m128i_s64(vld1q_s64((int64_t *) p)); +#endif +} + +// Compute the bitwise NOT of a and then AND with a 128-bit vector containing +// all 1's, and return 1 if the result is zero, otherwise return 0. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_test_all_ones +FORCE_INLINE int _mm_test_all_ones(__m128i a) +{ + return (uint64_t) (vgetq_lane_s64(a, 0) & vgetq_lane_s64(a, 1)) == + ~(uint64_t) 0; +} + +// Compute the bitwise AND of 128 bits (representing integer data) in a and +// mask, and return 1 if the result is zero, otherwise return 0. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_test_all_zeros +FORCE_INLINE int _mm_test_all_zeros(__m128i a, __m128i mask) +{ + int64x2_t a_and_mask = + vandq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(mask)); + return !(vgetq_lane_s64(a_and_mask, 0) | vgetq_lane_s64(a_and_mask, 1)); +} + +// Compute the bitwise AND of 128 bits (representing integer data) in a and +// mask, and set ZF to 1 if the result is zero, otherwise set ZF to 0. Compute +// the bitwise NOT of a and then AND with mask, and set CF to 1 if the result is +// zero, otherwise set CF to 0. Return 1 if both the ZF and CF values are zero, +// otherwise return 0. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=mm_test_mix_ones_zero +FORCE_INLINE int _mm_test_mix_ones_zeros(__m128i a, __m128i mask) +{ + uint64x2_t zf = + vandq_u64(vreinterpretq_u64_m128i(mask), vreinterpretq_u64_m128i(a)); + uint64x2_t cf = + vbicq_u64(vreinterpretq_u64_m128i(mask), vreinterpretq_u64_m128i(a)); + uint64x2_t result = vandq_u64(zf, cf); + return !(vgetq_lane_u64(result, 0) | vgetq_lane_u64(result, 1)); +} + // Compute the bitwise AND of 128 bits (representing integer data) in a and b, // and set ZF to 1 if the result is zero, otherwise set ZF to 0. Compute the // bitwise NOT of a and then AND with b, and set CF to 1 if the result is zero, @@ -6850,6 +8327,14 @@ FORCE_INLINE int _mm_testc_si128(__m128i a, __m128i b) return !(vgetq_lane_s64(s64, 0) | vgetq_lane_s64(s64, 1)); } +// Compute the bitwise AND of 128 bits (representing integer data) in a and b, +// and set ZF to 1 if the result is zero, otherwise set ZF to 0. Compute the +// bitwise NOT of a and then AND with b, and set CF to 1 if the result is zero, +// otherwise set CF to 0. Return 1 if both the ZF and CF values are zero, +// otherwise return 0. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_testnzc_si128 +#define _mm_testnzc_si128(a, b) _mm_test_mix_ones_zeros(a, b) + // Compute the bitwise AND of 128 bits (representing integer data) in a and b, // and set ZF to 1 if the result is zero, otherwise set ZF to 0. Compute the // bitwise NOT of a and then AND with b, and set CF to 1 if the result is zero, @@ -6862,305 +8347,99 @@ FORCE_INLINE int _mm_testz_si128(__m128i a, __m128i b) return !(vgetq_lane_s64(s64, 0) | vgetq_lane_s64(s64, 1)); } -// Extracts the selected signed or unsigned 8-bit integer from a and zero -// extends. -// FORCE_INLINE int _mm_extract_epi8(__m128i a, __constrange(0,16) int imm) -#define _mm_extract_epi8(a, imm) vgetq_lane_u8(vreinterpretq_u8_m128i(a), (imm)) +/* SSE4.2 */ -// Inserts the least significant 8 bits of b into the selected 8-bit integer -// of a. -// FORCE_INLINE __m128i _mm_insert_epi8(__m128i a, int b, -// __constrange(0,16) int imm) -#define _mm_insert_epi8(a, b, imm) \ - __extension__({ \ - vreinterpretq_m128i_s8( \ - vsetq_lane_s8((b), vreinterpretq_s8_m128i(a), (imm))); \ - }) - -// Extracts the selected signed or unsigned 16-bit integer from a and zero -// extends. -// https://msdn.microsoft.com/en-us/library/6dceta0c(v=vs.100).aspx -// FORCE_INLINE int _mm_extract_epi16(__m128i a, __constrange(0,8) int imm) -#define _mm_extract_epi16(a, imm) \ - vgetq_lane_u16(vreinterpretq_u16_m128i(a), (imm)) - -// Extract a 16-bit integer from a, selected with imm8, and store the result in -// the lower element of dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_extract_pi16 -#define _mm_extract_pi16(a, imm) \ - (int32_t) vget_lane_u16(vreinterpret_u16_m64(a), (imm)) - -// Inserts the least significant 16 bits of b into the selected 16-bit integer -// of a. -// https://msdn.microsoft.com/en-us/library/kaze8hz1%28v=vs.100%29.aspx -// FORCE_INLINE __m128i _mm_insert_epi16(__m128i a, int b, -// __constrange(0,8) int imm) -#define _mm_insert_epi16(a, b, imm) \ - __extension__({ \ - vreinterpretq_m128i_s16( \ - vsetq_lane_s16((b), vreinterpretq_s16_m128i(a), (imm))); \ - }) - -// Copy a to dst, and insert the 16-bit integer i into dst at the location -// specified by imm8. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_insert_pi16 -#define _mm_insert_pi16(a, b, imm) \ - __extension__({ \ - vreinterpret_m64_s16( \ - vset_lane_s16((b), vreinterpret_s16_m64(a), (imm))); \ - }) - -// Extracts the selected signed or unsigned 32-bit integer from a and zero -// extends. -// FORCE_INLINE int _mm_extract_epi32(__m128i a, __constrange(0,4) int imm) -#define _mm_extract_epi32(a, imm) \ - vgetq_lane_s32(vreinterpretq_s32_m128i(a), (imm)) - -// Extracts the selected single-precision (32-bit) floating-point from a. -// FORCE_INLINE int _mm_extract_ps(__m128 a, __constrange(0,4) int imm) -#define _mm_extract_ps(a, imm) vgetq_lane_s32(vreinterpretq_s32_m128(a), (imm)) - -// Inserts the least significant 32 bits of b into the selected 32-bit integer -// of a. -// FORCE_INLINE __m128i _mm_insert_epi32(__m128i a, int b, -// __constrange(0,4) int imm) -#define _mm_insert_epi32(a, b, imm) \ - __extension__({ \ - vreinterpretq_m128i_s32( \ - vsetq_lane_s32((b), vreinterpretq_s32_m128i(a), (imm))); \ - }) - -// Extracts the selected signed or unsigned 64-bit integer from a and zero -// extends. -// FORCE_INLINE __int64 _mm_extract_epi64(__m128i a, __constrange(0,2) int imm) -#define _mm_extract_epi64(a, imm) \ - vgetq_lane_s64(vreinterpretq_s64_m128i(a), (imm)) - -// Inserts the least significant 64 bits of b into the selected 64-bit integer -// of a. -// FORCE_INLINE __m128i _mm_insert_epi64(__m128i a, __int64 b, -// __constrange(0,2) int imm) -#define _mm_insert_epi64(a, b, imm) \ - __extension__({ \ - vreinterpretq_m128i_s64( \ - vsetq_lane_s64((b), vreinterpretq_s64_m128i(a), (imm))); \ - }) - -// Count the number of bits set to 1 in unsigned 32-bit integer a, and -// return that count in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_popcnt_u32 -FORCE_INLINE int _mm_popcnt_u32(unsigned int a) +// Compares the 2 signed 64-bit integers in a and the 2 signed 64-bit integers +// in b for greater than. +FORCE_INLINE __m128i _mm_cmpgt_epi64(__m128i a, __m128i b) { #if defined(__aarch64__) -#if __has_builtin(__builtin_popcount) - return __builtin_popcount(a); + return vreinterpretq_m128i_u64( + vcgtq_s64(vreinterpretq_s64_m128i(a), vreinterpretq_s64_m128i(b))); #else - return (int) vaddlv_u8(vcnt_u8(vcreate_u8((uint64_t) a))); -#endif -#else - uint32_t count = 0; - uint8x8_t input_val, count8x8_val; - uint16x4_t count16x4_val; - uint32x2_t count32x2_val; - - input_val = vld1_u8((uint8_t *) &a); - count8x8_val = vcnt_u8(input_val); - count16x4_val = vpaddl_u8(count8x8_val); - count32x2_val = vpaddl_u16(count16x4_val); - - vst1_u32(&count, count32x2_val); - return count; + return vreinterpretq_m128i_s64(vshrq_n_s64( + vqsubq_s64(vreinterpretq_s64_m128i(b), vreinterpretq_s64_m128i(a)), + 63)); #endif } -// Count the number of bits set to 1 in unsigned 64-bit integer a, and -// return that count in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_popcnt_u64 -FORCE_INLINE int64_t _mm_popcnt_u64(uint64_t a) +// Starting with the initial value in crc, accumulates a CRC32 value for +// unsigned 16-bit integer v. +// https://msdn.microsoft.com/en-us/library/bb531411(v=vs.100) +FORCE_INLINE uint32_t _mm_crc32_u16(uint32_t crc, uint16_t v) { -#if defined(__aarch64__) -#if __has_builtin(__builtin_popcountll) - return __builtin_popcountll(a); +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) + __asm__ __volatile__("crc32ch %w[c], %w[c], %w[v]\n\t" + : [c] "+r"(crc) + : [v] "r"(v)); +#elif (__ARM_ARCH == 8) && defined(__ARM_FEATURE_CRC32) + crc = __crc32ch(crc, v); #else - return (int64_t) vaddlv_u8(vcnt_u8(vcreate_u8(a))); -#endif -#else - uint64_t count = 0; - uint8x8_t input_val, count8x8_val; - uint16x4_t count16x4_val; - uint32x2_t count32x2_val; - uint64x1_t count64x1_val; - - input_val = vld1_u8((uint8_t *) &a); - count8x8_val = vcnt_u8(input_val); - count16x4_val = vpaddl_u8(count8x8_val); - count32x2_val = vpaddl_u16(count16x4_val); - count64x1_val = vpaddl_u32(count32x2_val); - vst1_u64(&count, count64x1_val); - return count; + crc = _mm_crc32_u8(crc, v & 0xff); + crc = _mm_crc32_u8(crc, (v >> 8) & 0xff); #endif + return crc; } -// Macro: Transpose the 4x4 matrix formed by the 4 rows of single-precision -// (32-bit) floating-point elements in row0, row1, row2, and row3, and store the -// transposed matrix in these vectors (row0 now contains column 0, etc.). -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=MM_TRANSPOSE4_PS -#define _MM_TRANSPOSE4_PS(row0, row1, row2, row3) \ - do { \ - float32x4x2_t ROW01 = vtrnq_f32(row0, row1); \ - float32x4x2_t ROW23 = vtrnq_f32(row2, row3); \ - row0 = vcombine_f32(vget_low_f32(ROW01.val[0]), \ - vget_low_f32(ROW23.val[0])); \ - row1 = vcombine_f32(vget_low_f32(ROW01.val[1]), \ - vget_low_f32(ROW23.val[1])); \ - row2 = vcombine_f32(vget_high_f32(ROW01.val[0]), \ - vget_high_f32(ROW23.val[0])); \ - row3 = vcombine_f32(vget_high_f32(ROW01.val[1]), \ - vget_high_f32(ROW23.val[1])); \ - } while (0) - -/* Crypto Extensions */ - -#if defined(__ARM_FEATURE_CRYPTO) -// Wraps vmull_p64 -FORCE_INLINE uint64x2_t _sse2neon_vmull_p64(uint64x1_t _a, uint64x1_t _b) +// Starting with the initial value in crc, accumulates a CRC32 value for +// unsigned 32-bit integer v. +// https://msdn.microsoft.com/en-us/library/bb531394(v=vs.100) +FORCE_INLINE uint32_t _mm_crc32_u32(uint32_t crc, uint32_t v) { - poly64_t a = vget_lane_p64(vreinterpret_p64_u64(_a), 0); - poly64_t b = vget_lane_p64(vreinterpret_p64_u64(_b), 0); - return vreinterpretq_u64_p128(vmull_p64(a, b)); -} -#else // ARMv7 polyfill -// ARMv7/some A64 lacks vmull_p64, but it has vmull_p8. -// -// vmull_p8 calculates 8 8-bit->16-bit polynomial multiplies, but we need a -// 64-bit->128-bit polynomial multiply. -// -// It needs some work and is somewhat slow, but it is still faster than all -// known scalar methods. -// -// Algorithm adapted to C from -// https://www.workofard.com/2017/07/ghash-for-low-end-cores/, which is adapted -// from "Fast Software Polynomial Multiplication on ARM Processors Using the -// NEON Engine" by Danilo Camara, Conrado Gouvea, Julio Lopez and Ricardo Dahab -// (https://hal.inria.fr/hal-01506572) -static uint64x2_t _sse2neon_vmull_p64(uint64x1_t _a, uint64x1_t _b) -{ - poly8x8_t a = vreinterpret_p8_u64(_a); - poly8x8_t b = vreinterpret_p8_u64(_b); - - // Masks - uint8x16_t k48_32 = vcombine_u8(vcreate_u8(0x0000ffffffffffff), - vcreate_u8(0x00000000ffffffff)); - uint8x16_t k16_00 = vcombine_u8(vcreate_u8(0x000000000000ffff), - vcreate_u8(0x0000000000000000)); - - // Do the multiplies, rotating with vext to get all combinations - uint8x16_t d = vreinterpretq_u8_p16(vmull_p8(a, b)); // D = A0 * B0 - uint8x16_t e = - vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 1))); // E = A0 * B1 - uint8x16_t f = - vreinterpretq_u8_p16(vmull_p8(vext_p8(a, a, 1), b)); // F = A1 * B0 - uint8x16_t g = - vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 2))); // G = A0 * B2 - uint8x16_t h = - vreinterpretq_u8_p16(vmull_p8(vext_p8(a, a, 2), b)); // H = A2 * B0 - uint8x16_t i = - vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 3))); // I = A0 * B3 - uint8x16_t j = - vreinterpretq_u8_p16(vmull_p8(vext_p8(a, a, 3), b)); // J = A3 * B0 - uint8x16_t k = - vreinterpretq_u8_p16(vmull_p8(a, vext_p8(b, b, 4))); // L = A0 * B4 - - // Add cross products - uint8x16_t l = veorq_u8(e, f); // L = E + F - uint8x16_t m = veorq_u8(g, h); // M = G + H - uint8x16_t n = veorq_u8(i, j); // N = I + J - - // Interleave. Using vzip1 and vzip2 prevents Clang from emitting TBL - // instructions. -#if defined(__aarch64__) - uint8x16_t lm_p0 = vreinterpretq_u8_u64( - vzip1q_u64(vreinterpretq_u64_u8(l), vreinterpretq_u64_u8(m))); - uint8x16_t lm_p1 = vreinterpretq_u8_u64( - vzip2q_u64(vreinterpretq_u64_u8(l), vreinterpretq_u64_u8(m))); - uint8x16_t nk_p0 = vreinterpretq_u8_u64( - vzip1q_u64(vreinterpretq_u64_u8(n), vreinterpretq_u64_u8(k))); - uint8x16_t nk_p1 = vreinterpretq_u8_u64( - vzip2q_u64(vreinterpretq_u64_u8(n), vreinterpretq_u64_u8(k))); +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) + __asm__ __volatile__("crc32cw %w[c], %w[c], %w[v]\n\t" + : [c] "+r"(crc) + : [v] "r"(v)); +#elif (__ARM_ARCH == 8) && defined(__ARM_FEATURE_CRC32) + crc = __crc32cw(crc, v); #else - uint8x16_t lm_p0 = vcombine_u8(vget_low_u8(l), vget_low_u8(m)); - uint8x16_t lm_p1 = vcombine_u8(vget_high_u8(l), vget_high_u8(m)); - uint8x16_t nk_p0 = vcombine_u8(vget_low_u8(n), vget_low_u8(k)); - uint8x16_t nk_p1 = vcombine_u8(vget_high_u8(n), vget_high_u8(k)); + crc = _mm_crc32_u16(crc, v & 0xffff); + crc = _mm_crc32_u16(crc, (v >> 16) & 0xffff); #endif - // t0 = (L) (P0 + P1) << 8 - // t1 = (M) (P2 + P3) << 16 - uint8x16_t t0t1_tmp = veorq_u8(lm_p0, lm_p1); - uint8x16_t t0t1_h = vandq_u8(lm_p1, k48_32); - uint8x16_t t0t1_l = veorq_u8(t0t1_tmp, t0t1_h); - - // t2 = (N) (P4 + P5) << 24 - // t3 = (K) (P6 + P7) << 32 - uint8x16_t t2t3_tmp = veorq_u8(nk_p0, nk_p1); - uint8x16_t t2t3_h = vandq_u8(nk_p1, k16_00); - uint8x16_t t2t3_l = veorq_u8(t2t3_tmp, t2t3_h); - - // De-interleave -#if defined(__aarch64__) - uint8x16_t t0 = vreinterpretq_u8_u64( - vuzp1q_u64(vreinterpretq_u64_u8(t0t1_l), vreinterpretq_u64_u8(t0t1_h))); - uint8x16_t t1 = vreinterpretq_u8_u64( - vuzp2q_u64(vreinterpretq_u64_u8(t0t1_l), vreinterpretq_u64_u8(t0t1_h))); - uint8x16_t t2 = vreinterpretq_u8_u64( - vuzp1q_u64(vreinterpretq_u64_u8(t2t3_l), vreinterpretq_u64_u8(t2t3_h))); - uint8x16_t t3 = vreinterpretq_u8_u64( - vuzp2q_u64(vreinterpretq_u64_u8(t2t3_l), vreinterpretq_u64_u8(t2t3_h))); -#else - uint8x16_t t1 = vcombine_u8(vget_high_u8(t0t1_l), vget_high_u8(t0t1_h)); - uint8x16_t t0 = vcombine_u8(vget_low_u8(t0t1_l), vget_low_u8(t0t1_h)); - uint8x16_t t3 = vcombine_u8(vget_high_u8(t2t3_l), vget_high_u8(t2t3_h)); - uint8x16_t t2 = vcombine_u8(vget_low_u8(t2t3_l), vget_low_u8(t2t3_h)); -#endif - // Shift the cross products - uint8x16_t t0_shift = vextq_u8(t0, t0, 15); // t0 << 8 - uint8x16_t t1_shift = vextq_u8(t1, t1, 14); // t1 << 16 - uint8x16_t t2_shift = vextq_u8(t2, t2, 13); // t2 << 24 - uint8x16_t t3_shift = vextq_u8(t3, t3, 12); // t3 << 32 - - // Accumulate the products - uint8x16_t cross1 = veorq_u8(t0_shift, t1_shift); - uint8x16_t cross2 = veorq_u8(t2_shift, t3_shift); - uint8x16_t mix = veorq_u8(d, cross1); - uint8x16_t r = veorq_u8(mix, cross2); - return vreinterpretq_u64_u8(r); + return crc; } -#endif // ARMv7 polyfill -// Perform a carry-less multiplication of two 64-bit integers, selected from a -// and b according to imm8, and store the results in dst. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_clmulepi64_si128 -FORCE_INLINE __m128i _mm_clmulepi64_si128(__m128i _a, __m128i _b, const int imm) +// Starting with the initial value in crc, accumulates a CRC32 value for +// unsigned 64-bit integer v. +// https://msdn.microsoft.com/en-us/library/bb514033(v=vs.100) +FORCE_INLINE uint64_t _mm_crc32_u64(uint64_t crc, uint64_t v) { - uint64x2_t a = vreinterpretq_u64_m128i(_a); - uint64x2_t b = vreinterpretq_u64_m128i(_b); - switch (imm & 0x11) { - case 0x00: - return vreinterpretq_m128i_u64( - _sse2neon_vmull_p64(vget_low_u64(a), vget_low_u64(b))); - case 0x01: - return vreinterpretq_m128i_u64( - _sse2neon_vmull_p64(vget_high_u64(a), vget_low_u64(b))); - case 0x10: - return vreinterpretq_m128i_u64( - _sse2neon_vmull_p64(vget_low_u64(a), vget_high_u64(b))); - case 0x11: - return vreinterpretq_m128i_u64( - _sse2neon_vmull_p64(vget_high_u64(a), vget_high_u64(b))); - default: - abort(); +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) + __asm__ __volatile__("crc32cx %w[c], %w[c], %x[v]\n\t" + : [c] "+r"(crc) + : [v] "r"(v)); +#else + crc = _mm_crc32_u32((uint32_t) (crc), v & 0xffffffff); + crc = _mm_crc32_u32((uint32_t) (crc), (v >> 32) & 0xffffffff); +#endif + return crc; +} + +// Starting with the initial value in crc, accumulates a CRC32 value for +// unsigned 8-bit integer v. +// https://msdn.microsoft.com/en-us/library/bb514036(v=vs.100) +FORCE_INLINE uint32_t _mm_crc32_u8(uint32_t crc, uint8_t v) +{ +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) + __asm__ __volatile__("crc32cb %w[c], %w[c], %w[v]\n\t" + : [c] "+r"(crc) + : [v] "r"(v)); +#elif (__ARM_ARCH == 8) && defined(__ARM_FEATURE_CRC32) + crc = __crc32cb(crc, v); +#else + crc ^= v; + for (int bit = 0; bit < 8; bit++) { + if (crc & 1) + crc = (crc >> 1) ^ UINT32_C(0x82f63b78); + else + crc = (crc >> 1); } +#endif + return crc; } +/* AES */ + #if !defined(__ARM_FEATURE_CRYPTO) /* clang-format off */ #define SSE2NEON_AES_DATA(w) \ @@ -7238,7 +8517,7 @@ FORCE_INLINE __m128i _mm_aesenc_si128(__m128i EncBlock, __m128i RoundKey) v = vqtbx4q_u8(v, _sse2neon_vld1q_u8_x4(SSE2NEON_sbox + 0xc0), w - 0xc0); // mix columns - w = (v << 1) ^ (uint8x16_t)(((int8x16_t) v >> 7) & 0x1b); + w = (v << 1) ^ (uint8x16_t) (((int8x16_t) v >> 7) & 0x1b); w ^= (uint8x16_t) vrev32q_u16((uint16x8_t) v); w ^= vqtbl1q_u8(v ^ w, vld1q_u8(ror32by8)); @@ -7246,9 +8525,9 @@ FORCE_INLINE __m128i _mm_aesenc_si128(__m128i EncBlock, __m128i RoundKey) return vreinterpretq_m128i_u8(w) ^ RoundKey; #else /* ARMv7-A NEON implementation */ -#define SSE2NEON_AES_B2W(b0, b1, b2, b3) \ - (((uint32_t)(b3) << 24) | ((uint32_t)(b2) << 16) | ((uint32_t)(b1) << 8) | \ - (b0)) +#define SSE2NEON_AES_B2W(b0, b1, b2, b3) \ + (((uint32_t) (b3) << 24) | ((uint32_t) (b2) << 16) | \ + ((uint32_t) (b1) << 8) | (uint32_t) (b0)) #define SSE2NEON_AES_F2(x) ((x << 1) ^ (((x >> 7) & 1) * 0x011b /* WPOLY */)) #define SSE2NEON_AES_F3(x) (SSE2NEON_AES_F2(x) ^ x) #define SSE2NEON_AES_U0(p) \ @@ -7299,22 +8578,22 @@ FORCE_INLINE __m128i _mm_aesenclast_si128(__m128i a, __m128i RoundKey) { /* FIXME: optimized for NEON */ uint8_t v[4][4] = { - [0] = {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 0)], - SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 5)], - SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 10)], - SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 15)]}, - [1] = {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 4)], - SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 9)], - SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 14)], - SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 3)]}, - [2] = {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 8)], - SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 13)], - SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 2)], - SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 7)]}, - [3] = {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 12)], - SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 1)], - SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 6)], - SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 11)]}, + {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 0)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 5)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 10)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 15)]}, + {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 4)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 9)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 14)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 3)]}, + {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 8)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 13)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 2)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 7)]}, + {SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 12)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 1)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 6)], + SSE2NEON_sbox[vreinterpretq_nth_u8_m128i(a, 11)]}, }; for (int i = 0; i < 16; i++) vreinterpretq_nth_u8_m128i(a, i) = @@ -7380,211 +8659,135 @@ FORCE_INLINE __m128i _mm_aeskeygenassist_si128(__m128i a, const int rcon) } #endif -/* Streaming Extensions */ +/* Others */ -// Guarantees that every preceding store is globally visible before any -// subsequent store. -// https://msdn.microsoft.com/en-us/library/5h2w73d1%28v=vs.90%29.aspx -FORCE_INLINE void _mm_sfence(void) +// Perform a carry-less multiplication of two 64-bit integers, selected from a +// and b according to imm8, and store the results in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_clmulepi64_si128 +FORCE_INLINE __m128i _mm_clmulepi64_si128(__m128i _a, __m128i _b, const int imm) { - __sync_synchronize(); -} - -// Store 64-bits of integer data from a into memory using a non-temporal memory -// hint. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_pi -FORCE_INLINE void _mm_stream_pi(__m64 *p, __m64 a) -{ - vst1_s64((int64_t *) p, vreinterpret_s64_m64(a)); -} - -// Store 128-bits (composed of 4 packed single-precision (32-bit) floating- -// point elements) from a into memory using a non-temporal memory hint. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_ps -FORCE_INLINE void _mm_stream_ps(float *p, __m128 a) -{ -#if __has_builtin(__builtin_nontemporal_store) - __builtin_nontemporal_store(a, (float32x4_t *) p); -#else - vst1q_f32(p, vreinterpretq_f32_m128(a)); -#endif -} - -// Store 128-bits (composed of 2 packed double-precision (64-bit) floating-point -// elements) from a into memory using a non-temporal memory hint. mem_addr must -// be aligned on a 16-byte boundary or a general-protection exception may be -// generated. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_pd -FORCE_INLINE void _mm_stream_pd(double *p, __m128d a) -{ -#if __has_builtin(__builtin_nontemporal_store) - __builtin_nontemporal_store(a, (float32x4_t *) p); -#elif defined(__aarch64__) - vst1q_f64(p, vreinterpretq_f64_m128d(a)); -#else - vst1q_s64((int64_t *) p, vreinterpretq_s64_m128d(a)); -#endif -} - -// Stores the data in a to the address p without polluting the caches. If the -// cache line containing address p is already in the cache, the cache will be -// updated. -// https://msdn.microsoft.com/en-us/library/ba08y07y%28v=vs.90%29.aspx -FORCE_INLINE void _mm_stream_si128(__m128i *p, __m128i a) -{ -#if __has_builtin(__builtin_nontemporal_store) - __builtin_nontemporal_store(a, p); -#else - vst1q_s64((int64_t *) p, vreinterpretq_s64_m128i(a)); -#endif -} - -// Store 32-bit integer a into memory using a non-temporal hint to minimize -// cache pollution. If the cache line containing address mem_addr is already in -// the cache, the cache will be updated. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_si32 -FORCE_INLINE void _mm_stream_si32(int *p, int a) -{ - vst1q_lane_s32((int32_t *) p, vdupq_n_s32(a), 0); -} - -// Load 128-bits of integer data from memory into dst using a non-temporal -// memory hint. mem_addr must be aligned on a 16-byte boundary or a -// general-protection exception may be generated. -// -// dst[127:0] := MEM[mem_addr+127:mem_addr] -// -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_stream_load_si128 -FORCE_INLINE __m128i _mm_stream_load_si128(__m128i *p) -{ -#if __has_builtin(__builtin_nontemporal_store) - return __builtin_nontemporal_load(p); -#else - return vreinterpretq_m128i_s64(vld1q_s64((int64_t *) p)); -#endif -} - -// Cache line containing p is flushed and invalidated from all caches in the -// coherency domain. : -// https://msdn.microsoft.com/en-us/library/ba08y07y(v=vs.100).aspx -FORCE_INLINE void _mm_clflush(void const *p) -{ - (void) p; - // no corollary for Neon? -} - -// Allocate aligned blocks of memory. -// https://software.intel.com/en-us/ -// cpp-compiler-developer-guide-and-reference-allocating-and-freeing-aligned-memory-blocks -FORCE_INLINE void *_mm_malloc(size_t size, size_t align) -{ - void *ptr; - if (align == 1) - return malloc(size); - if (align == 2 || (sizeof(void *) == 8 && align == 4)) - align = sizeof(void *); - if (!posix_memalign(&ptr, align, size)) - return ptr; - return NULL; -} - -// Conditionally store 8-bit integer elements from a into memory using mask -// (elements are not stored when the highest bit is not set in the corresponding -// element) and a non-temporal memory hint. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_maskmove_si64 -FORCE_INLINE void _mm_maskmove_si64(__m64 a, __m64 mask, char *mem_addr) -{ - int8x8_t shr_mask = vshr_n_s8(vreinterpret_s8_m64(mask), 7); - __m128 b = _mm_load_ps((const float *) mem_addr); - int8x8_t masked = - vbsl_s8(vreinterpret_u8_s8(shr_mask), vreinterpret_s8_m64(a), - vreinterpret_s8_u64(vget_low_u64(vreinterpretq_u64_m128(b)))); - vst1_s8((int8_t *) mem_addr, masked); -} - -// Conditionally store 8-bit integer elements from a into memory using mask -// (elements are not stored when the highest bit is not set in the corresponding -// element) and a non-temporal memory hint. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_m_maskmovq -#define _m_maskmovq(a, mask, mem_addr) _mm_maskmove_si64(a, mask, mem_addr) - -// Free aligned memory that was allocated with _mm_malloc. -// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_free -FORCE_INLINE void _mm_free(void *addr) -{ - free(addr); -} - -// Starting with the initial value in crc, accumulates a CRC32 value for -// unsigned 8-bit integer v. -// https://msdn.microsoft.com/en-us/library/bb514036(v=vs.100) -FORCE_INLINE uint32_t _mm_crc32_u8(uint32_t crc, uint8_t v) -{ -#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) - __asm__ __volatile__("crc32cb %w[c], %w[c], %w[v]\n\t" - : [c] "+r"(crc) - : [v] "r"(v)); -#else - crc ^= v; - for (int bit = 0; bit < 8; bit++) { - if (crc & 1) - crc = (crc >> 1) ^ UINT32_C(0x82f63b78); - else - crc = (crc >> 1); + uint64x2_t a = vreinterpretq_u64_m128i(_a); + uint64x2_t b = vreinterpretq_u64_m128i(_b); + switch (imm & 0x11) { + case 0x00: + return vreinterpretq_m128i_u64( + _sse2neon_vmull_p64(vget_low_u64(a), vget_low_u64(b))); + case 0x01: + return vreinterpretq_m128i_u64( + _sse2neon_vmull_p64(vget_high_u64(a), vget_low_u64(b))); + case 0x10: + return vreinterpretq_m128i_u64( + _sse2neon_vmull_p64(vget_low_u64(a), vget_high_u64(b))); + case 0x11: + return vreinterpretq_m128i_u64( + _sse2neon_vmull_p64(vget_high_u64(a), vget_high_u64(b))); + default: + abort(); } -#endif - return crc; } -// Starting with the initial value in crc, accumulates a CRC32 value for -// unsigned 16-bit integer v. -// https://msdn.microsoft.com/en-us/library/bb531411(v=vs.100) -FORCE_INLINE uint32_t _mm_crc32_u16(uint32_t crc, uint16_t v) +FORCE_INLINE unsigned int _sse2neon_mm_get_denormals_zero_mode() { -#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) - __asm__ __volatile__("crc32ch %w[c], %w[c], %w[v]\n\t" - : [c] "+r"(crc) - : [v] "r"(v)); + union { + fpcr_bitfield field; +#if defined(__aarch64__) + uint64_t value; #else - crc = _mm_crc32_u8(crc, v & 0xff); - crc = _mm_crc32_u8(crc, (v >> 8) & 0xff); + uint32_t value; #endif - return crc; + } r; + +#if defined(__aarch64__) + __asm__ __volatile__("mrs %0, FPCR" : "=r"(r.value)); /* read */ +#else + __asm__ __volatile__("vmrs %0, FPSCR" : "=r"(r.value)); /* read */ +#endif + + return r.field.bit24 ? _MM_DENORMALS_ZERO_ON : _MM_DENORMALS_ZERO_OFF; } -// Starting with the initial value in crc, accumulates a CRC32 value for -// unsigned 32-bit integer v. -// https://msdn.microsoft.com/en-us/library/bb531394(v=vs.100) -FORCE_INLINE uint32_t _mm_crc32_u32(uint32_t crc, uint32_t v) +// Count the number of bits set to 1 in unsigned 32-bit integer a, and +// return that count in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_popcnt_u32 +FORCE_INLINE int _mm_popcnt_u32(unsigned int a) { -#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) - __asm__ __volatile__("crc32cw %w[c], %w[c], %w[v]\n\t" - : [c] "+r"(crc) - : [v] "r"(v)); +#if defined(__aarch64__) +#if __has_builtin(__builtin_popcount) + return __builtin_popcount(a); #else - crc = _mm_crc32_u16(crc, v & 0xffff); - crc = _mm_crc32_u16(crc, (v >> 16) & 0xffff); + return (int) vaddlv_u8(vcnt_u8(vcreate_u8((uint64_t) a))); +#endif +#else + uint32_t count = 0; + uint8x8_t input_val, count8x8_val; + uint16x4_t count16x4_val; + uint32x2_t count32x2_val; + + input_val = vld1_u8((uint8_t *) &a); + count8x8_val = vcnt_u8(input_val); + count16x4_val = vpaddl_u8(count8x8_val); + count32x2_val = vpaddl_u16(count16x4_val); + + vst1_u32(&count, count32x2_val); + return count; #endif - return crc; } -// Starting with the initial value in crc, accumulates a CRC32 value for -// unsigned 64-bit integer v. -// https://msdn.microsoft.com/en-us/library/bb514033(v=vs.100) -FORCE_INLINE uint64_t _mm_crc32_u64(uint64_t crc, uint64_t v) +// Count the number of bits set to 1 in unsigned 64-bit integer a, and +// return that count in dst. +// https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_mm_popcnt_u64 +FORCE_INLINE int64_t _mm_popcnt_u64(uint64_t a) { -#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32) - __asm__ __volatile__("crc32cx %w[c], %w[c], %x[v]\n\t" - : [c] "+r"(crc) - : [v] "r"(v)); +#if defined(__aarch64__) +#if __has_builtin(__builtin_popcountll) + return __builtin_popcountll(a); #else - crc = _mm_crc32_u32((uint32_t)(crc), v & 0xffffffff); - crc = _mm_crc32_u32((uint32_t)(crc), (v >> 32) & 0xffffffff); + return (int64_t) vaddlv_u8(vcnt_u8(vcreate_u8(a))); +#endif +#else + uint64_t count = 0; + uint8x8_t input_val, count8x8_val; + uint16x4_t count16x4_val; + uint32x2_t count32x2_val; + uint64x1_t count64x1_val; + + input_val = vld1_u8((uint8_t *) &a); + count8x8_val = vcnt_u8(input_val); + count16x4_val = vpaddl_u8(count8x8_val); + count32x2_val = vpaddl_u16(count16x4_val); + count64x1_val = vpaddl_u32(count32x2_val); + vst1_u64(&count, count64x1_val); + return count; #endif - return crc; } -FORCE_INLINE void _mm_empty (void) { } +FORCE_INLINE void _sse2neon_mm_set_denormals_zero_mode(unsigned int flag) +{ + // AArch32 Advanced SIMD arithmetic always uses the Flush-to-zero setting, + // regardless of the value of the FZ bit. + union { + fpcr_bitfield field; +#if defined(__aarch64__) + uint64_t value; +#else + uint32_t value; +#endif + } r; + +#if defined(__aarch64__) + __asm__ __volatile__("mrs %0, FPCR" : "=r"(r.value)); /* read */ +#else + __asm__ __volatile__("vmrs %0, FPSCR" : "=r"(r.value)); /* read */ +#endif + + r.field.bit24 = (flag & _MM_DENORMALS_ZERO_MASK) == _MM_DENORMALS_ZERO_ON; + +#if defined(__aarch64__) + __asm__ __volatile__("msr FPCR, %0" ::"r"(r)); /* write */ +#else + __asm__ __volatile__("vmsr FPSCR, %0" ::"r"(r)); /* write */ +#endif +} #if defined(__GNUC__) || defined(__clang__) #pragma pop_macro("ALIGN_STRUCT") diff --git a/common/studiobyteswap.cpp b/common/studiobyteswap.cpp index e99d16ae..9462bdbd 100644 --- a/common/studiobyteswap.cpp +++ b/common/studiobyteswap.cpp @@ -16,10 +16,10 @@ #undef ALIGN4 #undef ALIGN16 #undef ALIGN32 -#define ALIGN4( a ) a = (byte *)((int)((byte *)a + 3) & ~ 3) -#define ALIGN16( a ) a = (byte *)((int)((byte *)a + 15) & ~ 15) -#define ALIGN32( a ) a = (byte *)((int)((byte *)a + 31) & ~ 31) -#define ALIGN64( a ) a = (byte *)((int)((byte *)a + 63) & ~ 63) +#define ALIGN4( a ) a = (byte *)((intp)((byte *)a + 3) & ~ 3) +#define ALIGN16( a ) a = (byte *)((intp)((byte *)a + 15) & ~ 15) +#define ALIGN32( a ) a = (byte *)((intp)((byte *)a + 31) & ~ 31) +#define ALIGN64( a ) a = (byte *)((intp)((byte *)a + 63) & ~ 63) // Fixup macros create variables that may not be referenced #pragma warning( push ) @@ -1228,8 +1228,8 @@ int ByteswapANI( studiohdr_t* pHdr, void *pDestBase, const void *pSrcBase, const V_memcpy( pNewDest, pDestBase, pAnimBlock->datastart ); pNewDest += pAnimBlock->datastart; - int padding = AlignValue( (unsigned int)pNewDest - (unsigned int)pNewDestBase, 2048 ); - padding -= (unsigned int)pNewDest - (unsigned int)pNewDestBase; + int padding = AlignValue( (uintp)pNewDest - (uintp)pNewDestBase, 2048 ); + padding -= (uintp)pNewDest - (uintp)pNewDestBase; pNewDest += padding; // iterate and compress anim blocks @@ -1240,7 +1240,7 @@ int ByteswapANI( studiohdr_t* pHdr, void *pDestBase, const void *pSrcBase, const void *pInput = (byte *)pDestBase + pAnimBlock->datastart; int inputSize = pAnimBlock->dataend - pAnimBlock->datastart; - pAnimBlock->datastart = (unsigned int)pNewDest - (unsigned int)pNewDestBase; + pAnimBlock->datastart = (uintp)pNewDest - (uintp)pNewDestBase; void *pOutput; int outputSize; @@ -1257,11 +1257,11 @@ int ByteswapANI( studiohdr_t* pHdr, void *pDestBase, const void *pSrcBase, const pNewDest += inputSize; } - padding = AlignValue( (unsigned int)pNewDest - (unsigned int)pNewDestBase, 2048 ); - padding -= (unsigned int)pNewDest - (unsigned int)pNewDestBase; + padding = AlignValue( (uintp)pNewDest - (uintp)pNewDestBase, 2048 ); + padding -= (uintp)pNewDest - (uintp)pNewDestBase; pNewDest += padding; - pAnimBlock->dataend = (unsigned int)pNewDest - (unsigned int)pNewDestBase; + pAnimBlock->dataend = (uintp)pNewDest - (uintp)pNewDestBase; } fixedFileSize = pNewDest - pNewDestBase; @@ -2522,14 +2522,14 @@ BEGIN_BYTESWAP_DATADESC( studiohdr_t ) DEFINE_FIELD( contents, FIELD_INTEGER ), DEFINE_FIELD( numincludemodels, FIELD_INTEGER ), DEFINE_INDEX( includemodelindex, FIELD_INTEGER ), - DEFINE_FIELD( virtualModel, FIELD_INTEGER ), // void* + DEFINE_FIELD( unused_virtualModel, FIELD_INTEGER ), // void* DEFINE_INDEX( szanimblocknameindex, FIELD_INTEGER ), DEFINE_FIELD( numanimblocks, FIELD_INTEGER ), DEFINE_INDEX( animblockindex, FIELD_INTEGER ), - DEFINE_FIELD( animblockModel, FIELD_INTEGER ), // void* + DEFINE_FIELD( unused_animblockModel, FIELD_INTEGER ), // void* DEFINE_INDEX( bonetablebynameindex, FIELD_INTEGER ), - DEFINE_FIELD( pVertexBase, FIELD_INTEGER ), // void* - DEFINE_FIELD( pIndexBase, FIELD_INTEGER ), // void* + DEFINE_FIELD( unused_pVertexBase, FIELD_INTEGER ), // void* + DEFINE_FIELD( unused_pIndexBase, FIELD_INTEGER ), // void* DEFINE_FIELD( constdirectionallightdot, FIELD_CHARACTER ), // byte DEFINE_FIELD( rootLOD, FIELD_CHARACTER ), // byte DEFINE_FIELD( numAllowedRootLODs, FIELD_CHARACTER ), // byte @@ -2985,7 +2985,11 @@ BEGIN_BYTESWAP_DATADESC( mstudiomesh_t ) END_BYTESWAP_DATADESC() BEGIN_BYTESWAP_DATADESC( mstudio_meshvertexdata_t ) +#ifdef PLATFORM_64BITS + DEFINE_FIELD( index_ptr_modelvertexdata, FIELD_INTEGER ), // mstudio_modelvertexdata_t* +#else DEFINE_FIELD( modelvertexdata, FIELD_INTEGER ), // mstudio_modelvertexdata_t* +#endif DEFINE_ARRAY( numLODVertexes, FIELD_INTEGER, MAX_NUM_LODS ), END_BYTESWAP_DATADESC() diff --git a/common/vgui_surfacelib/FontManager.h b/common/vgui_surfacelib/FontManager.h index 56471364..0d7d1e58 100644 --- a/common/vgui_surfacelib/FontManager.h +++ b/common/vgui_surfacelib/FontManager.h @@ -17,7 +17,7 @@ #include "filesystem.h" #include "vguifont.h" -#ifdef LINUX +#if defined(LINUX) || defined(OSX) #include #include FT_FREETYPE_H typedef void *(*FontDataHelper)( const char *pchFontName, int &size, const char *fontFileName ); @@ -71,7 +71,7 @@ public: IFileSystem *FileSystem() { return m_pFileSystem; } IMaterialSystem *MaterialSystem() { return m_pMaterialSystem; } -#ifdef LINUX +#if defined(LINUX) || defined(OSX) FT_Library GetFontLibraryHandle() { return library; } void SetFontDataHelper( FontDataHelper helper ) { m_pFontDataHelper = helper; } #endif @@ -96,7 +96,7 @@ private: CUtlVector m_FontAmalgams; CUtlVector m_Win32Fonts; -#ifdef LINUX +#if defined(LINUX) || defined(OSX) FT_Library library; FontDataHelper m_pFontDataHelper; #endif diff --git a/common/vgui_surfacelib/vguifont.h b/common/vgui_surfacelib/vguifont.h index 34ee32c8..02374f36 100644 --- a/common/vgui_surfacelib/vguifont.h +++ b/common/vgui_surfacelib/vguifont.h @@ -23,10 +23,7 @@ struct newChar_t #ifdef WIN32 #include "Win32Font.h" typedef CWin32Font font_t; -#elif defined(OSX) -#include "osxfont.h" -typedef COSXFont font_t; -#elif defined(LINUX) +#elif defined(LINUX) || defined(OSX) #include "linuxfont.h" typedef CLinuxFont font_t; #else diff --git a/datacache/datacache.h b/datacache/datacache.h index 56b77109..2bbc0e45 100644 --- a/datacache/datacache.h +++ b/datacache/datacache.h @@ -39,7 +39,7 @@ struct DataCacheItemData_t //------------------------------------- -#define DC_NO_NEXT_LOCKED ((DataCacheItem_t *)0xffffffff) +#define DC_NO_NEXT_LOCKED ((DataCacheItem_t *)-1) #define DC_MAX_THREADS_FRAMELOCKED 4 struct DataCacheItem_t : DataCacheItemData_t diff --git a/datacache/mdlcache.cpp b/datacache/mdlcache.cpp index 8f1ff365..57ea4006 100644 --- a/datacache/mdlcache.cpp +++ b/datacache/mdlcache.cpp @@ -126,7 +126,7 @@ struct studiodata_t // array of cache handles to demand loaded virtual model data int m_nAnimBlockCount; DataCacheHandle_t *m_pAnimBlock; - unsigned long *m_iFakeAnimBlockStall; + unsigned int *m_iFakeAnimBlockStall; // vertex data is usually compressed to save memory (model decal code only needs some data) DataCacheHandle_t m_VertexCache; @@ -235,11 +235,11 @@ struct AsyncInfo_t int iAnimBlock; }; -const int NO_ASYNC = CUtlLinkedList< AsyncInfo_t >::InvalidIndex(); +const intp NO_ASYNC = CUtlFixedLinkedList< AsyncInfo_t >::InvalidIndex(); //------------------------------------- -CUtlMap g_AsyncInfoMap( DefLessFunc( int ) ); +CUtlMap g_AsyncInfoMap( DefLessFunc( int ) ); CThreadFastMutex g_AsyncInfoMapMutex; inline int MakeAsyncInfoKey( MDLHandle_t hModel, MDLCacheDataType_t type, int iAnimBlock ) @@ -248,7 +248,7 @@ inline int MakeAsyncInfoKey( MDLHandle_t hModel, MDLCacheDataType_t type, int iA return ( ( ( (int)hModel) << 16 ) | ( (int)type << 13 ) | iAnimBlock ); } -inline int GetAsyncInfoIndex( MDLHandle_t hModel, MDLCacheDataType_t type, int iAnimBlock = 0 ) +inline intp GetAsyncInfoIndex( MDLHandle_t hModel, MDLCacheDataType_t type, int iAnimBlock = 0 ) { AUTO_LOCK( g_AsyncInfoMapMutex ); int key = MakeAsyncInfoKey( hModel, type, iAnimBlock ); @@ -260,7 +260,7 @@ inline int GetAsyncInfoIndex( MDLHandle_t hModel, MDLCacheDataType_t type, int i return g_AsyncInfoMap[i]; } -inline int SetAsyncInfoIndex( MDLHandle_t hModel, MDLCacheDataType_t type, int iAnimBlock, int index ) +inline intp SetAsyncInfoIndex( MDLHandle_t hModel, MDLCacheDataType_t type, int iAnimBlock, intp index ) { AUTO_LOCK( g_AsyncInfoMapMutex ); Assert( index == NO_ASYNC || GetAsyncInfoIndex( hModel, type, iAnimBlock ) == NO_ASYNC ); @@ -277,7 +277,7 @@ inline int SetAsyncInfoIndex( MDLHandle_t hModel, MDLCacheDataType_t type, int i return index; } -inline int SetAsyncInfoIndex( MDLHandle_t hModel, MDLCacheDataType_t type, int index ) +inline intp SetAsyncInfoIndex( MDLHandle_t hModel, MDLCacheDataType_t type, intp index ) { return SetAsyncInfoIndex( hModel, type, 0, index ); } @@ -507,7 +507,7 @@ private: bool BuildHardwareData( MDLHandle_t handle, studiodata_t *pStudioData, studiohdr_t *pStudioHdr, OptimizedModel::FileHeader_t *pVtxHdr ); void ConvertFlexData( studiohdr_t *pStudioHdr ); - int ProcessPendingAsync( int iAsync ); + int ProcessPendingAsync( intp iAsync ); void ProcessPendingAsyncs( MDLCacheDataType_t type = MDLCACHE_NONE ); bool ClearAsync( MDLHandle_t handle, MDLCacheDataType_t type, int iAnimBlock, bool bAbort = false ); @@ -523,7 +523,7 @@ private: int UpdateOrCreate( studiohdr_t *pHdr, const char *pFilename, char *pX360Filename, int maxLen, const char *pPathID, bool bForce = false ); // Attempts to read the platform native file - on 360 it can read and swap Win32 file as a fallback - bool ReadFileNative( char *pFileName, const char *pPath, CUtlBuffer &buf, int nMaxBytes = 0 ); + bool ReadFileNative( char *pFileName, const char *pPath, CUtlBuffer &buf, int nMaxBytes = 0, MDLCacheDataType_t type = MDLCACHE_NONE ); // Creates a thin cache entry (to be used for model decals) from fat vertex data vertexFileHeader_t * CreateThinVertexes( vertexFileHeader_t * originalData, const studiohdr_t * pStudioHdr, int * cacheLength ); @@ -879,7 +879,7 @@ void CMDLCache::SetCacheNotify( IMDLCacheNotify *pNotify ) //----------------------------------------------------------------------------- const char *CMDLCache::GetModelName( MDLHandle_t handle ) { - if ( handle == MDLHANDLE_INVALID ) + if ( handle == MDLHANDLE_INVALID ) return ERROR_MODEL; return m_MDLDict.GetElementName( handle ); @@ -909,7 +909,7 @@ void CMDLCache::MakeFilename( MDLHandle_t handle, const char *pszExtension, char Q_strncpy( pszFileName, GetActualModelName( handle ), nMaxLength ); Q_SetExtension( pszFileName, pszExtension, nMaxLength ); Q_FixSlashes( pszFileName ); -#ifdef _LINUX +#ifdef POSIX Q_strlower( pszFileName ); #endif } @@ -1004,7 +1004,7 @@ void CMDLCache::UnserializeVCollide( MDLHandle_t handle, bool synchronousLoad ) // FIXME: Should the vcollde be played into cacheable memory? studiodata_t *pStudioData = m_MDLDict[handle]; - int iAsync = GetAsyncInfoIndex( handle, MDLCACHE_VCOLLIDE ); + intp iAsync = GetAsyncInfoIndex( handle, MDLCACHE_VCOLLIDE ); if ( iAsync == NO_ASYNC ) { @@ -1025,7 +1025,7 @@ void CMDLCache::UnserializeVCollide( MDLHandle_t handle, bool synchronousLoad ) { for ( int i = 1; i < pVirtualModel->m_group.Count(); i++ ) { - MDLHandle_t sharedHandle = (MDLHandle_t) (int)pVirtualModel->m_group[i].cache & 0xffff; + MDLHandle_t sharedHandle = VoidPtrToMDLHandle(pVirtualModel->m_group[i].cache); studiodata_t *pData = m_MDLDict[sharedHandle]; if ( !(pData->m_nFlags & STUDIODATA_FLAGS_VCOLLISION_LOADED) ) { @@ -1169,8 +1169,8 @@ void CMDLCache::AllocateAnimBlocks( studiodata_t *pStudioData, int nCount ) memset( pStudioData->m_pAnimBlock, 0, sizeof(DataCacheHandle_t) * pStudioData->m_nAnimBlockCount ); - pStudioData->m_iFakeAnimBlockStall = new unsigned long [pStudioData->m_nAnimBlockCount]; - memset( pStudioData->m_iFakeAnimBlockStall, 0, sizeof( unsigned long ) * pStudioData->m_nAnimBlockCount ); + pStudioData->m_iFakeAnimBlockStall = new unsigned int [pStudioData->m_nAnimBlockCount]; + memset( pStudioData->m_iFakeAnimBlockStall, 0, sizeof( unsigned int ) * pStudioData->m_nAnimBlockCount ); } void CMDLCache::FreeAnimBlocks( MDLHandle_t handle ) @@ -1219,7 +1219,7 @@ unsigned char *CMDLCache::UnserializeAnimBlock( MDLHandle_t handle, int nBlock ) studiodata_t *pStudioData = m_MDLDict[handle]; - int iAsync = GetAsyncInfoIndex( handle, MDLCACHE_ANIMBLOCK, nBlock ); + intp iAsync = GetAsyncInfoIndex( handle, MDLCACHE_ANIMBLOCK, nBlock ); if ( iAsync == NO_ASYNC ) { @@ -1238,7 +1238,7 @@ unsigned char *CMDLCache::UnserializeAnimBlock( MDLHandle_t handle, int nBlock ) char pFileName[MAX_PATH]; Q_strncpy( pFileName, pModelName, sizeof(pFileName) ); Q_FixSlashes( pFileName ); -#ifdef _LINUX +#ifdef POSIX Q_strlower( pFileName ); #endif if ( IsX360() ) @@ -1398,12 +1398,12 @@ void CMDLCache::FreeVirtualModel( MDLHandle_t handle ) if ( pStudioData && pStudioData->m_pVirtualModel ) { int nGroupCount = pStudioData->m_pVirtualModel->m_group.Count(); - Assert( (nGroupCount >= 1) && pStudioData->m_pVirtualModel->m_group[0].cache == (void*)(uintp)handle ); + Assert( (nGroupCount >= 1) && pStudioData->m_pVirtualModel->m_group[0].cache == MDLHandleToVirtual(handle) ); // NOTE: Start at *1* here because the 0th element contains a reference to *this* handle for ( int i = 1; i < nGroupCount; ++i ) { - MDLHandle_t h = (MDLHandle_t)(int)pStudioData->m_pVirtualModel->m_group[i].cache&0xffff; + MDLHandle_t h = VoidPtrToMDLHandle( pStudioData->m_pVirtualModel->m_group[i].cache ); FreeVirtualModel( h ); Release( h ); } @@ -1453,7 +1453,7 @@ virtualmodel_t *CMDLCache::GetVirtualModelFast( const studiohdr_t *pStudioHdr, M // Group has to be zero to ensure refcounting is correct int nGroup = pStudioData->m_pVirtualModel->m_group.AddToTail( ); Assert( nGroup == 0 ); - pStudioData->m_pVirtualModel->m_group[nGroup].cache = (void *)(uintp)handle; + pStudioData->m_pVirtualModel->m_group[nGroup].cache = MDLHandleToVirtual(handle); // Add all dependent data pStudioData->m_pVirtualModel->AppendModels( 0, pStudioHdr ); @@ -1550,7 +1550,7 @@ bool CMDLCache::LoadHardwareData( MDLHandle_t handle ) return false; } - int iAsync = GetAsyncInfoIndex( handle, MDLCACHE_STUDIOHWDATA ); + intp iAsync = GetAsyncInfoIndex( handle, MDLCACHE_STUDIOHWDATA ); if ( iAsync == NO_ASYNC ) { @@ -1910,7 +1910,7 @@ int CMDLCache::UpdateOrCreate( studiohdr_t *pHdr, const char *pSourceName, char //----------------------------------------------------------------------------- // Purpose: Attempts to read a file native to the current platform //----------------------------------------------------------------------------- -bool CMDLCache::ReadFileNative( char *pFileName, const char *pPath, CUtlBuffer &buf, int nMaxBytes ) +bool CMDLCache::ReadFileNative( char *pFileName, const char *pPath, CUtlBuffer &buf, int nMaxBytes, MDLCacheDataType_t type ) { bool bOk = false; @@ -1925,6 +1925,32 @@ bool CMDLCache::ReadFileNative( char *pFileName, const char *pPath, CUtlBuffer & { // Read the PC version bOk = g_pFullFileSystem->ReadFile( pFileName, pPath, buf, nMaxBytes ); + + if( bOk && type == MDLCACHE_STUDIOHDR ) + { + studiohdr_t* pStudioHdr = ( studiohdr_t* ) buf.PeekGet(); + + if ( pStudioHdr->studiohdr2index == 0 ) + { + // We always need this now, so make room for it in the buffer now. + int bufferContentsEnd = buf.TellMaxPut(); + int maskBits = VALIGNOF( studiohdr2_t ) - 1; + int offsetStudiohdr2 = ( bufferContentsEnd + maskBits ) & ~maskBits; + int sizeIncrease = ( offsetStudiohdr2 - bufferContentsEnd ) + sizeof( studiohdr2_t ); + buf.SeekPut( CUtlBuffer::SEEK_CURRENT, sizeIncrease ); + + // Re-get the pointer after resizing, because it has probably moved. + pStudioHdr = ( studiohdr_t* ) buf.Base(); + studiohdr2_t* pStudioHdr2 = ( studiohdr2_t* ) ( ( byte * ) pStudioHdr + offsetStudiohdr2 ); + memset( pStudioHdr2, 0, sizeof( studiohdr2_t ) ); + pStudioHdr2->flMaxEyeDeflection = 0.866f; // Matches studio.h. + + pStudioHdr->studiohdr2index = offsetStudiohdr2; + // Also make sure the structure knows about the extra bytes + // we've added so they get copied around. + pStudioHdr->length += sizeIncrease; + } + } } return bOk; @@ -1970,7 +1996,7 @@ studiohdr_t *CMDLCache::UnserializeMDL( MDLHandle_t handle, void *pData, int nDa // critical! store a back link to our data // this is fetched when re-establishing dependent cached data (vtx/vvd) - pStudioHdrIn->virtualModel = (void *)(uintp)handle; + pStudioHdrIn->SetVirtualModel( MDLHandleToVirtual( handle ) ); MdlCacheMsg( "MDLCache: Alloc studiohdr %s\n", GetModelName( handle ) ); @@ -2022,7 +2048,7 @@ bool CMDLCache::ReadMDLFile( MDLHandle_t handle, const char *pMDLFileName, CUtlB char pFileName[ MAX_PATH ]; Q_strncpy( pFileName, pMDLFileName, sizeof( pFileName ) ); Q_FixSlashes( pFileName ); -#ifdef _LINUX +#ifdef POSIX Q_strlower( pFileName ); #endif @@ -2030,7 +2056,7 @@ bool CMDLCache::ReadMDLFile( MDLHandle_t handle, const char *pMDLFileName, CUtlB MEM_ALLOC_CREDIT(); - bool bOk = ReadFileNative( pFileName, "GAME", buf ); + bool bOk = ReadFileNative( pFileName, "GAME", buf, 0, MDLCACHE_STUDIOHDR ); if ( !bOk ) { DevWarning( "Failed to load %s!\n", pMDLFileName ); @@ -2059,6 +2085,12 @@ bool CMDLCache::ReadMDLFile( MDLHandle_t handle, const char *pMDLFileName, CUtlB } } + if ( buf.Size() < sizeof(studiohdr_t) ) + { + DevWarning( "Empty model %s\n", pMDLFileName ); + return false; + } + studiohdr_t *pStudioHdr = (studiohdr_t*)buf.PeekGet(); if ( !pStudioHdr ) { @@ -2073,7 +2105,7 @@ bool CMDLCache::ReadMDLFile( MDLHandle_t handle, const char *pMDLFileName, CUtlB // critical! store a back link to our data // this is fetched when re-establishing dependent cached data (vtx/vvd) - pStudioHdr->virtualModel = (void*)(uintp)handle; + pStudioHdr->SetVirtualModel( MDLHandleToVirtual( handle ) ); // Make sure all dependent files are valid if ( !VerifyHeaders( pStudioHdr ) ) @@ -2138,6 +2170,11 @@ studiohdr_t *CMDLCache::GetStudioHdr( MDLHandle_t handle ) // Assert( m_pModelCacheSection->IsFrameLocking() ); // Assert( m_pMeshCacheSection->IsFrameLocking() ); + studiodata_t *pStudioData = m_MDLDict[handle]; + + if( !pStudioData ) + return NULL; + #if _DEBUG VPROF_INCREMENT_COUNTER( "GetStudioHdr", 1 ); #endif @@ -2236,7 +2273,7 @@ void CMDLCache::TouchAllData( MDLHandle_t handle ) // ensure all sub models are cached for ( int i=1; im_group.Count(); ++i ) { - MDLHandle_t childHandle = (MDLHandle_t)(int)pVModel->m_group[i].cache&0xffff; + MDLHandle_t childHandle = VoidPtrToMDLHandle( pVModel->m_group[i].cache ); if ( childHandle != MDLHANDLE_INVALID ) { // FIXME: Should this be calling TouchAllData on the child? @@ -2301,7 +2338,7 @@ bool CMDLCache::HandleCacheNotification( const DataCacheNotification_t ¬ifica { MdlCacheMsg( "MDLCache: Data cache discard %s %s\n", g_ppszTypes[TypeFromCacheID( notification.clientId )], GetModelName( HandleFromCacheID( notification.clientId ) ) ); - if ( (DataCacheClientID_t)notification.pItemData == notification.clientId || + if ( (DataCacheClientID_t)(intp)notification.pItemData == notification.clientId || TypeFromCacheID(notification.clientId) != MDLCACHE_STUDIOHWDATA ) { Assert( notification.pItemData ); @@ -2320,7 +2357,7 @@ bool CMDLCache::HandleCacheNotification( const DataCacheNotification_t ¬ifica bool CMDLCache::GetItemName( DataCacheClientID_t clientId, const void *pItem, char *pDest, unsigned nMaxLen ) { - if ( (DataCacheClientID_t)pItem == clientId ) + if ( (DataCacheClientID_t)(uintp)pItem == clientId ) { return false; } @@ -2426,7 +2463,7 @@ void CMDLCache::FinishPendingLoads() AUTO_LOCK( m_AsyncMutex ); // finish just our known jobs - int iAsync = m_PendingAsyncs.Head(); + intp iAsync = m_PendingAsyncs.Head(); while ( iAsync != m_PendingAsyncs.InvalidIndex() ) { AsyncInfo_t &info = m_PendingAsyncs[iAsync]; @@ -2581,7 +2618,7 @@ bool CMDLCache::VerifyHeaders( studiohdr_t *pStudioHdr ) } char pFileName[ MAX_PATH ]; - MDLHandle_t handle = (MDLHandle_t)(int)pStudioHdr->virtualModel&0xffff; + MDLHandle_t handle = VoidPtrToMDLHandle( pStudioHdr->VirtualModel() ); MakeFilename( handle, ".vvd", pFileName, sizeof(pFileName) ); @@ -2642,7 +2679,7 @@ vertexFileHeader_t *CMDLCache::CacheVertexData( studiohdr_t *pStudioHdr ) Assert( pStudioHdr ); - handle = (MDLHandle_t)(int)pStudioHdr->virtualModel&0xffff; + handle = VoidPtrToMDLHandle( pStudioHdr->VirtualModel() ); Assert( handle != MDLHANDLE_INVALID ); pVvdHdr = (vertexFileHeader_t *)CheckData( m_MDLDict[handle]->m_VertexCache, MDLCACHE_VERTEXES ); @@ -3037,7 +3074,7 @@ bool CMDLCache::ProcessDataIntoCache( MDLHandle_t handle, MDLCacheDataType_t typ // =0: pending // >0: completed //----------------------------------------------------------------------------- -int CMDLCache::ProcessPendingAsync( int iAsync ) +int CMDLCache::ProcessPendingAsync( intp iAsync ) { if ( !ThreadInMainThread() ) { @@ -3122,10 +3159,10 @@ void CMDLCache::ProcessPendingAsyncs( MDLCacheDataType_t type ) // things -- the LRU is in correct order, and it catches precached items lurking // in the async queue that have only been requested once (thus aren't being cached // and might lurk forever, e.g., wood gibs in the citadel) - int current = m_PendingAsyncs.Head(); + intp current = m_PendingAsyncs.Head(); while ( current != m_PendingAsyncs.InvalidIndex() ) { - int next = m_PendingAsyncs.Next( current ); + intp next = m_PendingAsyncs.Next( current ); if ( type == MDLCACHE_NONE || m_PendingAsyncs[current].type == type ) { @@ -3148,7 +3185,7 @@ void CMDLCache::ProcessPendingAsyncs( MDLCacheDataType_t type ) //----------------------------------------------------------------------------- bool CMDLCache::ClearAsync( MDLHandle_t handle, MDLCacheDataType_t type, int iAnimBlock, bool bAbort ) { - int iAsyncInfo = GetAsyncInfoIndex( handle, type, iAnimBlock ); + intp iAsyncInfo = GetAsyncInfoIndex( handle, type, iAnimBlock ); if ( iAsyncInfo != NO_ASYNC ) { AsyncInfo_t *pInfo; @@ -3242,7 +3279,7 @@ bool CMDLCache::SetAsyncLoad( MDLCacheDataType_t type, bool bAsync ) //----------------------------------------------------------------------------- vertexFileHeader_t *CMDLCache::BuildAndCacheVertexData( studiohdr_t *pStudioHdr, vertexFileHeader_t *pRawVvdHdr ) { - MDLHandle_t handle = (MDLHandle_t)(int)pStudioHdr->virtualModel&0xffff; + MDLHandle_t handle = VoidPtrToMDLHandle( pStudioHdr->VirtualModel() ); vertexFileHeader_t *pVvdHdr; MdlCacheMsg( "MDLCache: Load VVD for %s\n", pStudioHdr->pszName() ); @@ -3330,7 +3367,7 @@ vertexFileHeader_t *CMDLCache::LoadVertexData( studiohdr_t *pStudioHdr ) MDLHandle_t handle; Assert( pStudioHdr ); - handle = (MDLHandle_t)(int)pStudioHdr->virtualModel&0xffff; + handle = VoidPtrToMDLHandle( pStudioHdr->VirtualModel() ); Assert( !m_MDLDict[handle]->m_VertexCache ); studiodata_t *pStudioData = m_MDLDict[handle]; @@ -3340,7 +3377,7 @@ vertexFileHeader_t *CMDLCache::LoadVertexData( studiohdr_t *pStudioHdr ) return NULL; } - int iAsync = GetAsyncInfoIndex( handle, MDLCACHE_VERTEXES ); + intp iAsync = GetAsyncInfoIndex( handle, MDLCACHE_VERTEXES ); if ( iAsync == NO_ASYNC ) { @@ -3420,7 +3457,7 @@ void CMDLCache::CacheData( DataCacheHandle_t *c, void *pData, int size, const ch } if ( id == (DataCacheClientID_t)-1 ) - id = (DataCacheClientID_t)pData; + id = (DataCacheClientID_t)(intp)pData; GetCacheSection( type )->Add(id, pData, size, c ); } @@ -3584,7 +3621,7 @@ void CMDLCache::QueuedLoaderCallback_MDL( void *pContext, void *pContext2, const // journal each incoming buffer ModelParts_t *pModelParts = (ModelParts_t *)pContext; - ModelParts_t::BufferType_t bufferType = static_cast< ModelParts_t::BufferType_t >((int)pContext2); + ModelParts_t::BufferType_t bufferType = static_cast< ModelParts_t::BufferType_t >((intp)pContext2); pModelParts->Buffers[bufferType].SetExternalBuffer( (void *)pData, nSize, nSize, CUtlBuffer::READ_ONLY ); pModelParts->nLoadedParts += (1 << bufferType); @@ -3895,7 +3932,7 @@ void CMDLCache::MarkFrame() const studiohdr_t *studiohdr_t::FindModel( void **cache, char const *pModelName ) const { MDLHandle_t handle = g_MDLCache.FindMDL( pModelName ); - *cache = (void*)(uintp)handle; + *cache = MDLHandleToVirtual(handle); return g_MDLCache.GetStudioHdr( handle ); } @@ -3904,21 +3941,21 @@ virtualmodel_t *studiohdr_t::GetVirtualModel( void ) const if (numincludemodels == 0) return NULL; - return g_MDLCache.GetVirtualModelFast( this, (MDLHandle_t)(int)virtualModel&0xffff ); + return g_MDLCache.GetVirtualModelFast( this, VoidPtrToMDLHandle( VirtualModel() ) ); } byte *studiohdr_t::GetAnimBlock( int i ) const { - return g_MDLCache.GetAnimBlock( (MDLHandle_t)(int)virtualModel&0xffff, i ); + return g_MDLCache.GetAnimBlock( VoidPtrToMDLHandle( VirtualModel() ), i ); } int studiohdr_t::GetAutoplayList( unsigned short **pOut ) const { - return g_MDLCache.GetAutoplayList( (MDLHandle_t)(int)virtualModel&0xffff, pOut ); + return g_MDLCache.GetAutoplayList( VoidPtrToMDLHandle( VirtualModel() ), pOut ); } const studiohdr_t *virtualgroup_t::GetStudioHdr( void ) const { - return g_MDLCache.GetStudioHdr( (MDLHandle_t)(int)cache&0xffff ); + return g_MDLCache.GetStudioHdr( VoidPtrToMDLHandle( cache ) ); } diff --git a/datamodel/clipboardmanager.cpp b/datamodel/clipboardmanager.cpp index 5ffa5335..cb2d5a9d 100644 --- a/datamodel/clipboardmanager.cpp +++ b/datamodel/clipboardmanager.cpp @@ -8,7 +8,7 @@ #include "datamodel.h" #include "tier1/KeyValues.h" -#ifndef _LINUX +#ifdef _WIN32 #define USE_WINDOWS_CLIPBOARD #endif diff --git a/datamodel/datamodel.cpp b/datamodel/datamodel.cpp index a569e65c..7e7589dc 100644 --- a/datamodel/datamodel.cpp +++ b/datamodel/datamodel.cpp @@ -901,7 +901,9 @@ bool CDataModel::Unserialize( CUtlBuffer &inBuf, const char *pEncodingName, cons return false; } +#if !defined(NO_MALLOC_OVERRIDE) g_pMemAlloc->heapchk(); +#endif DmxHeader_t header; bool bStoresVersionInFile = pSerializer->StoresVersionInFile(); @@ -1656,7 +1658,7 @@ DmAttributeReferenceIterator_t CDataModel::FirstAttributeReferencingElement( DmE if ( !pRef || pRef->m_attributes.m_hAttribute == DMATTRIBUTE_HANDLE_INVALID ) return DMATTRIBUTE_REFERENCE_ITERATOR_INVALID; - return ( DmAttributeReferenceIterator_t )( int )&pRef->m_attributes; + return ( DmAttributeReferenceIterator_t )( intp )&pRef->m_attributes; } DmAttributeReferenceIterator_t CDataModel::NextAttributeReferencingElement( DmAttributeReferenceIterator_t hAttrIter ) @@ -1665,7 +1667,7 @@ DmAttributeReferenceIterator_t CDataModel::NextAttributeReferencingElement( DmAt if ( !pList ) return DMATTRIBUTE_REFERENCE_ITERATOR_INVALID; - return ( DmAttributeReferenceIterator_t )( int )pList->m_pNext; + return ( DmAttributeReferenceIterator_t )( intp )pList->m_pNext; } CDmAttribute *CDataModel::GetAttribute( DmAttributeReferenceIterator_t hAttrIter ) diff --git a/datamodel/dependencygraph.cpp b/datamodel/dependencygraph.cpp index 2040b34d..527a38a4 100644 --- a/datamodel/dependencygraph.cpp +++ b/datamodel/dependencygraph.cpp @@ -67,7 +67,7 @@ bool HashEntryCompareFunc( CAttributeNode *const& lhs, CAttributeNode *const& rh uint HashEntryKeyFunc( CAttributeNode *const& keyinfo ) { - uint i = (uint)keyinfo->m_attribute; + uintp i = (uintp)keyinfo->m_attribute; return i >> 2; // since memory is allocated on a 4-byte (at least!) boundary } diff --git a/datamodel/dmattribute.cpp b/datamodel/dmattribute.cpp index 3569b4dc..71a0d52b 100644 --- a/datamodel/dmattribute.cpp +++ b/datamodel/dmattribute.cpp @@ -721,7 +721,7 @@ public: virtual void Undo() { - CDmrArray array( GetAttribute() ); + CDmrArray array( this->GetAttribute() ); if ( array.IsValid() ) { array.Set( m_nSlot, m_OldValue ); @@ -730,7 +730,7 @@ public: virtual void Redo() { - CDmrArray array( GetAttribute() ); + CDmrArray array( this->GetAttribute() ); if ( array.IsValid() ) { array.Set( m_nSlot, m_Value ); @@ -789,7 +789,7 @@ public: virtual void Undo() { - CDmrArray array( GetAttribute() ); + CDmrArray array( this->GetAttribute() ); if ( array.IsValid() ) { for ( int i = 0; i < m_nCount; ++i ) @@ -801,7 +801,7 @@ public: virtual void Redo() { - CDmrArray array( GetAttribute() ); + CDmrArray array( this->GetAttribute() ); if ( array.IsValid() ) { for ( int i = 0; i < m_nCount; ++i ) @@ -838,7 +838,7 @@ public: virtual void Undo() { - CDmrArray array( GetAttribute() ); + CDmrArray array( this->GetAttribute() ); if ( array.IsValid() ) { array.RemoveMultiple( m_nIndex, m_nCount ); @@ -847,7 +847,7 @@ public: virtual void Redo() { - CDmrArray array( GetAttribute() ); + CDmrArray array( this->GetAttribute() ); if ( array.IsValid() ) { T defaultVal; @@ -888,7 +888,7 @@ public: virtual void Undo() { - CDmrArray array( GetAttribute() ); + CDmrArray array( this->GetAttribute() ); if ( array.IsValid() ) { array.Remove( m_nIndex ); @@ -897,7 +897,7 @@ public: virtual void Redo() { - CDmrArray array( GetAttribute() ); + CDmrArray array( this->GetAttribute() ); if ( array.IsValid() ) { array.InsertBefore( m_nIndex, m_newValue ); @@ -955,7 +955,7 @@ public: virtual void Undo() { - CDmrArray array( GetAttribute() ); + CDmrArray array( this->GetAttribute() ); if ( array.IsValid() ) { if ( m_bFastRemove ) @@ -993,7 +993,7 @@ public: virtual void Redo() { - CDmrArray array( GetAttribute() ); + CDmrArray array( this->GetAttribute() ); if ( array.IsValid() ) { if ( m_bFastRemove ) @@ -1015,7 +1015,7 @@ public: static char buf[ 128 ]; const char *base = BaseClass::GetDesc(); - Q_snprintf( buf, sizeof( buf ), "%s (%s) = remove( pos %i, count %i )", base, GetAttributeName(), m_nIndex, m_nCount ); + Q_snprintf( buf, sizeof( buf ), "%s (%s) = remove( pos %i, count %i )", base, this->GetAttributeName(), m_nIndex, m_nCount ); return buf; } @@ -1097,7 +1097,7 @@ public: virtual void Undo() { - CDmrArray array( GetAttribute() ); + CDmrArray array( this->GetAttribute() ); if ( array.IsValid() ) { array.RemoveAll(); @@ -1110,7 +1110,7 @@ public: virtual void Redo() { - CDmrArray array( GetAttribute() ); + CDmrArray array( this->GetAttribute() ); if ( array.IsValid() ) { array.RemoveAll(); @@ -2734,7 +2734,7 @@ CDmaArrayConstBase::CDmaArrayConstBase( ) template< class T, class B > int CDmaArrayConstBase::Find( const T &value ) const { - return Value().Find( value ); + return this->Value().Find( value ); } @@ -2747,7 +2747,7 @@ int CDmaArrayBase::AddToTail() T defaultVal; CDmAttributeInfo::SetDefaultValue( defaultVal ); CDmArrayAttributeOp accessor( this->m_pAttribute ); - return accessor.InsertBefore( Value().Count(), defaultVal ); + return accessor.InsertBefore( this->Value().Count(), defaultVal ); } template< class T, class B > @@ -2763,7 +2763,7 @@ template< class T, class B > int CDmaArrayBase::AddToTail( const T& src ) { CDmArrayAttributeOp accessor( this->m_pAttribute ); - return accessor.InsertBefore( Value().Count(), src ); + return accessor.InsertBefore( this->Value().Count(), src ); } template< class T, class B > @@ -2777,7 +2777,7 @@ template< class T, class B > int CDmaArrayBase::AddMultipleToTail( int num ) { CDmArrayAttributeOp accessor( this->m_pAttribute ); - return accessor.InsertMultipleBefore( Value().Count(), num ); + return accessor.InsertMultipleBefore( this->Value().Count(), num ); } template< class T, class B > @@ -2790,7 +2790,7 @@ int CDmaArrayBase::InsertMultipleBefore( int elem, int num ) template< class T, class B > void CDmaArrayBase::EnsureCount( int num ) { - int nCurrentCount = Value().Count(); + int nCurrentCount = this->Value().Count(); if ( nCurrentCount < num ) { AddMultipleToTail( num - nCurrentCount ); @@ -2879,7 +2879,7 @@ void CDmaArrayBase::RemoveMultiple( int elem, int num ) template< class T, class B > void CDmaArrayBase::EnsureCapacity( int num ) { - Value().EnsureCapacity( num ); + this->Value().EnsureCapacity( num ); } template< class T, class B > @@ -2894,10 +2894,10 @@ void CDmaArrayBase::Purge() // Attribute initialization //----------------------------------------------------------------------------- template< class T, class B > -void CDmaDecorator::Init( CDmElement *pOwner, const char *pAttributeName, int nFlags = 0 ) +void CDmaDecorator::Init( CDmElement *pOwner, const char *pAttributeName, int nFlags ) { Assert( pOwner ); - this->m_pAttribute = pOwner->AddExternalAttribute( pAttributeName, CDmAttributeInfo >::AttributeType(), &Value() ); + this->m_pAttribute = pOwner->AddExternalAttribute( pAttributeName, CDmAttributeInfo >::AttributeType(), &(this->Value()) ); Assert( this->m_pAttribute ); if ( nFlags ) { @@ -2915,12 +2915,12 @@ void CDmrDecoratorConst::Init( const CDmAttribute* pAttribute ) if ( pAttribute && pAttribute->GetType() == CDmAttributeInfo< CUtlVector< T > >::AttributeType() ) { this->m_pAttribute = const_cast( pAttribute ); - Attach( this->m_pAttribute->GetAttributeData() ); + this->Attach( this->m_pAttribute->GetAttributeData() ); } else { this->m_pAttribute = NULL; - Attach( NULL ); + this->Attach( NULL ); } } @@ -2948,12 +2948,12 @@ void CDmrDecorator::Init( CDmAttribute* pAttribute ) if ( pAttribute && pAttribute->GetType() == CDmAttributeInfo< CUtlVector< T > >::AttributeType() ) { this->m_pAttribute = pAttribute; - Attach( this->m_pAttribute->GetAttributeData() ); + this->Attach( this->m_pAttribute->GetAttributeData() ); } else { this->m_pAttribute = NULL; - Attach( NULL ); + this->Attach( NULL ); } } diff --git a/datamodel/dmserializerkeyvalues.cpp b/datamodel/dmserializerkeyvalues.cpp index 24a45de0..f446e7ab 100644 --- a/datamodel/dmserializerkeyvalues.cpp +++ b/datamodel/dmserializerkeyvalues.cpp @@ -264,7 +264,7 @@ DmAttributeType_t CDmSerializerKeyValues::DetermineAttributeType( KeyValues *pKe if ( sscanf( pKeyValues->GetString(), "%f %f", &f1, &f2 ) == 2 ) return AT_VECTOR2; - int i = pKeyValues->GetInt( NULL, INT_MAX ); + int i = pKeyValues->GetInt( nullptr, INT_MAX ); if ( ( sscanf( pKeyValues->GetString(), "%d", &i ) == 1 ) && ( !strchr( pKeyValues->GetString(), '.' ) ) ) return AT_INT; diff --git a/dedicated/wscript b/dedicated/wscript index adb01eb8..5fed8f10 100755 --- a/dedicated/wscript +++ b/dedicated/wscript @@ -13,7 +13,7 @@ def options(opt): def configure(conf): conf.define('LAUNCHERONLY',1) -# conf.define('SUPPORT_PACKED_STORE',1) + conf.define('SUPPORT_PACKED_STORE',1) conf.define('DEDICATED',1) def build(bld): @@ -56,7 +56,7 @@ def build(bld): defines = [] - libs = ['tier0','tier1','tier2','tier3','vstdlib','steam_api','vpklib','appframework','mathlib', 'EDIT'] + libs = ['tier0','vpklib','tier1','tier2','tier3','vstdlib','steam_api','appframework','mathlib', 'EDIT'] install_path = bld.env.LIBDIR diff --git a/dmxloader/dmxattribute.cpp b/dmxloader/dmxattribute.cpp index aea474c7..293cce8b 100644 --- a/dmxloader/dmxattribute.cpp +++ b/dmxloader/dmxattribute.cpp @@ -73,8 +73,10 @@ struct CSizeTest COMPILE_TIME_ASSERT( sizeof( QAngle ) == 12 ); COMPILE_TIME_ASSERT( sizeof( Quaternion ) == 16 ); COMPILE_TIME_ASSERT( sizeof( VMatrix ) == 64 ); +#if !defined( PLATFORM_64BITS ) COMPILE_TIME_ASSERT( sizeof( CUtlString ) == 4 ); COMPILE_TIME_ASSERT( sizeof( CUtlBinaryBlock ) == 16 ); +#endif COMPILE_TIME_ASSERT( sizeof( DmObjectId_t ) == 16 ); }; }; diff --git a/engine/LoadScreenUpdate.cpp b/engine/LoadScreenUpdate.cpp index 6bfcd1b7..2ea25063 100644 --- a/engine/LoadScreenUpdate.cpp +++ b/engine/LoadScreenUpdate.cpp @@ -53,8 +53,8 @@ public: DELEGATE_TO_OBJECT_0( int, heapchk, m_pMemAlloc ); DELEGATE_TO_OBJECT_0( bool, IsDebugHeap, m_pMemAlloc ); DELEGATE_TO_OBJECT_2V( GetActualDbgInfo, const char *&, int &, m_pMemAlloc ); - DELEGATE_TO_OBJECT_5V( RegisterAllocation, const char *, int, int, int, unsigned, m_pMemAlloc ); - DELEGATE_TO_OBJECT_5V( RegisterDeallocation, const char *, int, int, int, unsigned, m_pMemAlloc ); + DELEGATE_TO_OBJECT_5V( RegisterAllocation, const char *, int, size_t, size_t, unsigned, m_pMemAlloc ); + DELEGATE_TO_OBJECT_5V( RegisterDeallocation, const char *, int, size_t, size_t, unsigned, m_pMemAlloc ); DELEGATE_TO_OBJECT_0( int, GetVersion, m_pMemAlloc ); DELEGATE_TO_OBJECT_0V( CompactHeap, m_pMemAlloc ); DELEGATE_TO_OBJECT_1( MemAllocFailHandler_t, SetAllocFailHandler, MemAllocFailHandler_t, m_pMemAlloc ); diff --git a/engine/ModelInfo.cpp b/engine/ModelInfo.cpp index d5d1f371..b72a0bc5 100644 --- a/engine/ModelInfo.cpp +++ b/engine/ModelInfo.cpp @@ -208,8 +208,8 @@ protected: public: struct ModelFileHandleHash { - uint operator()( model_t *p ) const { return Mix32HashFunctor()( (uint32)( p->fnHandle ) ); } - uint operator()( FileNameHandle_t fn ) const { return Mix32HashFunctor()( (uint32) fn ); } + uint operator()( model_t *p ) const { return PointerHashFunctor()( p->fnHandle ); } + uint operator()( FileNameHandle_t fn ) const { return PointerHashFunctor()( fn ); } }; struct ModelFileHandleEq { @@ -532,7 +532,7 @@ const studiohdr_t *CModelInfo::FindModel( const studiohdr_t *pStudioHdr, void ** //----------------------------------------------------------------------------- const studiohdr_t *CModelInfo::FindModel( void *cache ) const { - return g_pMDLCache->GetStudioHdr( (MDLHandle_t)(int)cache&0xffff ); + return g_pMDLCache->GetStudioHdr( VoidPtrToMDLHandle( cache ) ); } @@ -541,7 +541,7 @@ const studiohdr_t *CModelInfo::FindModel( void *cache ) const //----------------------------------------------------------------------------- virtualmodel_t *CModelInfo::GetVirtualModel( const studiohdr_t *pStudioHdr ) const { - MDLHandle_t handle = (MDLHandle_t)(int)pStudioHdr->virtualModel&0xffff; + MDLHandle_t handle = VoidPtrToMDLHandle( pStudioHdr->VirtualModel() ); return g_pMDLCache->GetVirtualModelFast( pStudioHdr, handle ); } @@ -550,13 +550,13 @@ virtualmodel_t *CModelInfo::GetVirtualModel( const studiohdr_t *pStudioHdr ) con //----------------------------------------------------------------------------- byte *CModelInfo::GetAnimBlock( const studiohdr_t *pStudioHdr, int nBlock ) const { - MDLHandle_t handle = (MDLHandle_t)(int)pStudioHdr->virtualModel&0xffff; + MDLHandle_t handle = VoidPtrToMDLHandle( pStudioHdr->VirtualModel() ); return g_pMDLCache->GetAnimBlock( handle, nBlock ); } int CModelInfo::GetAutoplayList( const studiohdr_t *pStudioHdr, unsigned short **pAutoplayList ) const { - MDLHandle_t handle = (MDLHandle_t)(int)pStudioHdr->virtualModel&0xffff; + MDLHandle_t handle = VoidPtrToMDLHandle( pStudioHdr->VirtualModel() ); return g_pMDLCache->GetAutoplayList( handle, pAutoplayList ); } @@ -576,22 +576,22 @@ virtualmodel_t *studiohdr_t::GetVirtualModel( void ) const { if ( numincludemodels == 0 ) return NULL; - return g_pMDLCache->GetVirtualModelFast( this, (MDLHandle_t)(int)virtualModel&0xffff ); + return g_pMDLCache->GetVirtualModelFast( this, VoidPtrToMDLHandle( VirtualModel() ) ); } byte *studiohdr_t::GetAnimBlock( int i ) const { - return g_pMDLCache->GetAnimBlock( (MDLHandle_t)(int)virtualModel&0xffff, i ); + return g_pMDLCache->GetAnimBlock( VoidPtrToMDLHandle( VirtualModel() ), i ); } int studiohdr_t::GetAutoplayList( unsigned short **pOut ) const { - return g_pMDLCache->GetAutoplayList( (MDLHandle_t)(int)virtualModel&0xffff, pOut ); + return g_pMDLCache->GetAutoplayList( VoidPtrToMDLHandle( VirtualModel() ), pOut ); } const studiohdr_t *virtualgroup_t::GetStudioHdr( void ) const { - return g_pMDLCache->GetStudioHdr( (MDLHandle_t)(int)cache&0xffff ); + return g_pMDLCache->GetStudioHdr( VoidPtrToMDLHandle( cache ) ); } diff --git a/engine/OcclusionSystem.cpp b/engine/OcclusionSystem.cpp index 86491631..1c3fad1c 100644 --- a/engine/OcclusionSystem.cpp +++ b/engine/OcclusionSystem.cpp @@ -1268,7 +1268,9 @@ void CEdgeList::CullSmallOccluders() // Sort the surfaces by screen area, in descending order int nSurfCount = m_Surfaces.Count(); s_pSortSurfaces = m_Surfaces.Base(); - qsort( m_SurfaceSort.Base(), nSurfCount, sizeof(int), SurfCompare ); + + if( m_SurfaceSort.Base() ) + qsort( m_SurfaceSort.Base(), nSurfCount, sizeof(int), SurfCompare ); // We're going to keep the greater of r_occludermin + All surfaces with a screen area >= r_occluderarea int nMinSurfaces = r_occludermincount.GetInt(); @@ -1282,7 +1284,7 @@ void CEdgeList::CullSmallOccluders() bool *bUseSurface = (bool*)stackalloc( nSurfCount * sizeof(bool) ); memset( bUseSurface, 0, nSurfCount * sizeof(bool) ); - + int i; for ( i = 0; i < nSurfCount; ++i ) { diff --git a/engine/audio/private/snd_mix.cpp b/engine/audio/private/snd_mix.cpp index ca44cbf6..94d9e794 100644 --- a/engine/audio/private/snd_mix.cpp +++ b/engine/audio/private/snd_mix.cpp @@ -1962,7 +1962,7 @@ public: { int m_channelNum; int m_vol; // max volume of sound. -1 means "do not cull, ever, do not even do the math" - unsigned int m_nameHash; // a unique id for a sound file + uintp m_nameHash; // a unique id for a sound file }; protected: sChannelVolData m_channelInfo[MAX_CHANNELS]; @@ -1994,7 +1994,7 @@ void CChannelCullList::Initialize( CChannelList &list ) { m_channelInfo[i].m_vol = ChannelLoudestCurVolume(ch); AssertMsg(m_channelInfo[i].m_vol >= 0, "Sound channel has a negative volume?"); - m_channelInfo[i].m_nameHash = (unsigned int) ch->sfx; + m_channelInfo[i].m_nameHash = (uintp) ch->sfx; } else { @@ -2029,7 +2029,7 @@ void CChannelCullList::Initialize( CChannelList &list ) ++j ) { // j steps through the sorted list until we find ourselves: - if (m_channelInfo[j].m_nameHash == (unsigned int)(ch->sfx)) + if (m_channelInfo[j].m_nameHash == (uintp)(ch->sfx)) { // that's another channel playing this sound but louder than me ++howManyLouder; diff --git a/engine/audio/private/snd_mp3_source.cpp b/engine/audio/private/snd_mp3_source.cpp index d4b012e4..82c9662e 100644 --- a/engine/audio/private/snd_mp3_source.cpp +++ b/engine/audio/private/snd_mp3_source.cpp @@ -93,7 +93,7 @@ CAudioSourceMP3::CAudioSourceMP3( CSfxTable *pSfx ) m_dataStart = 0; - int file = g_pSndIO->open( pSfx->GetFileName() ); + intp file = g_pSndIO->open( pSfx->GetFileName() ); if ( file != -1 ) { m_dataSize = g_pSndIO->size( file ); @@ -239,7 +239,7 @@ void CAudioSourceMP3::GetCacheData( CAudioSourceCachedInfo *info ) info->SetSampleRate( m_sampleRate ); info->SetDataStart( 0 ); - int file = g_pSndIO->open( m_pSfx->GetFileName() ); + intp file = g_pSndIO->open( m_pSfx->GetFileName() ); if ( !file ) { Warning( "Failed to find file for building soundcache [ %s ]\n", m_pSfx->GetFileName() ); diff --git a/engine/audio/private/snd_wave_source.cpp b/engine/audio/private/snd_wave_source.cpp index e51d22dc..3954dfdf 100644 --- a/engine/audio/private/snd_wave_source.cpp +++ b/engine/audio/private/snd_wave_source.cpp @@ -723,7 +723,7 @@ bool CAudioSourceWave::GetStartupData( void *dest, int destsize, int& bytesCopie // requesting precache snippet as leader for streaming startup latency if ( destsize ) { - int file = g_pSndIO->open( m_pSfx->GetFileName() ); + intp file = g_pSndIO->open( m_pSfx->GetFileName() ); if ( !file ) { return false; diff --git a/engine/audio/private/voice.cpp b/engine/audio/private/voice.cpp index ce506d1f..1948766b 100644 --- a/engine/audio/private/voice.cpp +++ b/engine/audio/private/voice.cpp @@ -37,7 +37,7 @@ void VoiceTweak_EndVoiceTweakMode(); void EngineTool_OverrideSampleRate( int& rate ); // A fallback codec that should be the most likely to work for local/offline use -#define VOICE_FALLBACK_CODEC "vaudio_celt" +#define VOICE_FALLBACK_CODEC "vaudio_opus" // Special entity index used for tweak mode. #define TWEAKMODE_ENTITYINDEX -500 @@ -197,6 +197,9 @@ extern IVoiceRecord* CreateVoiceRecord_AudioQueue(int sampleRate); extern IVoiceRecord* CreateVoiceRecord_OpenAL(int sampleRate); #endif +#ifdef USE_SDL +extern IVoiceRecord *CreateVoiceRecord_SDL(int sampleRate); +#endif static bool VoiceRecord_Start() { @@ -583,12 +586,13 @@ bool Voice_Init( const char *pCodecName, int nSampleRate ) bool bSpeex = Q_stricmp( pCodecName, "vaudio_speex" ) == 0; bool bCelt = Q_stricmp( pCodecName, "vaudio_celt" ) == 0; + bool bOpus = Q_stricmp( pCodecName, "vaudio_opus" ) == 0; bool bSteam = Q_stricmp( pCodecName, "steam" ) == 0; // Miles has not been in use for voice in a long long time. Not worth the surface to support ancient demos that may // use it (and probably do not work for other reasons) // "vaudio_miles" - if ( !( bSpeex || bCelt || bSteam ) ) + if ( !( bSpeex || bCelt || bOpus || bSteam ) ) { Msg( "Voice_Init Failed: invalid voice codec %s.\n", pCodecName ); return false; @@ -648,6 +652,8 @@ bool Voice_Init( const char *pCodecName, int nSampleRate ) } #elif defined( WIN32 ) g_pVoiceRecord = CreateVoiceRecord_DSound( Voice_SamplesPerSec() ); +#elif defined( USE_SDL ) + g_pVoiceRecord = CreateVoiceRecord_SDL( Voice_SamplesPerSec() ); #else g_pVoiceRecord = CreateVoiceRecord_OpenAL( Voice_SamplesPerSec() ); #endif @@ -671,6 +677,12 @@ bool Voice_Init( const char *pCodecName, int nSampleRate ) CreateInterfaceFn createCodecFn = NULL; g_hVoiceCodecDLL = FileSystem_LoadModule(pCodecName); + if( !g_hVoiceCodecDLL || (createCodecFn = Sys_GetFactory(g_hVoiceCodecDLL)) == NULL ) + { + g_hVoiceCodecDLL = FileSystem_LoadModule( VOICE_FALLBACK_CODEC ); + pCodecName = VOICE_FALLBACK_CODEC; + } + if ( !g_hVoiceCodecDLL || (createCodecFn = Sys_GetFactory(g_hVoiceCodecDLL)) == NULL || (g_pEncodeCodec = (IVoiceCodec*)createCodecFn(pCodecName, NULL)) == NULL || !g_pEncodeCodec->Init( quality ) ) { @@ -1075,7 +1087,7 @@ int Voice_GetCompressedData(char *pchDest, int nCount, bool bFinal) { // Check g_bVoiceRecordStopping in case g_bUsingSteamVoice changes on us // while waiting for the end of voice data. - if ( g_bUsingSteamVoice || g_bVoiceRecordStopping ) + if ( g_bUsingSteamVoice && g_bVoiceRecordStopping ) { uint32 cbCompressedWritten = 0; uint32 cbUncompressedWritten = 0; diff --git a/engine/audio/private/voice_mixer_controls_openal.cpp b/engine/audio/private/voice_mixer_controls_openal.cpp index 832815c8..6286889e 100644 --- a/engine/audio/private/voice_mixer_controls_openal.cpp +++ b/engine/audio/private/voice_mixer_controls_openal.cpp @@ -141,7 +141,7 @@ bool CMixerControls::GetValue_Float(Control iControl, float &value) case MicVolume: { OSStatus theError = noErr; - for ( int iChannel = 0; iChannel < 3; iChannel++ ) + for ( uint iChannel = 0; iChannel < 3; iChannel++ ) { // scan the channel list until you find a channel set to non-zero, then use that Float32 theVolume = 0; diff --git a/engine/audio/private/voice_record_sdl.cpp b/engine/audio/private/voice_record_sdl.cpp new file mode 100644 index 00000000..142a8f49 --- /dev/null +++ b/engine/audio/private/voice_record_sdl.cpp @@ -0,0 +1,257 @@ +//========= Copyright 1996-2009, Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +// This module implements the voice record and compression functions + +//#include "audio_pch.h" +//#include "voice.h" +#include "tier0/platform.h" +#include "ivoicerecord.h" +#include "tier0/dbg.h" +#include "tier0/threadtools.h" + +#include +#include + +#define RECORDING_BUFFER_SECONDS 3 +#define SAMPLE_COUNT 2048 + +// ------------------------------------------------------------------------------ +// VoiceRecord_SDL +// ------------------------------------------------------------------------------ + +struct AudioBuf +{ + int Read(char *out, int len) + { + int nAvalible = (size + (writePtr - readPtr)) % size; + + if( nAvalible == 0 ) + return 0; + + if( len > nAvalible ) len = nAvalible; + + int diff = (data + size) - readPtr; + + + if( len > diff ) + { + memcpy(out, readPtr, diff ); + memcpy(out+diff, data, len-diff ); + } else memcpy(out, readPtr, len); + + readPtr += len; + + if( readPtr >= data + size ) + readPtr -= size; + + return len; + } + + void Write(char *in, int len) + { + int diff = (data + size) - writePtr; + + if( len > diff ) + { + memcpy(writePtr, in, diff ); + memcpy(data, in+diff, len-diff ); + } else memcpy(writePtr, in, len); + + writePtr += len; + + if (writePtr >= (data + size)) + writePtr -= size; + } + + int size; + char *data; + char *readPtr; + char *writePtr; +}; + +class VoiceRecord_SDL : public IVoiceRecord +{ +protected: + virtual ~VoiceRecord_SDL(); +public: + VoiceRecord_SDL(); + virtual void Release(); + virtual bool RecordStart(); + virtual void RecordStop(); + + // Initialize. The format of the data we expect from the provider is + // 8-bit signed mono at the specified sample rate. + virtual bool Init(int sampleRate); + virtual void Idle() {}; // Stub + void RenderBuffer( char *pszBuf, int size ); + + // Get the most recent N samples. + virtual int GetRecordedData(short *pOut, int nSamplesWanted ); + + SDL_AudioSpec m_ReceivedRecordingSpec; + int m_BytesPerSample; // Да кому нужна Ñта ваша инкапÑулÑциÑ? + int m_nSampleRate; +private: + bool InitalizeInterfaces(); // Initialize the openal capture buffers and other interfaces + void ReleaseInterfaces(); // Release openal buffers and other interfaces + void ClearInterfaces(); // Clear members. +private: + + SDL_AudioDeviceID m_Device; + AudioBuf m_AudioBuffer; +}; + +void audioRecordingCallback( void *userdata, uint8 *stream, int len ) +{ + VoiceRecord_SDL *voice = (VoiceRecord_SDL*)userdata; + voice->RenderBuffer( (char*)stream, len ); +} + +VoiceRecord_SDL::VoiceRecord_SDL() : +m_nSampleRate( 0 ) ,m_Device( 0 ) +{ + m_AudioBuffer.data = NULL; + m_AudioBuffer.readPtr = NULL; + m_AudioBuffer.writePtr = NULL; + + ClearInterfaces(); +} + +VoiceRecord_SDL::~VoiceRecord_SDL() +{ + ReleaseInterfaces(); + ClearInterfaces(); +} + +void VoiceRecord_SDL::Release() +{ + ReleaseInterfaces(); + ClearInterfaces(); + delete this; +} + +bool VoiceRecord_SDL::RecordStart() +{ + if ( !m_Device ) + InitalizeInterfaces(); + + if ( !m_Device ) + return false; + + SDL_PauseAudioDevice( m_Device, SDL_FALSE ); + + return true; +} + + +void VoiceRecord_SDL::RecordStop() +{ + // Stop capturing. + if ( m_Device ) + SDL_PauseAudioDevice( m_Device, SDL_TRUE ); + + // Release the capture buffer interface and any other resources that are no + // longer needed + ReleaseInterfaces(); +} + +bool VoiceRecord_SDL::InitalizeInterfaces() +{ + //Default audio spec + SDL_AudioSpec desiredRecordingSpec; + SDL_zero(desiredRecordingSpec); + desiredRecordingSpec.freq = m_nSampleRate; + desiredRecordingSpec.format = AUDIO_S16; + desiredRecordingSpec.channels = 1; + desiredRecordingSpec.samples = SAMPLE_COUNT; + desiredRecordingSpec.callback = audioRecordingCallback; + desiredRecordingSpec.userdata = (void*)this; + + //Open recording device + m_Device = SDL_OpenAudioDevice( NULL, SDL_TRUE, &desiredRecordingSpec, &m_ReceivedRecordingSpec, 0 ); + + if( m_Device != 0 ) + { + //Calculate per sample bytes + m_BytesPerSample = m_ReceivedRecordingSpec.channels * ( SDL_AUDIO_BITSIZE( m_ReceivedRecordingSpec.format ) / 8 ); + + //Calculate bytes per second + int bytesPerSecond = m_ReceivedRecordingSpec.freq * m_BytesPerSample; + + //Allocate and initialize byte buffer + m_AudioBuffer.size = RECORDING_BUFFER_SECONDS * bytesPerSecond; + + if( !m_AudioBuffer.data ) + m_AudioBuffer.data = (char *)malloc( m_AudioBuffer.size ); + + m_AudioBuffer.readPtr = m_AudioBuffer.data; + m_AudioBuffer.writePtr = m_AudioBuffer.data + SAMPLE_COUNT*m_BytesPerSample*2; + + memset( m_AudioBuffer.data, 0, m_AudioBuffer.size ); + + return true; + } + else + return false; +} + +bool VoiceRecord_SDL::Init(int sampleRate) +{ + m_nSampleRate = sampleRate; + ReleaseInterfaces(); + + return true; +} + + +void VoiceRecord_SDL::ReleaseInterfaces() +{ + if( m_Device != 0 ) + SDL_CloseAudioDevice( m_Device ); + + m_Device = 0; +} + + +void VoiceRecord_SDL::ClearInterfaces() +{ + if( m_AudioBuffer.data ) + { + free( m_AudioBuffer.data ); + m_AudioBuffer.data = NULL; + m_AudioBuffer.readPtr = NULL; + m_AudioBuffer.writePtr = NULL; + } + m_Device = 0; +} + +void VoiceRecord_SDL::RenderBuffer( char *pszBuf, int size ) +{ + m_AudioBuffer.Write( pszBuf, size ); +} + +int VoiceRecord_SDL::GetRecordedData(short *pOut, int nSamples ) +{ + if ( !m_AudioBuffer.data || nSamples == 0 ) + return 0; + + int cbSamples = nSamples * m_BytesPerSample; + + return m_AudioBuffer.Read( (char*)pOut, cbSamples )/m_BytesPerSample; +} + +IVoiceRecord* CreateVoiceRecord_SDL(int sampleRate) +{ + VoiceRecord_SDL *pRecord = new VoiceRecord_SDL; + if ( pRecord && pRecord->Init(sampleRate) ) + return pRecord; + else if( pRecord ) + pRecord->Release(); + + return NULL; +} diff --git a/engine/baseclient.cpp b/engine/baseclient.cpp index 9e501e33..ed81068f 100644 --- a/engine/baseclient.cpp +++ b/engine/baseclient.cpp @@ -1098,10 +1098,10 @@ void CBaseClient::EndTrace( bf_write &msg ) } if ( sv_netspike_output.GetInt() & 1 ) - COM_LogString( SERVER_PACKETS_LOG, logData.String() ); + COM_LogString( SERVER_PACKETS_LOG, (const char*)logData.String() ); if ( sv_netspike_output.GetInt() & 2 ) - Log( "%s", logData.String() ); - ETWMark1S( "netspike", logData.String() ); + Log( "%s", (const char*)logData.String() ); + ETWMark1S( "netspike", (const char*)logData.String() ); m_Trace.m_Records.RemoveAll(); m_iTracing = 0; } diff --git a/engine/baseclientstate.cpp b/engine/baseclientstate.cpp index 591f367a..bb0d3de3 100644 --- a/engine/baseclientstate.cpp +++ b/engine/baseclientstate.cpp @@ -570,7 +570,7 @@ bool CBaseClientState::PrepareSteamConnectResponse( uint64 unGSSteamID, bool bGS return true; } -#if !defined( NO_STEAM ) && !defined( SWDS ) +#if 0 //!defined( NO_STEAM ) && !defined( SWDS ) if ( !Steam3Client().SteamUser() ) { COM_ExplainDisconnection( true, "#GameUI_ServerRequireSteam" ); @@ -578,14 +578,14 @@ bool CBaseClientState::PrepareSteamConnectResponse( uint64 unGSSteamID, bool bGS return false; } #endif - + netadr_t checkAdr = adr; if ( adr.GetType() == NA_LOOPBACK || adr.IsLocalhost() ) { checkAdr.SetIP( net_local_adr.GetIPHostByteOrder() ); } -#ifndef SWDS +#if 0 // #ifndef SWDS // now append the steam3 cookie char steam3Cookie[ STEAM_KEYSIZE ]; uint32 steam3CookieLen = 0; @@ -936,6 +936,7 @@ bool CBaseClientState::ProcessConnectionlessPacket( netpacket_t *packet ) int authprotocol = msg.ReadLong(); uint64 unGSSteamID = 0; bool bGSSecure = false; +#if 0 if ( authprotocol == PROTOCOL_STEAM ) { if ( msg.ReadShort() != 0 ) @@ -963,6 +964,7 @@ bool CBaseClientState::ProcessConnectionlessPacket( netpacket_t *packet ) return false; } } +#endif SendConnectPacket( challenge, authprotocol, unGSSteamID, bGSSecure ); } break; diff --git a/engine/baseserver.cpp b/engine/baseserver.cpp index 77800aaf..b0acee7c 100644 --- a/engine/baseserver.cpp +++ b/engine/baseserver.cpp @@ -741,7 +741,7 @@ bool CBaseServer::ProcessConnectionlessPacket(netpacket_t * packet) // break; // } - if ( authProtocol == PROTOCOL_STEAM ) +/* if ( authProtocol == PROTOCOL_STEAM ) { int keyLen = msg.ReadShort(); if ( keyLen < 0 || keyLen > sizeof(cdkey) ) @@ -753,7 +753,7 @@ bool CBaseServer::ProcessConnectionlessPacket(netpacket_t * packet) ConnectClient( packet->from, protocol, challengeNr, clientChallenge, authProtocol, name, password, cdkey, keyLen ); // cd key is actually a raw encrypted key } - else + else*/ { msg.ReadString( cdkey, sizeof(cdkey) ); ConnectClient( packet->from, protocol, challengeNr, clientChallenge, authProtocol, name, password, cdkey, strlen(cdkey) ); @@ -1434,11 +1434,13 @@ bool CBaseServer::CheckChallengeType( CBaseClient * client, int nNewUserID, neta return false; } +#if 0 if ( ( nAuthProtocol == PROTOCOL_HASHEDCDKEY ) && (Q_strlen( pchLogonCookie ) <= 0 || Q_strlen(pchLogonCookie) != 32 ) ) { RejectConnection( adr, clientChallenge, "#GameUI_ServerRejectInvalidCertLen" ); return false; } +#endif Assert( !IsReplay() ); @@ -1470,23 +1472,24 @@ bool CBaseServer::CheckChallengeType( CBaseClient * client, int nNewUserID, neta client->SetSteamID( CSteamID() ); // set an invalid SteamID // Convert raw certificate back into data - if ( cbCookie <= 0 || cbCookie >= STEAM_KEYSIZE ) +/* if ( cbCookie <= 0 || cbCookie >= STEAM_KEYSIZE ) { RejectConnection( adr, clientChallenge, "#GameUI_ServerRejectInvalidSteamCertLen" ); return false; - } + }*/ netadr_t checkAdr = adr; if ( adr.GetType() == NA_LOOPBACK || adr.IsLocalhost() ) { checkAdr.SetIP( net_local_adr.GetIPHostByteOrder() ); } - +#if 0 if ( !Steam3Server().NotifyClientConnect( client, nNewUserID, checkAdr, pchLogonCookie, cbCookie ) && !Steam3Server().BLanOnly() ) // the userID isn't alloc'd yet so we need to fill it in manually { RejectConnection( adr, clientChallenge, "#GameUI_ServerRejectSteam" ); return false; } +#endif // // Any rejections below this must call SendUserDisconnect diff --git a/engine/buildcubemaps.cpp b/engine/buildcubemaps.cpp index d53caf53..ac064f91 100644 --- a/engine/buildcubemaps.cpp +++ b/engine/buildcubemaps.cpp @@ -1042,7 +1042,7 @@ void R_BuildCubemapSamples( int numIterations ) } } - bool bSupportsHDR = g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE; + bool bSupportsHDR = true; //g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE; for( i = 0; i < pWorldModel->brush.pShared->m_nCubemapSamples; i++ ) { @@ -1080,7 +1080,7 @@ void R_BuildCubemapSamples( int numIterations ) return; } - iBSPPack->SetHDRMode( g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE ); + iBSPPack->SetHDRMode( true /*g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE*/ ); iBSPPack->LoadBSPFile( g_pFileSystem, cl.m_szLevelFileName ); diff --git a/engine/cl_ents_parse.cpp b/engine/cl_ents_parse.cpp index 9d96df85..03581216 100644 --- a/engine/cl_ents_parse.cpp +++ b/engine/cl_ents_parse.cpp @@ -451,7 +451,7 @@ void CL_PreserveExistingEntity( int nOldEntity ) return; } - pEnt->OnDataUnchangedInPVS(); +// pEnt->OnDataUnchangedInPVS(); } void CL_CopyExistingEntity( CEntityReadInfo &u ) diff --git a/engine/cl_main.cpp b/engine/cl_main.cpp index ef098423..16ddddf4 100644 --- a/engine/cl_main.cpp +++ b/engine/cl_main.cpp @@ -72,6 +72,7 @@ #include "replay_internal.h" #endif +#include "language.h" #include "igame.h" // memdbgon must be the last include file in a .cpp file!!! @@ -892,7 +893,7 @@ CON_COMMAND_F( connect, "Connect to specified server.", FCVAR_DONTRECORD ) { ConMsg( "Usage: connect \n" ); } - vecArgs.PurgeAndDeleteElements(); + vecArgs.PurgeAndDeleteElementsArray(); } CON_COMMAND_F( redirect, "Redirect client to specified server.", FCVAR_DONTRECORD | FCVAR_SERVER_CAN_EXECUTE ) @@ -2743,14 +2744,18 @@ void CL_InitLanguageCvar() } else { + char *szLang = getenv("LANG"); + if ( CommandLine()->CheckParm( "-language" ) ) - { cl_language.SetValue( CommandLine()->ParmValue( "-language", "english") ); + else if( szLang ) + { + ELanguage lang = PchLanguageICUCodeToELanguage(szLang, k_Lang_English); + const char *szShortLang = GetLanguageShortName(lang); + cl_language.SetValue( szShortLang ); } else - { cl_language.SetValue( "english" ); - } } } diff --git a/engine/cl_parse_event.cpp b/engine/cl_parse_event.cpp index 183d763f..bd1eed0b 100644 --- a/engine/cl_parse_event.cpp +++ b/engine/cl_parse_event.cpp @@ -18,7 +18,7 @@ static ConVar cl_showevents ( "cl_showevents", "0", FCVAR_CHEAT, "Print event fi // Input : slot - // *eventname - //----------------------------------------------------------------------------- -void CL_DescribeEvent( int slot, CEventInfo *event, const char *eventname ) +void CL_DescribeEvent( intp slot, CEventInfo *event, const char *eventname ) { int idx = (slot & 31); @@ -81,7 +81,7 @@ void CL_FireEvents( void ) return; } - int i, next; + intp i, next; for ( i = cl.events.Head(); i != cl.events.InvalidIndex(); i = next ) { next = cl.events.Next( i ); diff --git a/engine/cl_rcon.cpp b/engine/cl_rcon.cpp index ff732ec6..b26c3085 100644 --- a/engine/cl_rcon.cpp +++ b/engine/cl_rcon.cpp @@ -56,12 +56,10 @@ public: // Immediately try to start vprofiling // Also, enable cheats on this client only Cmd_SetRptActive( true ); - StartVProfData(); } virtual void OnSocketClosed( SocketHandle_t hSocket, const netadr_t & netAdr, void* pData ) { - StopVProfData(); Cmd_SetRptActive( false ); BaseClass::OnSocketClosed( hSocket, netAdr, pData ); } @@ -98,135 +96,6 @@ static void RconAddressChanged_f( IConVar *pConVar, const char *pOldString, floa static ConVar rcon_address( "rcon_address", "", FCVAR_SERVER_CANNOT_QUERY|FCVAR_DONTRECORD, "Address of remote server if sending unconnected rcon commands (format x.x.x.x:p) ", RconAddressChanged_f ); - - -//----------------------------------------------------------------------------- -// Implementation of remote vprof -//----------------------------------------------------------------------------- -CRConVProfExport::CRConVProfExport() -{ -} - -void CRConVProfExport::AddListener() -{ -} - -void CRConVProfExport::RemoveListener() -{ -} - -void CRConVProfExport::SetBudgetFlagsFilter( int filter ) -{ -} - -int CRConVProfExport::GetNumBudgetGroups() -{ - return m_Info.Count(); -} - -void CRConVProfExport::GetBudgetGroupInfos( CExportedBudgetGroupInfo *pInfos ) -{ - memcpy( pInfos, m_Info.Base(), GetNumBudgetGroups() * sizeof(CExportedBudgetGroupInfo) ); -} - -void CRConVProfExport::GetBudgetGroupTimes( float times[IVProfExport::MAX_BUDGETGROUP_TIMES] ) -{ - int nGroups = min( m_Times.Count(), (int)IVProfExport::MAX_BUDGETGROUP_TIMES ); - memset( times, 0, nGroups * sizeof(float) ); - nGroups = min( GetNumBudgetGroups(), nGroups ); - memcpy( times, m_Times.Base(), nGroups * sizeof(float) ); -} - -void CRConVProfExport::PauseProfile() -{ - // NOTE: This only has effect when testing on a listen server - // it shouldn't do anything in the wild. When drawing the budget panel - // this will cause the time spent doing so to not be counted - VProfExport_Pause(); -} - -void CRConVProfExport::ResumeProfile() -{ - // NOTE: This only has effect when testing on a listen server - // it shouldn't do anything in the wild - VProfExport_Resume(); -} - -void CRConVProfExport::CleanupGroupData() -{ - int nCount = m_Info.Count(); - for ( int i = 0; i < nCount; ++i ) - { - delete m_Info[i].m_pName; - } - - m_Info.RemoveAll(); -} - -void CRConVProfExport::OnRemoteGroupData( const void *data, int len ) -{ - CUtlBuffer buf( data, len, CUtlBuffer::READ_ONLY ); - int nFirstGroup = buf.GetInt(); - - if ( nFirstGroup == 0 ) - { - CleanupGroupData(); - } - else - { - Assert( nFirstGroup == m_Info.Count() ); - } - - // NOTE: See WriteRemoteVProfGroupData in vprof_engine.cpp - // to see the encoding of this data - int nGroupCount = buf.GetInt(); - int nBase = m_Info.AddMultipleToTail( nGroupCount ); - char temp[1024]; - for ( int i = 0; i < nGroupCount; ++i ) - { - CExportedBudgetGroupInfo *pInfo = &m_Info[nBase + i]; - - unsigned char red, green, blue, alpha; - red = buf.GetUnsignedChar( ); - green = buf.GetUnsignedChar( ); - blue = buf.GetUnsignedChar( ); - alpha = buf.GetUnsignedChar( ); - buf.GetString( temp ); - int nLen = Q_strlen( temp ); - - pInfo->m_Color.SetColor( red, green, blue, alpha ); - char *pBuf = new char[ nLen + 1 ]; - pInfo->m_pName = pBuf; - memcpy( pBuf, temp, nLen+1 ); - pInfo->m_BudgetFlags = 0; - } -} - -void CRConVProfExport::OnRemoteData( const void *data, int len ) -{ - // NOTE: See WriteRemoteVProfData in vprof_engine.cpp - // to see the encoding of this data - int nCount = len / sizeof(float); - Assert( nCount == m_Info.Count() ); - - CUtlBuffer buf( data, len, CUtlBuffer::READ_ONLY ); - m_Times.SetCount( nCount ); - memcpy( m_Times.Base(), data, nCount * sizeof(float) ); -} - - -CON_COMMAND( vprof_remote_start, "Request a VProf data stream from the remote server (requires authentication)" ) -{ - // TODO: Make this work (it might already!) -// RCONClient().StartVProfData(); -} - -CON_COMMAND( vprof_remote_stop, "Stop an existing remote VProf data request" ) -{ - // TODO: Make this work (it might already!) -// RCONClient().StopVProfData(); -} - #ifdef ENABLE_RPT CON_COMMAND_F( rpt_screenshot, "", FCVAR_HIDDEN | FCVAR_DONTRECORD ) { @@ -454,22 +323,6 @@ void CRConClient::ParseReceivedData() } break; - case SERVERDATA_VPROF_DATA: - { - int nDataSize = m_RecvBuffer.GetInt(); - m_VProfExport.OnRemoteData( m_RecvBuffer.PeekGet(), nDataSize ); - m_RecvBuffer.SeekGet( CUtlBuffer::SEEK_CURRENT, nDataSize ); - } - break; - - case SERVERDATA_VPROF_GROUPS: - { - int nDataSize = m_RecvBuffer.GetInt(); - m_VProfExport.OnRemoteGroupData( m_RecvBuffer.PeekGet(), nDataSize ); - m_RecvBuffer.SeekGet( CUtlBuffer::SEEK_CURRENT, nDataSize ); - } - break; - case SERVERDATA_RESPONSE_STRING: { char pBuf[2048]; @@ -706,45 +559,6 @@ void CRConClient::SendCmd( const char *msg ) SendResponse( response ); } - -//----------------------------------------------------------------------------- -// Purpose: Start vprofiling -//----------------------------------------------------------------------------- -void CRConClient::StartVProfData() -{ - if ( !IsConnected() ) - { - if ( !ConnectSocket() ) - return; - } - - // Override the vprof export to point to our local profiling data - OverrideVProfExport( &m_VProfExport ); - - CUtlBuffer response; - BuildResponse( response, SERVERDATA_VPROF, "", "" ); - SendResponse( response ); -} - - -//----------------------------------------------------------------------------- -// Purpose: Stop vprofiling -//----------------------------------------------------------------------------- -void CRConClient::StopVProfData() -{ - // Reset the vprof export to point to the normal profiling data - ResetVProfExport( &m_VProfExport ); - - // Don't bother restarting a connection to turn this off - if ( !IsConnected() ) - return; - - CUtlBuffer response; - BuildResponse( response, SERVERDATA_REMOVE_VPROF, "", "" ); - SendResponse( response ); -} - - //----------------------------------------------------------------------------- // Purpose: get data from the server //----------------------------------------------------------------------------- diff --git a/engine/cl_rcon.h b/engine/cl_rcon.h index f94d938a..01305a99 100644 --- a/engine/cl_rcon.h +++ b/engine/cl_rcon.h @@ -27,47 +27,6 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" -abstract_class IVProfData -{ -public: - virtual void OnRemoteGroupData( const void *data, int len ) = 0; - virtual void OnRemoteData( const void *data, int len ) = 0; -}; - - -//----------------------------------------------------------------------------- -// Used to display client perf data in showbudget -//----------------------------------------------------------------------------- -class CRConVProfExport : public IVProfExport, public IVProfData -{ - // Inherited from IVProfExport -public: - virtual void AddListener(); - virtual void RemoveListener(); - virtual void PauseProfile(); - virtual void ResumeProfile(); - virtual void SetBudgetFlagsFilter( int filter ); - virtual int GetNumBudgetGroups(); - virtual void GetBudgetGroupInfos( CExportedBudgetGroupInfo *pInfos ); - virtual void GetBudgetGroupTimes( float times[MAX_BUDGETGROUP_TIMES] ); - - // Inherited from IVProfData -public: - virtual void OnRemoteGroupData( const void *data, int len ); - virtual void OnRemoteData( const void *data, int len ); - - // Other public methods -public: - CRConVProfExport(); - -private: - void CleanupGroupData(); - - CUtlVector< CExportedBudgetGroupInfo > m_Info; - CUtlVector m_Times; // Times from the most recent snapshot. -}; - - class CRConClient : public ISocketCreatorListener { public: @@ -89,10 +48,6 @@ public: bool IsConnected() const; bool IsAuthenticated() const { return m_bAuthenticated; } - void RegisterVProfDataCallback( IVProfData *callback ); - void StopVProfData(); - void StartVProfData(); - void TakeScreenshot(); void GrabConsoleLog(); @@ -116,7 +71,6 @@ private: void SaveRemoteScreenshot( const void* pBuffer, int nBufLen ); void SaveRemoteConsoleLog( const void* pBuffer, int nBufLen ); - CRConVProfExport m_VProfExport; CSocketCreator m_Socket; netadr_t m_Address; int m_iAuthRequestID; diff --git a/engine/client.cpp b/engine/client.cpp index c2098376..712131a2 100644 --- a/engine/client.cpp +++ b/engine/client.cpp @@ -1816,14 +1816,14 @@ void CClientState::FinishSignonState_New() // // This is pretty janky, but doesn't really have any cost (and even makes our one-frozen-frame load screen slightly // less likely to trigger OS "not responding" warnings) - extern void V_RenderVGuiOnly(); - V_RenderVGuiOnly(); +// extern void V_RenderVGuiOnly(); +// V_RenderVGuiOnly(); // Before we do anything with the whitelist, make sure we have the proper map pack mounted // this will load the .bsp by setting the world model the string list at the hardcoded index 1. cl.SetModel( 1 ); - V_RenderVGuiOnly(); + //V_RenderVGuiOnly(); // Check for a new whitelist. It's good to do it early in the connection process here because if we wait until later, // the client may have loaded some files w/o the proper whitelist restrictions and we'd have to reload them. diff --git a/engine/cmd.cpp b/engine/cmd.cpp index 20beda09..8a507e46 100644 --- a/engine/cmd.cpp +++ b/engine/cmd.cpp @@ -579,7 +579,7 @@ void Cmd_Exec_f( const CCommand &args ) const char *szFile = args[1]; - const char *pPathID = "MOD"; + const char *pPathID = "*"; Q_snprintf( fileName, sizeof( fileName ), "//%s/cfg/%s", pPathID, szFile ); Q_DefaultExtension( fileName, ".cfg", sizeof( fileName ) ); @@ -624,12 +624,13 @@ void Cmd_Exec_f( const CCommand &args ) } } - char buf[16384] = { 0 }; + char *buf = new char[16384]; int len = 0; - char *f = (char *)COM_LoadStackFile( fileName, buf, sizeof( buf ), len ); + char *f = (char *)COM_LoadStackFile( fileName, buf, 16384, len ); if ( !f ) { ConMsg( "exec: couldn't exec %s\n", szFile ); + delete[] buf; return; } @@ -645,7 +646,7 @@ void Cmd_Exec_f( const CCommand &args ) ConDMsg( "execing %s\n", szFile ); // check to make sure we're not going to overflow the cmd_text buffer - int hCommand = s_CommandBuffer.GetNextCommandHandle(); + CommandHandle_t hCommand = s_CommandBuffer.GetNextCommandHandle(); // Execute each command immediately const char *pszDataPtr = f; @@ -684,6 +685,9 @@ void Cmd_Exec_f( const CCommand &args ) free( f ); } } + + delete[] buf; + // force any queued convar changes to flush before reading/writing them UpdateMaterialSystemConfig(); } diff --git a/engine/cmodel.cpp b/engine/cmodel.cpp index e9af063d..ce1c9f2d 100644 --- a/engine/cmodel.cpp +++ b/engine/cmodel.cpp @@ -2677,6 +2677,9 @@ int CM_BoxVisible( const Vector& mins, const Vector& maxs, const byte *visbi int cluster = CM_LeafCluster( leafList[i] ); int offset = cluster>>3; + if( offset == -1 ) + return true; + if ( offset > vissize ) { Sys_Error( "CM_BoxVisible: cluster %i, offset %i out of bounds %i\n", cluster, offset, vissize ); diff --git a/engine/cmodel_bsp.cpp b/engine/cmodel_bsp.cpp index 81e96220..5d4faed3 100644 --- a/engine/cmodel_bsp.cpp +++ b/engine/cmodel_bsp.cpp @@ -288,7 +288,7 @@ bool CollisionBSPData_Load( const char *pName, CCollisionBSPData *pBSPData ) CollisionBSPData_LoadPhysics( pBSPData ); COM_TimestampedLog( " CollisionBSPData_LoadDispInfo" ); - CollisionBSPData_LoadDispInfo( pBSPData ); + CollisionBSPData_LoadDispInfo( pBSPData ); return true; } @@ -1110,7 +1110,7 @@ void CollisionBSPData_LoadDispInfo( CCollisionBSPData *pBSPData ) // get face data // int face_lump_to_load = LUMP_FACES; - if ( g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE && + if ( g_pMaterialSystemHardwareConfig->GetHDREnabled() && /*g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE &&*/ CMapLoadHelper::LumpSize( LUMP_FACES_HDR ) > 0 ) { face_lump_to_load = LUMP_FACES_HDR; diff --git a/engine/cmodel_disp.cpp b/engine/cmodel_disp.cpp index f805c4ac..5090600f 100644 --- a/engine/cmodel_disp.cpp +++ b/engine/cmodel_disp.cpp @@ -228,7 +228,7 @@ public: // Fill out the meshlist for this terrain patch virtual void GetVirtualMesh( void *userData, virtualmeshlist_t *pList ) { - int index = (int)userData; + intp index = (intp)userData; Assert(index >= 0 && index < g_DispCollTreeCount ); g_pDispCollTrees[index].GetVirtualMeshList( pList ); pList->pHull = NULL; @@ -243,14 +243,14 @@ public: // returns the bounds for the terrain patch virtual void GetWorldspaceBounds( void *userData, Vector *pMins, Vector *pMaxs ) { - int index = (int)userData; + intp index = (intp)userData; *pMins = g_pDispBounds[index].mins; *pMaxs = g_pDispBounds[index].maxs; } // Query against the AABB tree to find the list of triangles for this patch in a sphere virtual void GetTrianglesInSphere( void *userData, const Vector ¢er, float radius, virtualmeshtrianglelist_t *pList ) { - int index = (int)userData; + intp index = (intp)userData; pList->triangleCount = g_pDispCollTrees[index].AABBTree_GetTrisInSphere( center, radius, pList->triangleIndices, ARRAYSIZE(pList->triangleIndices) ); } void LevelInit( dphysdisp_t *pLump, int lumpSize ) @@ -318,7 +318,7 @@ void CM_CreateDispPhysCollide( dphysdisp_t *pDispLump, int dispLumpSize ) { g_VirtualTerrain.LevelInit(pDispLump, dispLumpSize); g_TerrainList.SetCount( g_DispCollTreeCount ); - for ( int i = 0; i < g_DispCollTreeCount; i++ ) + for ( intp i = 0; i < g_DispCollTreeCount; i++ ) { // Don't create a physics collision model for displacements that have been tagged as such. CDispCollTree *pDispTree = &g_pDispCollTrees[i]; diff --git a/engine/colorcorrectionpanel.cpp b/engine/colorcorrectionpanel.cpp index b211aecf..b198be00 100644 --- a/engine/colorcorrectionpanel.cpp +++ b/engine/colorcorrectionpanel.cpp @@ -4895,7 +4895,7 @@ void CColorOperationListPanel::PopulateList( ) KeyValues *kv = new KeyValues( "operation", "layer", op->GetName() ); kv->SetInt( "image", (op->IsEnabled())?1:0 ); - m_pOperationListPanel->AddItem( kv, (unsigned int)op, false, false ); + m_pOperationListPanel->AddItem( kv, (uintp)op, false, false ); } } } diff --git a/engine/common.cpp b/engine/common.cpp index a7a3ec5d..f9348c95 100644 --- a/engine/common.cpp +++ b/engine/common.cpp @@ -16,7 +16,11 @@ #include #include #include "common.h" +#ifdef OSX +#include +#else #include +#endif #include "traceinit.h" #include #include "filesystem_engine.h" diff --git a/engine/console.cpp b/engine/console.cpp index f2a2ba76..95dce891 100644 --- a/engine/console.cpp +++ b/engine/console.cpp @@ -479,7 +479,7 @@ Handles cursor positioning, line wrapping, etc */ static bool g_fColorPrintf = false; static bool g_bInColorPrint = false; -extern CThreadLocalInt<> g_bInSpew; +extern CTHREADLOCALINT g_bInSpew; void Con_Printf( const char *fmt, ... ); @@ -865,6 +865,7 @@ CConPanel::CConPanel( vgui::Panel *parent ) : CBasePanel( parent, "CConPanel" ) //----------------------------------------------------------------------------- CConPanel::~CConPanel( void ) { + g_pConPanel = NULL; } void CConPanel::Con_NPrintf( int idx, const char *msg ) diff --git a/engine/decals.cpp b/engine/decals.cpp index d7de7122..106ff7fd 100644 --- a/engine/decals.cpp +++ b/engine/decals.cpp @@ -14,7 +14,11 @@ #include "filesystem.h" #include "filesystem_engine.h" #include "materialsystem/imaterial.h" +#ifdef OSX +#include +#else #include +#endif #include "utldict.h" // memdbgon must be the last include file in a .cpp file!!! diff --git a/engine/disp.cpp b/engine/disp.cpp index 6c9781c1..b0cdb86c 100644 --- a/engine/disp.cpp +++ b/engine/disp.cpp @@ -547,9 +547,9 @@ bool CDispInfo::Render( CGroupMesh *pGroup, bool bAllowDebugModes ) VectorAdd( bbMin, bbMax, vecCenter ); vecCenter *= 0.5f; - int nInt = ( mat_surfaceid.GetInt() != 2 ) ? (int)m_ParentSurfID : (msurface2_t*)m_ParentSurfID - host_state.worldbrush->surfaces2; + intp nInt = ( mat_surfaceid.GetInt() != 2 ) ? (intp)m_ParentSurfID : (msurface2_t*)m_ParentSurfID - host_state.worldbrush->surfaces2; char buf[32]; - Q_snprintf( buf, sizeof( buf ), "%d", nInt ); + Q_snprintf( buf, sizeof( buf ), "%d", (int)nInt ); CDebugOverlay::AddTextOverlay( vecCenter, 0, buf ); } diff --git a/engine/disp_interface.cpp b/engine/disp_interface.cpp index da6ea461..6bf015ca 100644 --- a/engine/disp_interface.cpp +++ b/engine/disp_interface.cpp @@ -764,7 +764,7 @@ void DispInfo_BatchDecals( CDispInfo **pVisibleDisps, int nVisibleDisps ) // There is only one group at a time. int iGroup = 0; - int iPool = g_aDispDecalSortPool.Alloc( true ); + intp iPool = g_aDispDecalSortPool.Alloc( true ); g_aDispDecalSortPool[iPool] = decal.m_pDecal; int iSortTree = decal.m_pDecal->m_iSortTree; @@ -773,7 +773,7 @@ void DispInfo_BatchDecals( CDispInfo **pVisibleDisps, int nVisibleDisps ) DecalMaterialBucket_t &materialBucket = g_aDispDecalSortTrees[iSortTree].m_aDecalSortBuckets[iGroup][iTreeType].Element( iSortMaterial ); if ( materialBucket.m_nCheckCount == g_nDispDecalSortCheckCount ) { - int iHead = materialBucket.m_iHead; + intp iHead = materialBucket.m_iHead; g_aDispDecalSortPool.LinkBefore( iHead, iPool ); } @@ -844,7 +844,7 @@ void DispInfo_DrawDecalsGroup( int iGroup, int iTreeType ) if ( materialBucketList.Element( iBucket ).m_nCheckCount != g_nDispDecalSortCheckCount ) continue; - int iHead = materialBucketList.Element( iBucket ).m_iHead; + intp iHead = materialBucketList.Element( iBucket ).m_iHead; if ( !g_aDispDecalSortPool.IsValidIndex( iHead ) ) continue; @@ -863,7 +863,7 @@ void DispInfo_DrawDecalsGroup( int iGroup, int iTreeType ) bool bBatchInit = true; int nCount; - int iElement = iHead; + intp iElement = iHead; while ( iElement != g_aDispDecalSortPool.InvalidIndex() ) { decal_t *pDecal = g_aDispDecalSortPool.Element( iElement ); @@ -1300,7 +1300,7 @@ int DispInfo_ComputeIndex( HDISPINFOARRAY hArray, IDispInfo* pInfo ) if( !pArray ) return NULL; - int iElement = ((int)pInfo - (int)(pArray->m_pDispInfos)) / sizeof(CDispInfo); + intp iElement = ((intp)pInfo - (intp)(pArray->m_pDispInfos)) / sizeof(CDispInfo); Assert( iElement >= 0 && iElement < pArray->m_nDispInfos ); return iElement; diff --git a/engine/download.cpp b/engine/download.cpp index 8714b06d..f09f47dc 100644 --- a/engine/download.cpp +++ b/engine/download.cpp @@ -924,14 +924,14 @@ void CDownloadManager::StartNewDownload() m_lastPercent = 0; // Start the thread - DWORD threadID; + uintp threadID; VCRHook_CreateThread(NULL, 0, #ifdef POSIX (void *) #endif - DownloadThread, m_activeRequest, 0, (unsigned long int *)&threadID ); + DownloadThread, m_activeRequest, 0, &threadID ); - ThreadDetach( ( ThreadHandle_t )threadID ); + ReleaseThreadHandle( ( ThreadHandle_t )threadID ); } else { @@ -1070,16 +1070,16 @@ bool CL_IsGamePathValidAndSafeForDownload( const char *pGamePath ) class CDownloadSystem : public IDownloadSystem { public: - virtual DWORD CreateDownloadThread( RequestContext_t *pContext ) + virtual uintp CreateDownloadThread( RequestContext_t *pContext ) { - DWORD nThreadID; + uintp nThreadID; VCRHook_CreateThread(NULL, 0, #ifdef POSIX (void*) #endif - DownloadThread, pContext, 0, (unsigned long int *)&nThreadID ); + DownloadThread, pContext, 0, (uintp *)&nThreadID ); - ThreadDetach( ( ThreadHandle_t )nThreadID ); + ReleaseThreadHandle( ( ThreadHandle_t )nThreadID ); return nThreadID; } }; diff --git a/engine/dt_encode.cpp b/engine/dt_encode.cpp index fdd0639a..8bebd113 100644 --- a/engine/dt_encode.cpp +++ b/engine/dt_encode.cpp @@ -39,7 +39,7 @@ void EncodeFloat( const SendProp *pProp, float fVal, bf_write *pOut, int objectI } else // standard clamped-range float { - unsigned long ulVal; + unsigned int ulVal; int nBits = pProp->m_nBits; if ( flags & SPROP_NOSCALE ) { @@ -109,7 +109,7 @@ static float DecodeFloat(SendProp const *pProp, bf_read *pIn) } else // standard clamped-range float { - unsigned long dwInterp = pIn->ReadUBitLong(pProp->m_nBits); + unsigned int dwInterp = pIn->ReadUBitLong(pProp->m_nBits); float fVal = (float)dwInterp / ((1 << pProp->m_nBits) - 1); fVal = pProp->m_fLowValue + (pProp->m_fHighValue - pProp->m_fLowValue) * fVal; return fVal; @@ -281,7 +281,7 @@ void Int_Decode( DecodeInfo *pInfo ) { if ( flags & SPROP_UNSIGNED ) { - pInfo->m_Value.m_Int = (long)pInfo->m_pIn->ReadVarInt32(); + pInfo->m_Value.m_Int = (int)pInfo->m_pIn->ReadVarInt32(); } else { @@ -295,7 +295,7 @@ void Int_Decode( DecodeInfo *pInfo ) if( bits != 32 && (flags & SPROP_UNSIGNED) == 0 ) { - unsigned long highbit = 1ul << (pProp->m_nBits - 1); + unsigned int highbit = 1ul << (pProp->m_nBits - 1); if ( pInfo->m_Value.m_Int & highbit ) { pInfo->m_Value.m_Int -= highbit; // strip high bit... diff --git a/engine/dt_localtransfer.cpp b/engine/dt_localtransfer.cpp index 61c78edf..9cc101dc 100644 --- a/engine/dt_localtransfer.cpp +++ b/engine/dt_localtransfer.cpp @@ -175,12 +175,12 @@ void BuildPropOffsetToIndexMap( CSendTablePrecalc *pPrecalc, const CStandardSend { const SendProp *pProp = pPrecalc->m_Props[i]; - int offset = pProp->GetOffset() + (int)pmStack.GetCurStructBase() - 1; + intp offset = pProp->GetOffset() + (intp)pmStack.GetCurStructBase() - 1; int elementCount = 1; int elementStride = 0; if ( pProp->GetType() == DPT_Array ) { - offset = pProp->GetArrayProp()->GetOffset() + (int)pmStack.GetCurStructBase() - 1; + offset = pProp->GetArrayProp()->GetOffset() + (intp)pmStack.GetCurStructBase() - 1; elementCount = pProp->m_nElements; elementStride = pProp->m_ElementStride; } diff --git a/engine/dt_stack.h b/engine/dt_stack.h index 9fa48d4e..84e993de 100644 --- a/engine/dt_stack.h +++ b/engine/dt_stack.h @@ -121,7 +121,7 @@ inline unsigned char* UpdateRoutesExplicit_Template( DTStack *pStack, ProxyCalle // Early out. unsigned short iPropProxyIndex = pStack->m_pPrecalc->m_PropProxyIndices[pStack->m_iCurProp]; unsigned char **pTest = &pStack->m_pProxies[iPropProxyIndex]; - if ( *pTest != (unsigned char*)0xFFFFFFFF ) + if ( *pTest != (unsigned char*)-1 ) return *pTest; // Ok.. setup this proxy. @@ -133,7 +133,7 @@ inline unsigned char* UpdateRoutesExplicit_Template( DTStack *pStack, ProxyCalle CSendTablePrecalc::CProxyPathEntry *pEntry = &pStack->m_pPrecalc->m_ProxyPathEntries[proxyPath.m_iFirstEntry + i]; int iProxy = pEntry->m_iProxy; - if ( pStack->m_pProxies[iProxy] == (unsigned char*)0xFFFFFFFF ) + if ( pStack->m_pProxies[iProxy] == (unsigned char*)-1 ) { pStack->m_pProxies[iProxy] = ProxyCaller::CallProxy( pStack, pStructBase, pEntry->m_iDatatableProp ); if ( !pStack->m_pProxies[iProxy] ) diff --git a/engine/event_system.h b/engine/event_system.h index 0139cb45..7d0ba8a0 100644 --- a/engine/event_system.h +++ b/engine/event_system.h @@ -52,7 +52,7 @@ public: { if ( pData ) { - delete pData; + delete[] pData; } } @@ -65,7 +65,7 @@ public: pSendTable = src.pSendTable; pClientClass = src.pClientClass; filter.AddPlayersFromFilter( &src.filter ); - + if ( src.pData ) { int size = Bits2Bytes( src.bits ); diff --git a/engine/filesystem_engine.cpp b/engine/filesystem_engine.cpp index e0944f85..35fd1081 100644 --- a/engine/filesystem_engine.cpp +++ b/engine/filesystem_engine.cpp @@ -8,7 +8,6 @@ #include "quakedef.h" // for MAX_OSPATH #include #include -#include #include "filesystem.h" #include "bitmap/tgawriter.h" #include diff --git a/engine/gl_rsurf.cpp b/engine/gl_rsurf.cpp index 82ed85ac..5731704c 100644 --- a/engine/gl_rsurf.cpp +++ b/engine/gl_rsurf.cpp @@ -4099,7 +4099,9 @@ CBrushBatchRender::brushrender_t *CBrushBatchRender::FindOrCreateRenderBatch( mo surfaceList.Sort( SurfaceCmp ); renderT.pPlanes = new cplane_t *[planeList.Count()]; renderT.planeCount = planeList.Count(); - memcpy( renderT.pPlanes, planeList.Base(), sizeof(cplane_t *)*planeList.Count() ); + + if( planeList.Base() ) + memcpy( renderT.pPlanes, planeList.Base(), sizeof(cplane_t *)*planeList.Count() ); renderT.pSurfaces = new brushrendersurface_t[surfaceList.Count()]; renderT.surfaceCount = surfaceList.Count(); @@ -4745,7 +4747,7 @@ struct EnumLeafBoxInfo_t VectorAligned m_vecBoxCenter; VectorAligned m_vecBoxHalfDiagonal; ISpatialLeafEnumerator *m_pIterator; - int m_nContext; + intp m_nContext; }; struct EnumLeafSphereInfo_t @@ -4755,7 +4757,7 @@ struct EnumLeafSphereInfo_t Vector m_vecBoxCenter; Vector m_vecBoxHalfDiagonal; ISpatialLeafEnumerator *m_pIterator; - int m_nContext; + intp m_nContext; }; //----------------------------------------------------------------------------- @@ -5092,7 +5094,7 @@ bool EnumerateLeafInSphere_R( mnode_t *node, EnumLeafSphereInfo_t& info, int nTe //----------------------------------------------------------------------------- static bool EnumerateLeavesAlongRay_R( mnode_t *node, Ray_t const& ray, - float start, float end, ISpatialLeafEnumerator* pEnum, int context ) + float start, float end, ISpatialLeafEnumerator* pEnum, intp context ) { // no polygons in solid nodes (don't report these leaves either) if (node->contents == CONTENTS_SOLID) @@ -5151,7 +5153,7 @@ static bool EnumerateLeavesAlongRay_R( mnode_t *node, Ray_t const& ray, //----------------------------------------------------------------------------- static bool EnumerateLeavesAlongExtrudedRay_R( mnode_t *node, Ray_t const& ray, - float start, float end, ISpatialLeafEnumerator* pEnum, int context ) + float start, float end, ISpatialLeafEnumerator* pEnum, intp context ) { // no polygons in solid nodes (don't report these leaves either) if (node->contents == CONTENTS_SOLID) @@ -5274,10 +5276,10 @@ public: int LeafCount() const; // Enumerates the leaves along a ray, box, etc. - bool EnumerateLeavesAtPoint( const Vector& pt, ISpatialLeafEnumerator* pEnum, int context ); - bool EnumerateLeavesInBox( const Vector& mins, const Vector& maxs, ISpatialLeafEnumerator* pEnum, int context ); - bool EnumerateLeavesInSphere( const Vector& center, float radius, ISpatialLeafEnumerator* pEnum, int context ); - bool EnumerateLeavesAlongRay( Ray_t const& ray, ISpatialLeafEnumerator* pEnum, int context ); + bool EnumerateLeavesAtPoint( const Vector& pt, ISpatialLeafEnumerator* pEnum, intp context ); + bool EnumerateLeavesInBox( const Vector& mins, const Vector& maxs, ISpatialLeafEnumerator* pEnum, intp context ); + bool EnumerateLeavesInSphere( const Vector& center, float radius, ISpatialLeafEnumerator* pEnum, intp context ); + bool EnumerateLeavesAlongRay( Ray_t const& ray, ISpatialLeafEnumerator* pEnum, intp context ); }; //----------------------------------------------------------------------------- @@ -5302,7 +5304,7 @@ int CEngineBSPTree::LeafCount() const //----------------------------------------------------------------------------- bool CEngineBSPTree::EnumerateLeavesAtPoint( const Vector& pt, - ISpatialLeafEnumerator* pEnum, int context ) + ISpatialLeafEnumerator* pEnum, intp context ) { int leaf = CM_PointLeafnum( pt ); return pEnum->EnumerateLeaf( leaf, context ); @@ -5313,7 +5315,7 @@ static ConVar opt_EnumerateLeavesFastAlgorithm( "opt_EnumerateLeavesFastAlgorith bool CEngineBSPTree::EnumerateLeavesInBox( const Vector& mins, const Vector& maxs, - ISpatialLeafEnumerator* pEnum, int context ) + ISpatialLeafEnumerator* pEnum, intp context ) { if ( !host_state.worldmodel ) return false; @@ -5338,7 +5340,7 @@ bool CEngineBSPTree::EnumerateLeavesInBox( const Vector& mins, const Vector& max bool CEngineBSPTree::EnumerateLeavesInSphere( const Vector& center, float radius, - ISpatialLeafEnumerator* pEnum, int context ) + ISpatialLeafEnumerator* pEnum, intp context ) { EnumLeafSphereInfo_t info; info.m_vecCenter = center; @@ -5352,7 +5354,7 @@ bool CEngineBSPTree::EnumerateLeavesInSphere( const Vector& center, float radius } -bool CEngineBSPTree::EnumerateLeavesAlongRay( Ray_t const& ray, ISpatialLeafEnumerator* pEnum, int context ) +bool CEngineBSPTree::EnumerateLeavesAlongRay( Ray_t const& ray, ISpatialLeafEnumerator* pEnum, intp context ) { if (!ray.m_IsSwept) { diff --git a/engine/hltvdemo.cpp b/engine/hltvdemo.cpp index 5dc25b44..02dd0594 100644 --- a/engine/hltvdemo.cpp +++ b/engine/hltvdemo.cpp @@ -22,6 +22,7 @@ #include "host.h" #include "server.h" #include "networkstringtableclient.h" +#include "vcrmode.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" diff --git a/engine/host.cpp b/engine/host.cpp index 57370866..9ddc96b6 100644 --- a/engine/host.cpp +++ b/engine/host.cpp @@ -2750,10 +2750,6 @@ void CheckSpecialCheatVars() if ( !mat_picmip ) mat_picmip = g_pCVar->FindVar( "mat_picmip" ); - // In multiplayer, don't allow them to set mat_picmip > 2. - if ( mat_picmip ) - CheckVarRange_Generic( mat_picmip, -1, 2 ); - CheckVarRange_r_rootlod(); CheckVarRange_r_lod(); HandleServerAllowColorCorrection(); @@ -4850,7 +4846,9 @@ void Host_FreeToLowMark( bool server ) //----------------------------------------------------------------------------- void Host_Shutdown(void) { +#ifndef ANDROID extern void ShutdownMixerControls(); +#endif if ( host_checkheap ) { @@ -4962,7 +4960,7 @@ void Host_Shutdown(void) #ifndef SWDS TRACESHUTDOWN( Key_Shutdown() ); -#ifndef _X360 +#if !defined _X360 && !defined ANDROID TRACESHUTDOWN( ShutdownMixerControls() ); #endif #endif diff --git a/engine/host_saverestore.cpp b/engine/host_saverestore.cpp index 3ae1feaa..6e1afa9f 100644 --- a/engine/host_saverestore.cpp +++ b/engine/host_saverestore.cpp @@ -806,7 +806,8 @@ int CSaveRestore::SaveGameSlot( const char *pSaveName, const char *pSaveComment, m_bWaitingForSafeDangerousSave = bIsAutosaveDangerous; int iHeaderBufferSize = 64 + tokenSize + pSaveData->GetCurPos(); - void *pMem = malloc(iHeaderBufferSize); + void *pMem = new char[iHeaderBufferSize]; + CUtlBuffer saveHeader( pMem, iHeaderBufferSize ); // Write the header -- THIS SHOULD NEVER CHANGE STRUCTURE, USE SAVE_HEADER FOR NEW HEADER INFORMATION diff --git a/engine/l_studio.cpp b/engine/l_studio.cpp index ef96ab92..aca389f2 100644 --- a/engine/l_studio.cpp +++ b/engine/l_studio.cpp @@ -872,7 +872,7 @@ public: virtual void SetupLighting( const Vector &vecCenter ); virtual void SuppressEngineLighting( bool bSuppress ); - inline vertexFileHeader_t *CacheVertexData() { return g_pMDLCache->GetVertexData( (MDLHandle_t)(int)m_pStudioHdr->virtualModel&0xffff ); } + inline vertexFileHeader_t *CacheVertexData() { return g_pMDLCache->GetVertexData( VoidPtrToMDLHandle( m_pStudioHdr->VirtualModel() ) ); } bool Init(); void Shutdown(); @@ -3637,12 +3637,12 @@ void CModelRender::ValidateStaticPropColorData( ModelInstanceHandle_t handle ) // fetch the header CUtlBuffer utlBuf; char fileName[MAX_PATH]; - if ( g_pMaterialSystemHardwareConfig->GetHDRType() == HDR_TYPE_NONE || g_bBakedPropLightingNoSeparateHDR ) + if ( !g_pMaterialSystemHardwareConfig->GetHDREnabled() || g_bBakedPropLightingNoSeparateHDR ) { Q_snprintf( fileName, sizeof( fileName ), "sp_%d%s.vhv", StaticPropMgr()->GetStaticPropIndex( pProp ), GetPlatformExt() ); } else - { + { Q_snprintf( fileName, sizeof( fileName ), "sp_hdr_%d%s.vhv", StaticPropMgr()->GetStaticPropIndex( pProp ), GetPlatformExt() ); } @@ -3930,13 +3930,13 @@ bool CModelRender::LoadStaticPropColorData( IHandleEntity *pProp, DataCacheHandl // each static prop has its own compiled color mesh char fileName[MAX_PATH]; - if ( g_pMaterialSystemHardwareConfig->GetHDRType() == HDR_TYPE_NONE || g_bBakedPropLightingNoSeparateHDR ) + if ( !g_pMaterialSystemHardwareConfig->GetHDREnabled() || g_bBakedPropLightingNoSeparateHDR ) { - Q_snprintf( fileName, sizeof( fileName ), "sp_%d%s.vhv", StaticPropMgr()->GetStaticPropIndex( pProp ), GetPlatformExt() ); + Q_snprintf( fileName, sizeof( fileName ), "sp_%d%s.vhv", StaticPropMgr()->GetStaticPropIndex( pProp ), GetPlatformExt() ); } else { - Q_snprintf( fileName, sizeof( fileName ), "sp_hdr_%d%s.vhv", StaticPropMgr()->GetStaticPropIndex( pProp ), GetPlatformExt() ); + Q_snprintf( fileName, sizeof( fileName ), "sp_hdr_%d%s.vhv", StaticPropMgr()->GetStaticPropIndex( pProp ), GetPlatformExt() ); } // mark as invalid, async callback will set upon completion @@ -4121,7 +4121,7 @@ bool CModelRender::UpdateStaticPropColorData( IHandleEntity *pProp, ModelInstanc if ( !bDebugColor ) { // vertexes must be available for lighting calculation - vertexFileHeader_t *pVertexHdr = g_pMDLCache->GetVertexData( (MDLHandle_t)(int)pStudioHdr->virtualModel&0xffff ); + vertexFileHeader_t *pVertexHdr = g_pMDLCache->GetVertexData( VoidPtrToMDLHandle( pStudioHdr->VirtualModel() ) ); if ( !pVertexHdr ) { // data not available yet diff --git a/engine/materialproxyfactory.cpp b/engine/materialproxyfactory.cpp index e4936195..9ea00252 100644 --- a/engine/materialproxyfactory.cpp +++ b/engine/materialproxyfactory.cpp @@ -6,7 +6,6 @@ //=============================================================================// #include -#include #include #include "materialsystem/imaterialproxy.h" #include "materialproxyfactory.h" diff --git a/engine/matsys_interface.cpp b/engine/matsys_interface.cpp index d3067bf8..d49235c9 100644 --- a/engine/matsys_interface.cpp +++ b/engine/matsys_interface.cpp @@ -251,6 +251,9 @@ static const char *s_pRegistryConVars[] = #if defined( OSX ) #define MOD_VIDEO_CONFIG_SETTINGS "videoconfig_mac.cfg" #define USE_VIDEOCONFIG_FILE 1 +#elif defined( ANDROID ) + #define MOD_VIDEO_CONFIG_SETTINGS "videoconfig_android.cfg" + #define USE_VIDEOCONFIG_FILE 1 #elif defined( POSIX ) #define MOD_VIDEO_CONFIG_SETTINGS "videoconfig_linux.cfg" #define USE_VIDEOCONFIG_FILE 1 diff --git a/engine/modelloader.cpp b/engine/modelloader.cpp index 72a479d4..481963a0 100644 --- a/engine/modelloader.cpp +++ b/engine/modelloader.cpp @@ -483,7 +483,8 @@ void CMapLoadHelper::Init( model_t *pMapModel, const char *loadname ) s_pMap = &g_ModelLoader.m_worldBrushData; -#if 0 + // nillerusr: Fuck you johns + // XXX(johns): There are security issues with this system currently. sv_pure doesn't handle unexpected/mismatched // lumps, so players can create lumps for maps not using them to wallhack/etc.. Currently unused, // disabling until we have time to make a proper security pass. @@ -530,7 +531,6 @@ void CMapLoadHelper::Init( model_t *pMapModel, const char *loadname ) } } } -#endif } //----------------------------------------------------------------------------- @@ -1038,7 +1038,7 @@ bool Map_CheckForHDR( model_t *pModel, const char *pLoadName ) } bool bEnableHDR = ( IsX360() && bHasHDR ) || - ( bHasHDR && ( mat_hdr_level.GetInt() >= 2 ) && + ( bHasHDR && ( g_pMaterialSystemHardwareConfig->GetDXSupportLevel() >= 90 ) ); EnableHDR( bEnableHDR ); @@ -1831,7 +1831,7 @@ void *Hunk_AllocNameAlignedClear_( int size, int alignment, const char *pHunkNam Assert(IsPowerOfTwo(alignment)); void *pMem = Hunk_AllocName( alignment + size, pHunkName ); memset( pMem, 0, size + alignment ); - pMem = (void *)( ( ( ( unsigned long )pMem ) + (alignment-1) ) & ~(alignment-1) ); + pMem = (void *)( ( ( ( uintp )pMem ) + (alignment-1) ) & ~(alignment-1) ); return pMem; } @@ -1856,8 +1856,7 @@ void Mod_LoadFaces( void ) int ti, di; int face_lump_to_load = LUMP_FACES; - if ( g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE && - CMapLoadHelper::LumpSize( LUMP_FACES_HDR ) > 0 ) + if ( g_pMaterialSystemHardwareConfig->GetHDREnabled() && CMapLoadHelper::LumpSize( LUMP_FACES_HDR ) > 0 ) { face_lump_to_load = LUMP_FACES_HDR; } @@ -1870,6 +1869,12 @@ void Mod_LoadFaces( void ) // align these allocations // If you trip one of these, you need to rethink the alignment of the struct +#ifdef PLATFORM_64BITS + msurface1_t *out1 = Hunk_AllocNameAlignedClear< msurface1_t >( count, alignof(msurface1_t), va( "%s [%s]", lh.GetLoadName(), "surface1" ) ); + msurface2_t *out2 = Hunk_AllocNameAlignedClear< msurface2_t >( count, alignof(msurface2_t), va( "%s [%s]", lh.GetLoadName(), "surface2" ) ); + + msurfacelighting_t *pLighting = Hunk_AllocNameAlignedClear< msurfacelighting_t >( count, alignof(msurfacelighting_t), va( "%s [%s]", lh.GetLoadName(), "surfacelighting" ) ); +#else Assert( sizeof(msurface1_t) == 16 ); Assert( sizeof(msurface2_t) == 32 ); Assert( sizeof(msurfacelighting_t) == 32 ); @@ -1878,6 +1883,7 @@ void Mod_LoadFaces( void ) msurface2_t *out2 = Hunk_AllocNameAlignedClear< msurface2_t >( count, 32, va( "%s [%s]", lh.GetLoadName(), "surface2" ) ); msurfacelighting_t *pLighting = Hunk_AllocNameAlignedClear< msurfacelighting_t >( count, 32, va( "%s [%s]", lh.GetLoadName(), "surfacelighting" ) ); +#endif lh.GetMap()->surfaces1 = out1; lh.GetMap()->surfaces2 = out2; @@ -2289,8 +2295,7 @@ void Mod_LoadLeafs( void ) Mod_LoadLeafs_Version_0( lh ); break; case 1: - if( g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE && - CMapLoadHelper::LumpSize( LUMP_LEAF_AMBIENT_LIGHTING_HDR ) > 0 ) + if( g_pMaterialSystemHardwareConfig->GetHDREnabled() && CMapLoadHelper::LumpSize( LUMP_LEAF_AMBIENT_LIGHTING_HDR ) > 0 ) { CMapLoadHelper mlh( LUMP_LEAF_AMBIENT_LIGHTING_HDR ); CMapLoadHelper mlhTable( LUMP_LEAF_AMBIENT_INDEX_HDR ); @@ -2385,7 +2390,7 @@ void Mod_LoadCubemapSamples( void ) lh.GetMap()->m_pCubemapSamples = out; lh.GetMap()->m_nCubemapSamples = count; - bool bHDR = g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE; + bool bHDR = g_pMaterialSystemHardwareConfig->GetHDREnabled(); //g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE; int nCreateFlags = bHDR ? 0 : TEXTUREFLAGS_SRGB; // We have separate HDR versions of the textures. In order to deal with this, @@ -2862,7 +2867,7 @@ void Mod_TouchAllData( model_t *pModel, int nServerCount ) // skip self, start at children for ( int i=1; im_group.Count(); ++i ) { - MDLHandle_t childHandle = (MDLHandle_t)(int)pVirtualModel->m_group[i].cache&0xffff; + MDLHandle_t childHandle = (MDLHandle_t)(intp)pVirtualModel->m_group[i].cache&0xffff; model_t *pChildModel = (model_t *)g_pMDLCache->GetUserData( childHandle ); if ( pChildModel ) { @@ -4327,7 +4332,7 @@ public: m_pShared = pBrush->brush.pShared; m_count = 0; } - bool EnumerateLeaf( int leaf, int ) + bool EnumerateLeaf( int leaf, intp ) { // garymcthack - need to test identity brush models int flags = ( m_pShared->leafs[leaf].leafWaterDataID == -1 ) ? SURFDRAW_ABOVEWATER : SURFDRAW_UNDERWATER; @@ -4374,7 +4379,7 @@ static void MarkBrushModelWaterSurfaces( model_t* world, model_t* pTemp = host_state.worldmodel; CBrushBSPIterator brushIterator( world, brush ); host_state.SetWorldModel( world ); - g_pToolBSPTree->EnumerateLeavesInBox( mins, maxs, &brushIterator, (int)brush ); + g_pToolBSPTree->EnumerateLeavesInBox( mins, maxs, &brushIterator, (intp)brush ); brushIterator.CheckSurfaces(); host_state.SetWorldModel( pTemp ); } @@ -4453,8 +4458,7 @@ void CModelLoader::Map_LoadModel( model_t *mod ) // Until BSP version 19, this must occur after loading texinfo COM_TimestampedLog( " Mod_LoadLighting" ); - if ( g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE && - CMapLoadHelper::LumpSize( LUMP_LIGHTING_HDR ) > 0 ) + if ( g_pMaterialSystemHardwareConfig->GetHDREnabled() && CMapLoadHelper::LumpSize( LUMP_LIGHTING_HDR ) > 0 ) { CMapLoadHelper mlh( LUMP_LIGHTING_HDR ); Mod_LoadLighting( mlh ); @@ -4546,8 +4550,7 @@ void CModelLoader::Map_LoadModel( model_t *mod ) &m_worldBrushData.m_nAreas ); COM_TimestampedLog( " Mod_LoadWorldlights" ); - if ( g_pMaterialSystemHardwareConfig->GetHDRType() != HDR_TYPE_NONE && - CMapLoadHelper::LumpSize( LUMP_WORLDLIGHTS_HDR ) > 0 ) + if ( g_pMaterialSystemHardwareConfig->GetHDREnabled() && CMapLoadHelper::LumpSize( LUMP_WORLDLIGHTS_HDR ) > 0 ) { CMapLoadHelper mlh( LUMP_WORLDLIGHTS_HDR ); Mod_LoadWorldlights( mlh, true ); diff --git a/engine/net_ws.cpp b/engine/net_ws.cpp index 3c49ab6c..6a0d0efe 100644 --- a/engine/net_ws.cpp +++ b/engine/net_ws.cpp @@ -417,7 +417,7 @@ bool NET_StringToAdr ( const char *s, netadr_t *a) CNetChan *NET_FindNetChannel(int socket, netadr_t &adr) { - AUTO_LOCK( s_NetChannels ); + AUTO_LOCK_FM( s_NetChannels ); int numChannels = s_NetChannels.Count(); @@ -798,7 +798,7 @@ INetChannel *NET_CreateNetChannel(int socket, netadr_t *adr, const char * name, // create new channel chan = new CNetChan(); - AUTO_LOCK( s_NetChannels ); + AUTO_LOCK_FM( s_NetChannels ); s_NetChannels.AddToTail( chan ); } @@ -817,7 +817,7 @@ void NET_RemoveNetChannel(INetChannel *netchan, bool bDeleteNetChan) return; } - AUTO_LOCK( s_NetChannels ); + AUTO_LOCK_FM( s_NetChannels ); if ( s_NetChannels.Find( static_cast(netchan) ) == s_NetChannels.InvalidIndex() ) { DevMsg(1, "NET_CloseNetChannel: unknown channel.\n"); @@ -1389,7 +1389,7 @@ bool NET_GetLoopPacket ( netpacket_t * packet ) if ( loop->data != loop->defbuffer ) { - delete loop->data; + delete[] loop->data; loop->data = loop->defbuffer; } @@ -1677,7 +1677,7 @@ netpacket_t *NET_GetPacket (int sock, byte *scratch ) void NET_ProcessPending( void ) { - AUTO_LOCK( s_PendingSockets ); + AUTO_LOCK_FM( s_PendingSockets ); for ( int i=0; i +#else #include +#endif #include #include #include "packed_entity.h" diff --git a/engine/pr_edict.cpp b/engine/pr_edict.cpp index 755adc1c..b8b13bd0 100644 --- a/engine/pr_edict.cpp +++ b/engine/pr_edict.cpp @@ -32,7 +32,11 @@ #ifdef _DEBUG +#ifdef OSX +#include +#else #include +#endif #endif // _DEBUG static ConVar sv_useexplicitdelete( "sv_useexplicitdelete", "1", FCVAR_DEVELOPMENTONLY, "Explicitly delete dormant client entities caused by AllowImmediateReuse()." ); diff --git a/engine/pure_server.h b/engine/pure_server.h index 5fb33ef3..a5bb0ab1 100644 --- a/engine/pure_server.h +++ b/engine/pure_server.h @@ -96,7 +96,7 @@ private: CPureServerWhitelist::CCommand *pBestEntry ); unsigned short m_LoadCounter; // Incremented as we load things so their m_LoadOrder increases. - volatile long int m_RefCount; + volatile int32 m_RefCount; // Commands are applied to files in order. CUtlDict m_FileCommands; // file commands diff --git a/engine/r_decal.cpp b/engine/r_decal.cpp index 95f8c8ea..923e6ba9 100644 --- a/engine/r_decal.cpp +++ b/engine/r_decal.cpp @@ -2001,9 +2001,9 @@ void R_DrawDecalsAllImmediate_GatherDecals( IMatRenderContext *pRenderContext, i if ( g_aDecalSortTrees[iSortTree].m_aDecalSortBuckets[iGroup][iTreeType].Element( iBucket ).m_nCheckCount != nCheckCount ) continue; - int iHead = g_aDecalSortTrees[iSortTree].m_aDecalSortBuckets[iGroup][iTreeType].Element( iBucket ).m_iHead; + intp iHead = g_aDecalSortTrees[iSortTree].m_aDecalSortBuckets[iGroup][iTreeType].Element( iBucket ).m_iHead; - int iElement = iHead; + intp iElement = iHead; while ( iElement != g_aDecalSortPool.InvalidIndex() ) { decal_t *pDecal = g_aDecalSortPool.Element( iElement ); @@ -2154,11 +2154,11 @@ void R_DrawDecalsAllImmediate( IMatRenderContext *pRenderContext, int iGroup, in { if ( g_aDecalSortTrees[iSortTree].m_aDecalSortBuckets[iGroup][iTreeType].Element( iBucket ).m_nCheckCount != nCheckCount ) continue; - - int iHead = g_aDecalSortTrees[iSortTree].m_aDecalSortBuckets[iGroup][iTreeType].Element( iBucket ).m_iHead; - + + intp iHead = g_aDecalSortTrees[iSortTree].m_aDecalSortBuckets[iGroup][iTreeType].Element( iBucket ).m_iHead; + int nCount; - int iElement = iHead; + intp iElement = iHead; while ( iElement != g_aDecalSortPool.InvalidIndex() ) { decal_t *pDecal = g_aDecalSortPool.Element( iElement ); @@ -2304,7 +2304,7 @@ inline void R_DrawDecalMeshList( DecalMeshList_t &meshList ) } #define DECALMARKERS_SWITCHSORTTREE ((decal_t *)0x00000000) -#define DECALMARKERS_SWITCHBUCKET ((decal_t *)0xFFFFFFFF) +#define DECALMARKERS_SWITCHBUCKET ((decal_t *)-1) //----------------------------------------------------------------------------- // //----------------------------------------------------------------------------- @@ -2330,7 +2330,7 @@ void R_DrawDecalsAll_GatherDecals( IMatRenderContext *pRenderContext, int iGroup if ( bucket.m_nCheckCount != nCheckCount ) continue; - int iHead = bucket.m_iHead; + intp iHead = bucket.m_iHead; if ( !g_aDecalSortPool.IsValidIndex( iHead ) ) continue; @@ -2346,7 +2346,7 @@ void R_DrawDecalsAll_GatherDecals( IMatRenderContext *pRenderContext, int iGroup DrawDecals.AddToTail( DECALMARKERS_SWITCHBUCKET ); - int iElement = iHead; + intp iElement = iHead; while ( iElement != g_aDecalSortPool.InvalidIndex() ) { decal_t *pDecal = g_aDecalSortPool.Element( iElement ); @@ -2647,7 +2647,7 @@ void R_DrawDecalsAll( IMatRenderContext *pRenderContext, int iGroup, int iTreeTy if ( bucket.m_nCheckCount != nCheckCount ) continue; - int iHead = bucket.m_iHead; + intp iHead = bucket.m_iHead; if ( !g_aDecalSortPool.IsValidIndex( iHead ) ) continue; @@ -2666,7 +2666,7 @@ void R_DrawDecalsAll( IMatRenderContext *pRenderContext, int iGroup, int iTreeTy bool bBatchInit = true; int nCount; - int iElement = iHead; + intp iElement = iHead; while ( iElement != g_aDecalSortPool.InvalidIndex() ) { decal_t *pDecal = g_aDecalSortPool.Element( iElement ); @@ -3015,7 +3015,7 @@ void DecalSurfaceAdd( SurfaceHandle_t surfID, int iGroup ) } pDecal->flags &= ~FDECAL_HASUPDATED; - int iPool = g_aDecalSortPool.Alloc( true ); + intp iPool = g_aDecalSortPool.Alloc( true ); if ( iPool != g_aDecalSortPool.InvalidIndex() ) { g_aDecalSortPool[iPool] = pDecal; @@ -3024,7 +3024,7 @@ void DecalSurfaceAdd( SurfaceHandle_t surfID, int iGroup ) DecalMaterialBucket_t &bucket = sortTree.m_aDecalSortBuckets[iGroup][iTreeType].Element( pDecal->m_iSortMaterial ); if ( bucket.m_nCheckCount == nCheckCount ) { - int iHead = bucket.m_iHead; + intp iHead = bucket.m_iHead; g_aDecalSortPool.LinkBefore( iHead, iPool ); } diff --git a/engine/r_decal.h b/engine/r_decal.h index 8883c3a9..63fdb57e 100644 --- a/engine/r_decal.h +++ b/engine/r_decal.h @@ -74,7 +74,7 @@ struct DecalMaterialSortData_t struct DecalMaterialBucket_t { - int m_iHead; + intp m_iHead; int m_nCheckCount; }; @@ -82,16 +82,16 @@ inline bool DecalSortTreeSortLessFunc( const DecalMaterialSortData_t &decal1, co { if ( ( decal1.m_iLightmapPage == -1 ) || ( decal2.m_iLightmapPage == -1 ) ) { - return ( ( int )decal1.m_pMaterial < ( int )decal2.m_pMaterial ); + return ( ( intp )decal1.m_pMaterial < ( intp )decal2.m_pMaterial ); } - if ( ( int )decal1.m_pMaterial == ( int )decal2.m_pMaterial ) + if ( ( intp )decal1.m_pMaterial == ( intp )decal2.m_pMaterial ) { return ( decal1.m_iLightmapPage < decal2.m_iLightmapPage ); } else { - return ( ( int )decal1.m_pMaterial < ( int )decal2.m_pMaterial ); + return ( ( intp )decal1.m_pMaterial < ( intp )decal2.m_pMaterial ); } } diff --git a/engine/saverestore_filesystem.cpp b/engine/saverestore_filesystem.cpp index 3aef07ad..a58bab50 100644 --- a/engine/saverestore_filesystem.cpp +++ b/engine/saverestore_filesystem.cpp @@ -154,7 +154,7 @@ private: CSaveDirectory *m_pSaveDirectory; CUtlMap &GetDirectory( void ) { return m_pSaveDirectory->m_Files; } SaveFile_t &GetFile( const int idx ) { return m_pSaveDirectory->m_Files[idx]; } - SaveFile_t &GetFile( const FileHandle_t hFile ) { return GetFile( (unsigned int)hFile ); } + SaveFile_t &GetFile( const FileHandle_t hFile ) { return GetFile( (uintp)hFile ); } FileHandle_t GetFileHandle( const char *pFileName ); int GetFileIndex( const char *pFileName ); @@ -310,12 +310,12 @@ int CSaveRestoreFileSystem::GetFileIndex( const char *filename ) FileHandle_t CSaveRestoreFileSystem::GetFileHandle( const char *filename ) { - int idx = GetFileIndex( filename ); + intp idx = GetFileIndex( filename ); if ( idx == INVALID_INDEX ) { idx = 0; } - return (void*)idx; + return (FileHandle_t)idx; } //----------------------------------------------------------------------------- @@ -331,7 +331,7 @@ bool CSaveRestoreFileSystem::FileExists( const char *pFileName, const char *pPat //----------------------------------------------------------------------------- bool CSaveRestoreFileSystem::HandleIsValid( FileHandle_t hFile ) { - return hFile && GetDirectory().IsValidIndex( (unsigned int)hFile ); + return hFile && GetDirectory().IsValidIndex( (uintp)hFile ); } //----------------------------------------------------------------------------- @@ -339,7 +339,7 @@ bool CSaveRestoreFileSystem::HandleIsValid( FileHandle_t hFile ) //----------------------------------------------------------------------------- void CSaveRestoreFileSystem::RenameFile( char const *pOldPath, char const *pNewPath, const char *pathID ) { - int idx = GetFileIndex( pOldPath ); + intp idx = GetFileIndex( pOldPath ); if ( idx != INVALID_INDEX ) { CUtlSymbol newID = AddString( Q_UnqualifiedFileName( pNewPath ) ); @@ -369,7 +369,7 @@ FileHandle_t CSaveRestoreFileSystem::Open( const char *pFullName, const char *pO { SaveFile_t *pFile = NULL; CUtlSymbol id = AddString( Q_UnqualifiedFileName( pFullName ) ); - int idx = GetDirectory().Find( id ); + intp idx = GetDirectory().Find( id ); if ( idx == INVALID_INDEX ) { // Don't create a read-only file @@ -588,7 +588,7 @@ FSAsyncStatus_t CSaveRestoreFileSystem::AsyncWrite( const char *pFileName, const FileHandle_t hFile = Open( pFileName, "wb" ); if ( hFile ) { - SaveFile_t &file = GetFile( (unsigned int)hFile ); + SaveFile_t &file = GetFile( (uintp)hFile ); if( file.eType == WRITE_ONLY ) { @@ -1289,7 +1289,7 @@ public: SaveMsg( "DirectoryCopy: AsyncAppend %s, %s\n", szName, pDestFileName ); g_pFileSystem->AsyncAppend( pDestFileName, memcpy( new char[MAX_PATH], list[i].szFileName, MAX_PATH), MAX_PATH, true ); // Filename can only be as long as a map name + extension - g_pFileSystem->AsyncAppend( pDestFileName, new int(fileSize), sizeof(int), true ); + g_pFileSystem->AsyncAppend( pDestFileName, memcpy( new char[sizeof(int)], &fileSize, sizeof(int)), sizeof(int), true ); g_pFileSystem->AsyncAppendFile( pDestFileName, szName ); } } diff --git a/engine/shadowmgr.cpp b/engine/shadowmgr.cpp index d60f953c..7ed88684 100644 --- a/engine/shadowmgr.cpp +++ b/engine/shadowmgr.cpp @@ -166,7 +166,7 @@ public: virtual unsigned short InvalidShadowIndex( ); // Methods of ISpatialLeafEnumerator - virtual bool EnumerateLeaf( int leaf, int context ); + virtual bool EnumerateLeaf( int leaf, intp context ); // Sets the texture coordinate range for a shadow... virtual void SetShadowTexCoord( ShadowHandle_t handle, float x, float y, float w, float h ); @@ -605,7 +605,7 @@ void CShadowMgr::SetMaterial( Shadow_t& shadow, IMaterial* pMaterial, IMaterial* } // Search the sort order handles for an enumeration id match - int materialEnum = (int)pMaterial; + int materialEnum = (intp)pMaterial; for (unsigned short i = m_SortOrderIds.Head(); i != m_SortOrderIds.InvalidIndex(); i = m_SortOrderIds.Next(i) ) { @@ -1536,7 +1536,7 @@ void CShadowMgr::ProjectShadow( ShadowHandle_t handle, const Vector &origin, for ( int i = 0; i < nLeafCount; ++i ) { // NOTE: Scope specifier eliminates virtual function call - CShadowMgr::EnumerateLeaf( pLeafList[i], (int)&build ); + CShadowMgr::EnumerateLeaf( pLeafList[i], (intp)&build ); } } @@ -1650,7 +1650,7 @@ void CShadowMgr::ProjectFlashlight( ShadowHandle_t handle, const VMatrix& worldT for ( int i = 0; i < nLeafCount; ++i ) { // NOTE: Scope specifier eliminates virtual function call - CShadowMgr::EnumerateLeaf( pLeafList[i], (int)&build ); + CShadowMgr::EnumerateLeaf( pLeafList[i], (intp)&build ); } } @@ -1809,7 +1809,7 @@ void CShadowMgr::ApplyShadowToLeaf( const Shadow_t &shadow, mleaf_t* RESTRICT pL //----------------------------------------------------------------------------- // Applies a projected texture to all surfaces in the leaf //----------------------------------------------------------------------------- -bool CShadowMgr::EnumerateLeaf( int leaf, int context ) +bool CShadowMgr::EnumerateLeaf( int leaf, intp context ) { VPROF( "CShadowMgr::EnumerateLeaf" ); ShadowBuildInfo_t* pBuild = (ShadowBuildInfo_t*)context; @@ -2048,34 +2048,34 @@ public: class CClipPlane { public: - static inline bool Inside( ShadowVertex_t const& vert ) + static inline bool Inside( ShadowVertex_t const& vert ) { - return DotProduct( vert.m_Position, *m_pNormal ) < m_Dist; + return DotProduct( vert.m_Position, m_pNormal ) < m_Dist; } - static inline float Clip( const Vector& one, const Vector& two ) + static inline float Clip( const Vector& one, const Vector& two ) { Vector dir; VectorSubtract( two, one, dir ); - return IntersectRayWithPlane( one, dir, *m_pNormal, m_Dist ); + return IntersectRayWithPlane( one, dir, m_pNormal, m_Dist ); } static inline bool IsAbove() {return false;} static inline bool IsPlane() {return true;} - static void SetPlane( const Vector& normal, float dist ) + static void SetPlane( const Vector normal, float dist ) { - m_pNormal = &normal; + m_pNormal = normal; m_Dist = dist; } private: - static const Vector *m_pNormal; + static Vector m_pNormal; static float m_Dist; }; -const Vector *CClipPlane::m_pNormal; +Vector CClipPlane::m_pNormal; float CClipPlane::m_Dist; static inline void ClampTexCoord( ShadowVertex_t *pInVertex, ShadowVertex_t *pOutVertex ) diff --git a/engine/snd_io.cpp b/engine/snd_io.cpp index 594e7c4d..6d986647 100644 --- a/engine/snd_io.cpp +++ b/engine/snd_io.cpp @@ -20,17 +20,17 @@ class COM_IOReadBinary : public IFileReadBinary { public: - int open( const char *pFileName ); - int read( void *pOutput, int size, int file ); - void seek( int file, int pos ); - unsigned int tell( int file ); - unsigned int size( int file ); - void close( int file ); + intp open( const char *pFileName ); + int read( void *pOutput, int size, intp file ); + void seek( intp file, int pos ); + unsigned int tell( intp file ); + unsigned int size( intp file ); + void close( intp file ); }; // prepend sound/ to the filename -- all sounds are loaded from the sound/ directory -int COM_IOReadBinary::open( const char *pFileName ) +intp COM_IOReadBinary::open( const char *pFileName ) { char namebuffer[512]; FileHandle_t hFile; @@ -46,10 +46,10 @@ int COM_IOReadBinary::open( const char *pFileName ) hFile = g_pFileSystem->Open( namebuffer, "rb", "GAME" ); - return (int)hFile; + return (intp)hFile; } -int COM_IOReadBinary::read( void *pOutput, int size, int file ) +int COM_IOReadBinary::read( void *pOutput, int size, intp file ) { if ( !file ) return 0; @@ -57,7 +57,7 @@ int COM_IOReadBinary::read( void *pOutput, int size, int file ) return g_pFileSystem->Read( pOutput, size, (FileHandle_t)file ); } -void COM_IOReadBinary::seek( int file, int pos ) +void COM_IOReadBinary::seek( intp file, int pos ) { if ( !file ) return; @@ -65,7 +65,7 @@ void COM_IOReadBinary::seek( int file, int pos ) g_pFileSystem->Seek( (FileHandle_t)file, pos, FILESYSTEM_SEEK_HEAD ); } -unsigned int COM_IOReadBinary::tell( int file ) +unsigned int COM_IOReadBinary::tell( intp file ) { if ( !file ) return 0; @@ -73,7 +73,7 @@ unsigned int COM_IOReadBinary::tell( int file ) return g_pFileSystem->Tell( (FileHandle_t)file ); } -unsigned int COM_IOReadBinary::size( int file ) +unsigned int COM_IOReadBinary::size( intp file ) { if (!file) return 0; @@ -81,7 +81,7 @@ unsigned int COM_IOReadBinary::size( int file ) return g_pFileSystem->Size( (FileHandle_t)file ); } -void COM_IOReadBinary::close( int file ) +void COM_IOReadBinary::close( intp file ) { if (!file) return; diff --git a/engine/spatialpartition.cpp b/engine/spatialpartition.cpp index 489dd9cd..29689d03 100644 --- a/engine/spatialpartition.cpp +++ b/engine/spatialpartition.cpp @@ -1,4 +1,4 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// +//===== Copyright © 1996-2005, Valve Corporation, All rights reserved. ======// // // Purpose: // @@ -30,8 +30,13 @@ #include "datacache/imdlcache.h" #include "tier2/renderutils.h" #include "bitvec.h" +#include "host.h" #include "tier1/mempool.h" +#ifdef _PS3 +#include "tls_ps3.h" +#endif + // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" @@ -63,6 +68,9 @@ class CPartitionVisitor; #if defined( _X360 ) #pragma bitfield_order( push, lsb_to_msb ) +#elif defined( _PS3 ) +#pragma ms_struct on +#pragma reverse_bitfields on #endif union Voxel_t { @@ -76,6 +84,9 @@ union Voxel_t }; #if defined( _X360 ) #pragma bitfield_order( pop ) +#elif defined( _PS3 ) +#pragma ms_struct off +#pragma reverse_bitfields off #endif enum EntityInfoFlags_t @@ -89,20 +100,22 @@ enum EntityInfoFlags_t struct EntityInfo_t { Vector m_vecMin; // Min/Max of entity + Voxel_t m_voxelMin; Vector m_vecMax; + Voxel_t m_voxelMax; IHandleEntity * m_pHandleEntity; // Entity handle. unsigned short m_fList; // Which lists is it in? uint8 m_flags; char m_nLevel[NUM_TREES]; // Which level voxel tree is it in? unsigned short m_nVisitBit[NUM_TREES]; - int m_iLeafList[NUM_TREES]; // Index into the leaf pool - leaf list for entity (m_aLeafList). + intp m_iLeafList[NUM_TREES]; // Index into the leaf pool - leaf list for entity (m_aLeafList). }; struct LeafListData_t { - UtlHashFastHandle_t m_hVoxel; // Voxel handle the entity is in. - int m_iEntity; // Entity list index for voxel + UtlHashFixedHandle_t m_hVoxel; // Voxel handle the entity is in. + intp m_iEntity; // Entity list index for voxel }; typedef CUtlFixedLinkedList CLeafList; @@ -142,7 +155,12 @@ inline Voxel_t ConvertToNextLevel( Voxel_t v ) return res; } - +class CSpatialEntry +{ +public: + SpatialPartitionHandle_t m_handle; + uint16 m_nListMask; +}; //----------------------------------------------------------------------------- // A single voxel hash //----------------------------------------------------------------------------- @@ -164,8 +182,9 @@ public: bool EnumerateElementsAtPoint( SpatialPartitionListMask_t listMask, Voxel_t v, const Vector& pt, IPartitionEnumerator* pIterator ); // Inserts/Removes a handle from the tree. - void InsertIntoTree( SpatialPartitionHandle_t hPartition, const Vector &vecMin, const Vector &vecMax ); + void InsertIntoTree( SpatialPartitionHandle_t hPartition, Voxel_t voxelMin, Voxel_t voxelMax ); void RemoveFromTree( SpatialPartitionHandle_t hPartition ); + void UpdateListMask( SpatialPartitionHandle_t hPartition ); // Debug! void RenderAllObjectsInTree( float flTime ); @@ -179,6 +198,7 @@ public: // Gets the voxel size for this hash int VoxelSize( ) const; + inline float VoxelSizeF( ) const { return m_flVoxelSize; } int EntityCount(); @@ -189,6 +209,11 @@ public: inline Voxel_t VoxelIndexFromPoint( const Vector &vecWorldPoint ); inline void VoxelIndexFromPoint( const Vector &vecWorldPoint, int pPoint[3] ); +#if defined(_X360) || defined(_PS3) + inline Voxel_t VoxelIndexFromPoint( const fltx4 &vecWorldPoint ); + inline void VoxelIndexFromPoint( const fltx4 &vecWorldPoint, int pPoint[3] ); +#endif + // Setup ray for iteration void LeafListRaySetup( const Ray_t &ray, const Vector &vecEnd, const Vector &vecInvDelta, Voxel_t voxel, int *pStep, float *pMax, float *pDelta ); void LeafListExtrudedRaySetup( const Ray_t &ray, const Vector &vecInvDelta, const Vector &vecMin, const Vector &vecMax, int iVoxelMin[3], int iVoxelMax[3], int *pStep, float *pMin, float *pMax, float *pDelta ); @@ -206,14 +231,16 @@ private: inline void PackVoxel( int iX, int iY, int iZ, Voxel_t &voxel ); - typedef CUtlHashFixed > CHashTable; + typedef CUtlHashFixed > CHashTable; Vector m_vecVoxelOrigin; // Voxel space (hash) origin. CHashTable m_aVoxelHash; // Voxel tree (hash) - data = entity list head handle (m_aEntityList) int m_nVoxelDelta[3]; // Voxel world - width(Dx), height(Dy), depth(Dz) - CUtlFixedLinkedList m_aEntityList; // Pool - Linked list(multilist) of entities per leaf. + CUtlFixedLinkedList m_aEntityList; // Pool - Linked list(multilist) of entities per leaf. CVoxelTree *m_pTree; int m_nLevel; + float m_flVoxelSize; + uint m_nLevelShift; }; class CSpatialPartition; @@ -257,10 +284,11 @@ public: void Shutdown( void ); // Insert into the appropriate tree - void InsertIntoTree( SpatialPartitionHandle_t hPartition, const Vector& mins, const Vector& maxs ); + void InsertIntoTree( SpatialPartitionHandle_t hPartition, const Vector& mins, const Vector& maxs, bool bReinsert ); // Remove from appropriate tree void RemoveFromTree( SpatialPartitionHandle_t hPartition ); + void UpdateListMask( SpatialPartitionHandle_t hPartition ); void LockForWrite() { m_lock.LockForWrite(); } void UnlockWrite() { m_lock.UnlockWrite(); } @@ -273,6 +301,8 @@ public: bool EnumerateElementsAlongRay_ExtrudedRay( SpatialPartitionListMask_t listMask, const Ray_t &ray, const Vector &vecInvDelta, const Vector &vecEnd, IPartitionEnumerator *pIterator ); + bool EnumerateRayStartVoxels( SpatialPartitionListMask_t listMask, IPartitionEnumerator *pIterator, CIntersectSweptBox &intersectSweptBox, int voxelBounds[4][2][3] ); + // Purpose: void ComputeSweptRayBounds( const Ray_t &ray, const Vector &vecStartMin, const Vector &vecStartMax, Vector *pVecMin, Vector *pVecMax ); @@ -282,15 +312,11 @@ private: CVoxelHash* m_pVoxelHash; CLeafList m_aLeafList; // Pool - Linked list(multilist) of leaves per entity. int m_TreeId; - CThreadLocalPtr m_pVisits; + CPartitionVisits * m_pVisits[MAX_THREADS_SUPPORTED]; CSpatialPartition * m_pOwner; CUtlVector m_AvailableVisitBits; unsigned short m_nNextVisitBit; -#if TEST_TRACE_POOL CTSPool m_FreeVisits; -#else - CObjectPool m_FreeVisits; -#endif CThreadSpinRWLock m_lock; }; @@ -326,7 +352,7 @@ public: virtual void UnhideElement( SpatialPartitionHandle_t handle, SpatialTempHandle_t tempHandle ); virtual void InstallQueryCallback( IPartitionQueryCallback *pCallback ); - virtual void InstallQueryCallback_V1( IPartitionQueryCallback *pCallback ); + virtual void InstallQueryCallback_V1( IPartitionQueryCallback *pCallback ) { Error("Use InstallQueryCallback instead of InstallQueryCallback_V1\n"); } virtual void RemoveQueryCallback( IPartitionQueryCallback *pCallback ); virtual void SuppressLists( SpatialPartitionListMask_t nListMask, bool bSuppress ); @@ -366,6 +392,7 @@ public: CVoxelTree * VoxelTreeForHandle( SpatialPartitionHandle_t handle ); protected: + void UpdateListMask( SpatialPartitionHandle_t hPartition, uint16 nListMask ); // Invokes the pre-query callbacks. void InvokeQueryCallbacks( SpatialPartitionListMask_t listMask, bool = false ); @@ -378,7 +405,6 @@ private: CVoxelTree m_VoxelTrees[NUM_TREES]; IPartitionQueryCallback *m_pQueryCallback[MAX_QUERY_CALLBACK]; // Query callbacks. - bool m_bUseOldQueryCallback[MAX_QUERY_CALLBACK]; int m_nQueryCallbackCount; // Number of query callbacks. // Debug! @@ -411,22 +437,32 @@ inline int CVoxelTree::GetTreeId() const inline CPartitionVisits *CVoxelTree::GetVisits() { - return m_pVisits; + int nThread = g_nThreadID; + return m_pVisits[nThread]; } inline CPartitionVisits *CVoxelTree::BeginVisit() { - CPartitionVisits *pPrev = m_pVisits; + int nThread = g_nThreadID; + CPartitionVisits *pPrev = m_pVisits[nThread]; CPartitionVisits *pVisits = m_FreeVisits.GetObject(); - pVisits->Resize( m_nNextVisitBit, true ); - m_pVisits = pVisits; + if ( pVisits->GetNumBits() < m_nNextVisitBit ) + { + pVisits->Resize( m_nNextVisitBit, true ); + } + else + { + pVisits->ClearAll(); + } + m_pVisits[g_nThreadID] = pVisits; return pPrev; } inline void CVoxelTree::EndVisit( CPartitionVisits *pPrev ) { - m_FreeVisits.PutObject( m_pVisits ); - m_pVisits = pPrev; + int nThread = g_nThreadID; + m_FreeVisits.PutObject( m_pVisits[nThread] ); + m_pVisits[nThread] = pPrev; } inline CVoxelTree *CSpatialPartition::VoxelTree( SpatialPartitionListMask_t listMask ) @@ -460,13 +496,6 @@ CVoxelHash::~CVoxelHash() // Input: vecWorldPoint - world point to get voxel index for // Output: voxel index //----------------------------------------------------------------------------- -inline void CVoxelHash::VoxelIndexFromPoint( const Vector &vecWorldPoint, int pPoint[3] ) -{ - pPoint[0] = static_cast( vecWorldPoint.x - m_vecVoxelOrigin.x ) >> ( SPHASH_VOXEL_SHIFT + SPHASH_LEVEL_SKIP * m_nLevel ); - pPoint[1] = static_cast( vecWorldPoint.y - m_vecVoxelOrigin.y ) >> ( SPHASH_VOXEL_SHIFT + SPHASH_LEVEL_SKIP * m_nLevel ); - pPoint[2] = static_cast( vecWorldPoint.z - m_vecVoxelOrigin.z ) >> ( SPHASH_VOXEL_SHIFT + SPHASH_LEVEL_SKIP * m_nLevel ); -} - inline void CVoxelHash::PackVoxel( int iX, int iY, int iZ, Voxel_t &voxel ) { Assert( ( iX >= -( 1 << 10 ) ) && ( iX <= ( 1 << 10 ) ) ); @@ -477,17 +506,125 @@ inline void CVoxelHash::PackVoxel( int iX, int iY, int iZ, Voxel_t &voxel ) voxel.bitsVoxel.z = iZ; } + +#if defined(_X360) || defined(_PS3) + +// NOTE: This isn't supportable on SSE but it isn't necessary either +inline double FloatConvertToIntegerFormat( double flVal ) +{ +#if defined( _PS3 ) + return __builtin_fctiwz( flVal ); +#else + return __fctiwz( flVal ); +#endif +} + +inline fltx4 ConvertToSignedIntegerSIMD( fltx4 fl4Data ) +{ +#if defined(_X360) + return __vctsxs( fl4Data, 0 ); // NOTE: 0 is power of 2 to scale by +#else + return (fltx4)vec_cts( fl4Data, 0 ); +#endif +} + +inline fltx4 ShiftRightSIMD( const fltx4 &fl4Data, const fltx4 &fl4Shift ) +{ +#if defined(_X360) + return __vsrw( fl4Data, fl4Shift ); +#else + return (fltx4)vec_sr( (u32x4)fl4Data, (u32x4)fl4Shift ); +#endif +} + +union doublecnv_t +{ + double m_flConverted; + int32 m_nConverted[2]; +}; + +// SIMD Versions - need more code changes to fully support this but there are enough benefits to use it on some of the code +inline void CVoxelHash::VoxelIndexFromPoint( const fltx4 &fl4WorldPoint, int pPoint[3] ) +{ + fltx4 fl4Shift = (fltx4)ReplicateIX4( m_nLevelShift ); + fltx4 fl4VoxelOrigin = LoadUnaligned3SIMD( m_vecVoxelOrigin.Base() ); + fltx4 fl4LocalOrigin = SubSIMD( fl4WorldPoint, fl4VoxelOrigin ); + fltx4 fl4OriginInt = ConvertToSignedIntegerSIMD( fl4LocalOrigin ); + fl4OriginInt = ShiftRightSIMD( fl4OriginInt, fl4Shift ); + StoreUnaligned3SIMD( (float *)pPoint, fl4OriginInt ); +} + +inline void CVoxelHash::VoxelIndexFromPoint( const Vector &vecWorldPoint, int pPoint[3] ) +{ + return VoxelIndexFromPoint( LoadUnaligned3SIMD( vecWorldPoint.Base() ), pPoint ); +} + + inline Voxel_t CVoxelHash::VoxelIndexFromPoint( const Vector &vecWorldPoint ) { Voxel_t voxel; - voxel.bitsVoxel.x = static_cast( vecWorldPoint.x - m_vecVoxelOrigin.x ) >> ( SPHASH_VOXEL_SHIFT + SPHASH_LEVEL_SKIP * m_nLevel ); - voxel.bitsVoxel.y = static_cast( vecWorldPoint.y - m_vecVoxelOrigin.y ) >> ( SPHASH_VOXEL_SHIFT + SPHASH_LEVEL_SKIP * m_nLevel ); - voxel.bitsVoxel.z = static_cast( vecWorldPoint.z - m_vecVoxelOrigin.z ) >> ( SPHASH_VOXEL_SHIFT + SPHASH_LEVEL_SKIP * m_nLevel ); + // This code manually schedules the float->int conversion to avoid LHS on PPC + // First we convert the float to int format within a float register + // then we write it back to memory + volatile union doublecnv_t cnvX, cnvY, cnvZ; + cnvX.m_flConverted = FloatConvertToIntegerFormat( vecWorldPoint.x - m_vecVoxelOrigin.x ); + cnvY.m_flConverted = FloatConvertToIntegerFormat( vecWorldPoint.y - m_vecVoxelOrigin.y ); + cnvZ.m_flConverted = FloatConvertToIntegerFormat( vecWorldPoint.z - m_vecVoxelOrigin.z ); + // now we load that value back into an integer register. This will LHS if there aren't enough + // cycles between the stores and the loads but this will allow the compiler to reorder the operations + // and when the conversions are implicit they don't get reordered (load instruction immediately follows the store) + int nX = cnvX.m_nConverted[1]; + int nY = cnvY.m_nConverted[1]; + int nZ = cnvZ.m_nConverted[1]; + voxel.bitsVoxel.x = nX >> m_nLevelShift; + voxel.bitsVoxel.y = nY >> m_nLevelShift; + voxel.bitsVoxel.z = nZ >> m_nLevelShift; return voxel; } +inline Voxel_t CVoxelHash::VoxelIndexFromPoint( const fltx4 &fl4WorldPoint ) +{ + Voxel_t voxel; + + fltx4 fl4Shift = (fltx4)ReplicateIX4( m_nLevelShift ); + fltx4 fl4VoxelOrigin = LoadUnaligned3SIMD( m_vecVoxelOrigin.Base() ); + fltx4 fl4LocalOrigin = SubSIMD( fl4WorldPoint, fl4VoxelOrigin ); + fltx4 fl4OriginInt = ConvertToSignedIntegerSIMD( fl4LocalOrigin ); + fl4OriginInt = ShiftRightSIMD( fl4OriginInt, fl4Shift ); + + // UNDONE: Can probably pack these with shift, permute, or + int32 ALIGN16 tmp[4]; + StoreAlignedIntSIMD( tmp, fl4OriginInt ); + voxel.bitsVoxel.x = tmp[0]; + voxel.bitsVoxel.y = tmp[1]; + voxel.bitsVoxel.z = tmp[2]; + + return voxel; +} + +#else + +inline void CVoxelHash::VoxelIndexFromPoint( const Vector &vecWorldPoint, int pPoint[3] ) +{ + pPoint[0] = static_cast( vecWorldPoint.x - m_vecVoxelOrigin.x ) >> m_nLevelShift; + pPoint[1] = static_cast( vecWorldPoint.y - m_vecVoxelOrigin.y ) >> m_nLevelShift; + pPoint[2] = static_cast( vecWorldPoint.z - m_vecVoxelOrigin.z ) >> m_nLevelShift; +} + + +inline Voxel_t CVoxelHash::VoxelIndexFromPoint( const Vector &vecWorldPoint ) +{ + Voxel_t voxel; + + voxel.bitsVoxel.x = static_cast( vecWorldPoint.x - m_vecVoxelOrigin.x ) >> m_nLevelShift; + voxel.bitsVoxel.y = static_cast( vecWorldPoint.y - m_vecVoxelOrigin.y ) >> m_nLevelShift; + voxel.bitsVoxel.z = static_cast( vecWorldPoint.z - m_vecVoxelOrigin.z ) >> m_nLevelShift; + + return voxel; +} +#endif //----------------------------------------------------------------------------- // Purpose: Computes the voxel count at a particular level of the tree @@ -518,6 +655,8 @@ void CVoxelHash::Init( CVoxelTree *pPartition, const Vector &worldmin, const Vec { m_pTree = pPartition; m_nLevel = nLevel; + m_flVoxelSize = VoxelSize(); + m_nLevelShift = ( SPHASH_VOXEL_SHIFT + SPHASH_LEVEL_SKIP * nLevel ); // Setup the hash. MEM_ALLOC_CREDIT(); @@ -562,27 +701,21 @@ void CVoxelHash::Shutdown( void ) //----------------------------------------------------------------------------- // Purpose: Insert the object into the voxel hash. //----------------------------------------------------------------------------- -void CVoxelHash::InsertIntoTree( SpatialPartitionHandle_t hPartition, const Vector &vecMin, const Vector &vecMax ) +void CVoxelHash::InsertIntoTree( SpatialPartitionHandle_t hPartition, Voxel_t voxelMin, Voxel_t voxelMax ) { EntityInfo_t &info = m_pTree->EntityInfo( hPartition ); CLeafList &leafList = m_pTree->LeafList(); int treeId = m_pTree->GetTreeId(); - // Set the entity bounding box. - info.m_vecMin = vecMin; - info.m_vecMax = vecMax; + uint16 nListMask = m_pTree->EntityInfo( hPartition ).m_fList; // Set the voxel level info.m_nLevel[m_pTree->GetTreeId()] = m_nLevel; - // Add the object to the tree. - Voxel_t voxelMin, voxelMax; - voxelMin = VoxelIndexFromPoint( vecMin ); - voxelMax = VoxelIndexFromPoint( vecMax ); Assert( (m_nLevel == 4) || - ( (voxelMax.bitsVoxel.x - voxelMin.bitsVoxel.x <= 1) && + (voxelMax.bitsVoxel.x - voxelMin.bitsVoxel.x <= 1) && (voxelMax.bitsVoxel.y - voxelMin.bitsVoxel.y <= 1) && - (voxelMax.bitsVoxel.z - voxelMin.bitsVoxel.z <= 1) ) ); + (voxelMax.bitsVoxel.z - voxelMin.bitsVoxel.z <= 1) ); // Add the object to all the voxels it intersects. Voxel_t voxel; @@ -603,10 +736,11 @@ void CVoxelHash::InsertIntoTree( SpatialPartitionHandle_t hPartition, const Vect #endif // Entity list. - int iEntity = m_aEntityList.Alloc( true ); - m_aEntityList[iEntity] = hPartition; + intp iEntity = m_aEntityList.Alloc( true ); + m_aEntityList[iEntity].m_handle = hPartition; + m_aEntityList[iEntity].m_nListMask = nListMask; - UtlHashFastHandle_t hHash = m_aVoxelHash.Find( voxel.uiVoxel ); + UtlHashFixedHandle_t hHash = m_aVoxelHash.Find( voxel.uiVoxel ); if ( hHash == m_aVoxelHash.InvalidHandle() ) { // Add voxel(leaf) to hash. @@ -614,13 +748,13 @@ void CVoxelHash::InsertIntoTree( SpatialPartitionHandle_t hPartition, const Vect } else { - int iHead = m_aVoxelHash.Element( hHash ); + intp iHead = m_aVoxelHash.Element( hHash ); m_aEntityList.LinkBefore( iHead, iEntity ); m_aVoxelHash[hHash] = iEntity; } // Leaf list. - int iLeafList = leafList.Alloc( true ); + intp iLeafList = leafList.Alloc( true ); leafList[iLeafList].m_hVoxel = hHash; leafList[iLeafList].m_iEntity = iEntity; @@ -630,7 +764,7 @@ void CVoxelHash::InsertIntoTree( SpatialPartitionHandle_t hPartition, const Vect } else { - int iHead = info.m_iLeafList[treeId]; + intp iHead = info.m_iLeafList[treeId]; leafList.LinkBefore( iHead, iLeafList ); info.m_iLeafList[treeId] = iLeafList; } @@ -649,14 +783,14 @@ void CVoxelHash::RemoveFromTree( SpatialPartitionHandle_t hPartition ) CLeafList &leafList = m_pTree->LeafList(); int treeId = m_pTree->GetTreeId(); - int iLeaf = data.m_iLeafList[treeId]; - int iNext; + intp iLeaf = data.m_iLeafList[treeId]; + intp iNext; while ( iLeaf != leafList.InvalidIndex() ) { // Get the next voxel - if any. iNext = leafList.Next( iLeaf ); - UtlHashFastHandle_t hHash = leafList[iLeaf].m_hVoxel; + UtlHashFixedHandle_t hHash = leafList[iLeaf].m_hVoxel; if ( hHash == m_aVoxelHash.InvalidHandle() ) { iLeaf = iNext; @@ -664,12 +798,12 @@ void CVoxelHash::RemoveFromTree( SpatialPartitionHandle_t hPartition ) } // Get the head of the entity list for the voxel. - int iEntity = leafList[iLeaf].m_iEntity; - int iEntityHead = m_aVoxelHash[hHash]; + intp iEntity = leafList[iLeaf].m_iEntity; + intp iEntityHead = m_aVoxelHash[hHash]; if ( iEntityHead == iEntity ) { - int iEntityNext = m_aEntityList.Next( iEntityHead ); + intp iEntityNext = m_aEntityList.Next( iEntityHead ); if ( iEntityNext == m_aEntityList.InvalidIndex() ) { m_aVoxelHash.Remove( hHash ); @@ -691,6 +825,64 @@ void CVoxelHash::RemoveFromTree( SpatialPartitionHandle_t hPartition ) data.m_iLeafList[treeId] = leafList.InvalidIndex(); } +void CVoxelHash::UpdateListMask( SpatialPartitionHandle_t hPartition ) +{ + EntityInfo_t &data = m_pTree->EntityInfo( hPartition ); + uint16 nListMask = data.m_fList; + + Voxel_t vmin = data.m_voxelMin; + Voxel_t vmax = data.m_voxelMax; + + // single voxel + if ( vmin.uiVoxel == vmax.uiVoxel ) + { + UtlHashFixedHandle_t hHash = m_aVoxelHash.Find( vmin.uiVoxel ); + if ( hHash != m_aVoxelHash.InvalidHandle() ) + { + for ( intp i = m_aVoxelHash.Element( hHash ); i != m_aEntityList.InvalidIndex(); i = m_aEntityList.Next(i) ) + { + SpatialPartitionHandle_t handle = m_aEntityList[i].m_handle; + if ( handle != hPartition ) + continue; + + m_aEntityList[i].m_nListMask = nListMask; + break; + } + } + } + + // spans voxels + Voxel_t vdelta; + vdelta.uiVoxel = vmax.uiVoxel - vmin.uiVoxel; + int cx = vdelta.bitsVoxel.x; + int cy = vdelta.bitsVoxel.y; + int cz = vdelta.bitsVoxel.z; + Voxel_t voxel; + voxel.bitsVoxel.x = vmin.bitsVoxel.x; + for ( int iX = 0; iX <= cx; ++iX, ++voxel.bitsVoxel.x ) + { + voxel.bitsVoxel.y = vmin.bitsVoxel.y; + for ( int iY = 0; iY <= cy; ++iY, ++voxel.bitsVoxel.y ) + { + voxel.bitsVoxel.z = vmin.bitsVoxel.z; + for ( int iZ = 0; iZ <= cz; ++iZ, ++voxel.bitsVoxel.z ) + { + UtlHashFixedHandle_t hHash = m_aVoxelHash.Find( voxel.uiVoxel ); + if ( hHash != m_aVoxelHash.InvalidHandle() ) + { + for ( intp i = m_aVoxelHash.Element( hHash ); i != m_aEntityList.InvalidIndex(); i = m_aEntityList.Next(i) ) + { + if ( m_aEntityList[i].m_handle != hPartition ) + continue; + + m_aEntityList[i].m_nListMask = nListMask; + break; + } + } + } + } + } +} //----------------------------------------------------------------------------- // Purpose: @@ -803,23 +995,23 @@ private: class CIntersectPoint : public CPartitionVisitor { public: - CIntersectPoint( CVoxelTree *pPartition, const Vector &pt ) : CPartitionVisitor( pPartition ), m_vecPoint( pt ) + CIntersectPoint( CVoxelTree *pPartition, const Vector &pt ) : CPartitionVisitor( pPartition ) { + m_f4Point = LoadUnaligned3SIMD( pt.Base() ); } - bool Intersects( const Vector &vecMins, const Vector &vecMaxs ) const + bool Intersects( const float *pMins, const float *pMaxs ) const { // Ray intersection test - Assert( vecMins.x <= vecMaxs.x ); - Assert( vecMins.y <= vecMaxs.y ); - Assert( vecMins.z <= vecMaxs.z ); + Assert( pMins[0] <= pMaxs[0] ); + Assert( pMins[1] <= pMaxs[1] ); + Assert( pMins[2] <= pMaxs[2] ); - // Does the ray intersect the box? - return IsPointInBox( m_vecPoint, vecMins, vecMaxs ); + return IsPointInBox( m_f4Point, LoadUnaligned3SIMD( pMins ), LoadUnaligned3SIMD(pMaxs) ); } private: - const Vector &m_vecPoint; + fltx4 m_f4Point; }; @@ -830,16 +1022,16 @@ public: { } - bool Intersects( const Vector &vecMins, const Vector &vecMaxs ) const + bool Intersects( const float *pMins, const float *pMaxs ) const { // Box intersection test - Assert( vecMins.x <= vecMaxs.x ); - Assert( vecMins.y <= vecMaxs.y ); - Assert( vecMins.z <= vecMaxs.z ); + Assert( pMins[0] <= pMaxs[0] ); + Assert( pMins[1] <= pMaxs[1] ); + Assert( pMins[2] <= pMaxs[2] ); - return ( vecMins.x <= m_vecMaxs.x ) && ( vecMaxs.x >= m_vecMins.x ) && - ( vecMins.y <= m_vecMaxs.y ) && ( vecMaxs.y >= m_vecMins.y ) && - ( vecMins.z <= m_vecMaxs.z ) && ( vecMaxs.z >= m_vecMins.z ); + return ( pMins[0] <= m_vecMaxs.x ) && ( pMaxs[0] >= m_vecMins.x ) && + ( pMins[1] <= m_vecMaxs.y ) && ( pMaxs[1] >= m_vecMins.y ) && + ( pMins[2] <= m_vecMaxs.z ) && ( pMaxs[2] >= m_vecMins.z ); } private: @@ -850,55 +1042,64 @@ private: class CIntersectRay : public CPartitionVisitor { public: - CIntersectRay( CVoxelTree *pPartition, const Ray_t &ray, const Vector &vecInvDelta ) : CPartitionVisitor( pPartition ), m_Ray( ray ), m_vecInvDelta( vecInvDelta ) + CIntersectRay( CVoxelTree *pPartition, const Ray_t &ray, const Vector &vecInvDelta ) : CPartitionVisitor( pPartition ) { + m_f4Start = LoadUnaligned3SIMD( ray.m_Start.Base() ); + m_f4Delta = LoadUnaligned3SIMD( ray.m_Delta.Base() ); + m_f4InvDelta = LoadUnaligned3SIMD( vecInvDelta.Base() ); } - bool Intersects( const Vector &vecMins, const Vector &vecMaxs ) const + bool Intersects( const float *pMins, const float *pMaxs ) const { // Ray intersection test - Assert( vecMins.x <= vecMaxs.x ); - Assert( vecMins.y <= vecMaxs.y ); - Assert( vecMins.z <= vecMaxs.z ); + Assert( pMins[0] <= pMaxs[0] ); + Assert( pMins[1] <= pMaxs[1] ); + Assert( pMins[2] <= pMaxs[2] ); - // Does the ray intersect the box? - return IsBoxIntersectingRay( vecMins, vecMaxs, m_Ray.m_Start, m_Ray.m_Delta, m_vecInvDelta ); + fltx4 f4Mins = LoadUnaligned3SIMD( pMins ); + fltx4 f4Maxs = LoadUnaligned3SIMD( pMaxs ); + return IsBoxIntersectingRay( f4Mins, f4Maxs, m_f4Start, m_f4Delta, m_f4InvDelta ); } private: - const Ray_t &m_Ray; - const Vector &m_vecInvDelta; + fltx4 m_f4Start; + fltx4 m_f4Delta; + fltx4 m_f4InvDelta; }; class CIntersectSweptBox : public CPartitionVisitor { public: - CIntersectSweptBox( CVoxelTree *pPartition, const Ray_t &ray, const Vector &vecInvDelta ) : CPartitionVisitor( pPartition ), m_Ray( ray ), m_vecInvDelta( vecInvDelta ) + CIntersectSweptBox( CVoxelTree *pPartition, const Ray_t &ray, const Vector &vecInvDelta ) : CPartitionVisitor( pPartition ) { + m_f4Start = LoadUnaligned3SIMD( ray.m_Start.Base() ); + m_f4Delta = LoadUnaligned3SIMD( ray.m_Delta.Base() ); + m_f4InvDelta = LoadUnaligned3SIMD( vecInvDelta.Base() ); + m_f4Extents = LoadUnaligned3SIMD( ray.m_Extents.Base() ); } - bool Intersects( const Vector &vecMins, const Vector &vecMaxs ) const + bool Intersects( const float *pMins, const float *pMaxs ) const { // Swept box intersection test - Assert( vecMins.x <= vecMaxs.x ); - Assert( vecMins.y <= vecMaxs.y ); - Assert( vecMins.z <= vecMaxs.z ); + Assert( pMins[0] <= pMaxs[0] ); + Assert( pMins[1] <= pMaxs[1] ); + Assert( pMins[2] <= pMaxs[2] ); - Vector vecTestMin, vecTestMax; - VectorSubtract( vecMins, m_Ray.m_Extents, vecTestMin ); - VectorAdd( vecMaxs, m_Ray.m_Extents, vecTestMax ); + fltx4 f4Mins = LoadUnaligned3SIMD( pMins ); + fltx4 f4Maxs = LoadUnaligned3SIMD( pMaxs ); // Does the ray intersect the box? - return IsBoxIntersectingRay( vecTestMin, vecTestMax, m_Ray.m_Start, m_Ray.m_Delta, m_vecInvDelta ); + return IsBoxIntersectingRay( SubSIMD(f4Mins, m_f4Extents), AddSIMD(f4Maxs, m_f4Extents), m_f4Start, m_f4Delta, m_f4InvDelta ); } private: - const Ray_t &m_Ray; - const Vector &m_vecInvDelta; + fltx4 m_f4Start; + fltx4 m_f4Delta; + fltx4 m_f4InvDelta; + fltx4 m_f4Extents; }; - //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- @@ -906,32 +1107,33 @@ template bool CVoxelHash::EnumerateElementsInVoxel( Voxel_t voxel, const T &intersectTest, SpatialPartitionListMask_t listMask, IPartitionEnumerator* pIterator ) { // If the voxel doesn't exist, nothing to iterate over - UtlHashFastHandle_t hHash = m_aVoxelHash.Find( voxel.uiVoxel ); + UtlHashFixedHandle_t hHash = m_aVoxelHash.Find( voxel.uiVoxel ); if ( hHash == m_aVoxelHash.InvalidHandle() ) return true; - SpatialPartitionHandle_t hPartition; - for ( int i = m_aVoxelHash.Element( hHash ); i != m_aEntityList.InvalidIndex(); i = m_aEntityList.Next(i) ) + for ( intp i = m_aVoxelHash.Element( hHash ); i != m_aEntityList.InvalidIndex(); i = m_aEntityList.Next(i) ) { - hPartition = m_aEntityList[i]; - if ( hPartition == PARTITION_INVALID_HANDLE ) + SpatialPartitionHandle_t handle = m_aEntityList[i].m_handle; + SpatialPartitionListMask_t nListMask = m_aEntityList[i].m_nListMask; + if ( handle == PARTITION_INVALID_HANDLE ) continue; - EntityInfo_t &hInfo = m_pTree->EntityInfo( hPartition ); - // Keep going if this dude isn't in the list - if ( !( listMask & hInfo.m_fList ) ) + if ( !( listMask & nListMask ) ) continue; + EntityInfo_t &hInfo = m_pTree->EntityInfo( handle ); + Assert( hInfo.m_fList == nListMask ); + if ( hInfo.m_flags & ENTITY_HIDDEN ) continue; // Has this handle already been visited? - if ( !intersectTest.Visit( hPartition, hInfo ) ) + if ( !intersectTest.Visit( handle, hInfo ) ) continue; // Intersection test - if ( !intersectTest.Intersects( hInfo.m_vecMin, hInfo.m_vecMax ) ) + if ( !intersectTest.Intersects( hInfo.m_vecMin.Base(), hInfo.m_vecMax.Base() ) ) continue; // Okay, this one is good... @@ -952,29 +1154,29 @@ bool CVoxelHash::EnumerateElementsInSingleVoxel( Voxel_t voxel, const T &interse { // NOTE: We don't have to do the enum id checking, nor do we have to up the // nesting level, since this only visits 1 voxel. - int iEntityList; - UtlHashFastHandle_t hHash = m_aVoxelHash.Find( voxel.uiVoxel ); + intp iEntityList; + UtlHashFixedHandle_t hHash = m_aVoxelHash.Find( voxel.uiVoxel ); if ( hHash != m_aVoxelHash.InvalidHandle() ) { iEntityList = m_aVoxelHash.Element( hHash ); while ( iEntityList != m_aEntityList.InvalidIndex() ) { - SpatialPartitionHandle_t hPartition = m_aEntityList[iEntityList]; + SpatialPartitionHandle_t handle = m_aEntityList[iEntityList].m_handle; + SpatialPartitionListMask_t nListMask = m_aEntityList[iEntityList].m_nListMask; iEntityList = m_aEntityList.Next( iEntityList ); - if ( hPartition == PARTITION_INVALID_HANDLE ) + if ( handle == PARTITION_INVALID_HANDLE ) continue; - EntityInfo_t &hInfo = m_pTree->EntityInfo( hPartition ); - // Keep going if this dude isn't in the list - if ( !( listMask & hInfo.m_fList ) ) + if ( !( listMask & nListMask ) ) continue; + EntityInfo_t &hInfo = m_pTree->EntityInfo( handle ); if ( hInfo.m_flags & ENTITY_HIDDEN ) continue; // Keep going if there's no collision - if ( !intersectTest.Intersects( hInfo.m_vecMin, hInfo.m_vecMax ) ) + if ( !intersectTest.Intersects( hInfo.m_vecMin.Base(), hInfo.m_vecMax.Base() ) ) continue; // Okay, this one is good... @@ -1013,6 +1215,15 @@ bool CVoxelHash::EnumerateElementsInBox( SpatialPartitionListMask_t listMask, int cy = vdelta.bitsVoxel.y; int cz = vdelta.bitsVoxel.z; + // Hijack what can feel like infinite iteration over voxels +#if defined( _GAMECONSOLE ) && defined( _DEBUG ) + if ( uint64( cx ) * uint64( cy ) * uint64( cz ) > 10000ull ) + { + Assert( !"CVoxelHash::EnumerateElementsInBox: box too large" ); + return true; + } +#endif + Voxel_t voxel; voxel.bitsVoxel.x = vmin.bitsVoxel.x; for ( int iX = 0; iX <= cx; ++iX, ++voxel.bitsVoxel.x ) @@ -1394,24 +1605,24 @@ bool CVoxelHash::EnumerateElementsAtPoint( SpatialPartitionListMask_t listMask, { // NOTE: We don't have to do the enum id checking, nor do we have to up the // nesting level, since this only visits 1 voxel. - int iEntityList; - UtlHashFastHandle_t hHash = m_aVoxelHash.Find( v.uiVoxel ); + intp iEntityList; + UtlHashFixedHandle_t hHash = m_aVoxelHash.Find( v.uiVoxel ); if ( hHash != m_aVoxelHash.InvalidHandle() ) { iEntityList = m_aVoxelHash.Element( hHash ); while ( iEntityList != m_aEntityList.InvalidIndex() ) { - SpatialPartitionHandle_t hPartition = m_aEntityList[iEntityList]; + SpatialPartitionHandle_t handle = m_aEntityList[iEntityList].m_handle; + SpatialPartitionListMask_t nListMask = m_aEntityList[iEntityList].m_nListMask; iEntityList = m_aEntityList.Next( iEntityList ); - if ( hPartition == PARTITION_INVALID_HANDLE ) + if ( handle == PARTITION_INVALID_HANDLE ) continue; - EntityInfo_t &hInfo = m_pTree->EntityInfo( hPartition ); - // Keep going if this dude isn't in the list - if ( !( listMask & hInfo.m_fList ) ) + if ( !( listMask & nListMask ) ) continue; + EntityInfo_t &hInfo = m_pTree->EntityInfo( handle ); if ( hInfo.m_flags & ENTITY_HIDDEN ) continue; @@ -1433,7 +1644,7 @@ bool CVoxelHash::EnumerateElementsAtPoint( SpatialPartitionListMask_t listMask, //----------------------------------------------------------------------------- void CVoxelHash::RenderVoxel( Voxel_t voxel, float flTime ) { -#ifndef SWDS +#ifndef DEDICATED Vector vecMin, vecMax; vecMin.x = ( voxel.bitsVoxel.x * VoxelSize() ) + m_vecVoxelOrigin.x; vecMin.y = ( voxel.bitsVoxel.y * VoxelSize() ) + m_vecVoxelOrigin.y; @@ -1479,7 +1690,7 @@ void CVoxelHash::RenderVoxel( Voxel_t voxel, float flTime ) //----------------------------------------------------------------------------- void CVoxelHash::RenderObjectInVoxel( SpatialPartitionHandle_t hPartition, CPartitionVisitor *pVisitor, float flTime ) { -#ifndef SWDS +#ifndef DEDICATED // Add outline. if ( hPartition == PARTITION_INVALID_HANDLE ) return; @@ -1529,14 +1740,14 @@ void CVoxelHash::RenderObjectInVoxel( SpatialPartitionHandle_t hPartition, CPart //----------------------------------------------------------------------------- void CVoxelHash::RenderObjectsInVoxel( Voxel_t voxel, CPartitionVisitor *pVisitor, bool bRenderVoxel, float flTime ) { - UtlHashFastHandle_t hHash = m_aVoxelHash.Find( voxel.uiVoxel ); + UtlHashFixedHandle_t hHash = m_aVoxelHash.Find( voxel.uiVoxel ); if ( hHash == m_aVoxelHash.InvalidHandle() ) return; - int iEntityList = m_aVoxelHash.Element( hHash ); + intp iEntityList = m_aVoxelHash.Element( hHash ); while ( iEntityList != m_aEntityList.InvalidIndex() ) { - SpatialPartitionHandle_t hPartition = m_aEntityList[iEntityList]; + SpatialPartitionHandle_t hPartition = m_aEntityList[iEntityList].m_handle; RenderObjectInVoxel( hPartition, pVisitor, flTime ); iEntityList = m_aEntityList.Next( iEntityList ); } @@ -1564,7 +1775,7 @@ int CVoxelHash::EntityCount() while ( hHash != m_aVoxelHash.m_aBuckets[iBucket].InvalidIndex() ) { - int iEntity = m_aVoxelHash.m_aBuckets[iBucket][hHash].m_Data; + intp iEntity = m_aVoxelHash.m_aBuckets[iBucket][hHash].m_Data; while ( iEntity!= m_aEntityList.InvalidIndex() ) { ++nCount; @@ -1583,7 +1794,7 @@ int CVoxelHash::EntityCount() //----------------------------------------------------------------------------- void CVoxelHash::RenderGrid() { -#ifndef SWDS +#ifndef DEDICATED Vector vecStart, vecEnd; for ( int i = 0; i < m_nVoxelDelta[0]; ++i ) { @@ -1645,10 +1856,10 @@ void CVoxelHash::RenderAllObjectsInTree( float flTime ) while ( hHash != m_aVoxelHash.m_aBuckets[iBucket].InvalidIndex() ) { - int iEntity = m_aVoxelHash.m_aBuckets[iBucket][hHash].m_Data; + intp iEntity = m_aVoxelHash.m_aBuckets[iBucket][hHash].m_Data; while ( iEntity!= m_aEntityList.InvalidIndex() ) { - SpatialPartitionHandle_t hPartition = m_aEntityList[iEntity]; + SpatialPartitionHandle_t hPartition = m_aEntityList[iEntity].m_handle; RenderObjectInVoxel( hPartition, &visitor, flTime ); iEntity = m_aEntityList.Next( iEntity ); } @@ -1744,7 +1955,7 @@ void CVoxelTree::Init( CSpatialPartition *pOwner, int iTree, const Vector &world m_TreeId = iTree; // Reset the enumeration id. - m_pVisits = NULL; + memset( m_pVisits, 0, sizeof( m_pVisits ) ); for ( int i = 0; i < m_nLevelCount; ++i ) { @@ -1769,32 +1980,14 @@ void CVoxelTree::Shutdown( void ) } } - //----------------------------------------------------------------------------- // Insert into the appropriate tree //----------------------------------------------------------------------------- -void CVoxelTree::InsertIntoTree( SpatialPartitionHandle_t hPartition, const Vector& mins, const Vector& maxs ) +void CVoxelTree::InsertIntoTree( SpatialPartitionHandle_t hPartition, const Vector& mins, const Vector& maxs, bool bReinsert ) { - bool bWasReading = ( m_pVisits != NULL ); - if ( bWasReading ) - { - // If we're recursing in this thread, need to release our read lock to allow ourselves to write - UnlockRead(); - } - - m_lock.LockForWrite(); Assert( hPartition != PARTITION_INVALID_HANDLE ); EntityInfo_t &info = EntityInfo( hPartition ); - if ( m_AvailableVisitBits.Count() ) - { - info.m_nVisitBit[m_TreeId] = m_AvailableVisitBits.Tail(); - m_AvailableVisitBits.Remove( m_AvailableVisitBits.Count() - 1 ); - } - else - { - info.m_nVisitBit[m_TreeId] = m_nNextVisitBit++; - } // Bloat by an eps before inserting the object into the tree. Vector vecMin( mins.x - SPHASH_EPS, mins.y - SPHASH_EPS, mins.z - SPHASH_EPS ); @@ -1808,16 +2001,63 @@ void CVoxelTree::InsertIntoTree( SpatialPartitionHandle_t hPartition, const Vect int nLevel; for ( nLevel = 0; nLevel < m_nLevelCount - 1; ++nLevel ) { - int nVoxelSize = m_pVoxelHash[nLevel].VoxelSize(); - if ( (nVoxelSize > vecSize.x) && (nVoxelSize > vecSize.y) && (nVoxelSize > vecSize.z) ) + float flVoxelSize = m_pVoxelHash[nLevel].VoxelSizeF(); + if ( (flVoxelSize > vecSize.x) && (flVoxelSize > vecSize.y) && (flVoxelSize > vecSize.z) ) break; } - m_pVoxelHash[nLevel].InsertIntoTree( hPartition, vecMin, vecMax ); - m_lock.UnlockWrite(); - if ( bWasReading ) + // Add the object to the tree. + Voxel_t voxelMin, voxelMax; + voxelMin = m_pVoxelHash[nLevel].VoxelIndexFromPoint( vecMin ); + voxelMax = m_pVoxelHash[nLevel].VoxelIndexFromPoint( vecMax ); + + bool bDoInsert = true; + if ( bReinsert ) { - LockForRead(); + // on reinsert we need to either remove/insert or not do anything + // if the entity spans the same bounding box of voxels no remove/insert is necessary + if ( info.m_voxelMin.uiVoxel == voxelMin.uiVoxel && info.m_voxelMax.uiVoxel == voxelMax.uiVoxel ) + { + bDoInsert = false; + } + else + { + // Remove entity from voxel hash. + RemoveFromTree( hPartition ); + } + } + // Set/update the entity bounding box. + info.m_vecMin = vecMin; + info.m_vecMax = vecMax; + + if ( bDoInsert ) + { + bool bWasReading = ( m_pVisits[g_nThreadID] != NULL ); + if ( bWasReading ) + { + // If we're recursing in this thread, need to release our read lock to allow ourselves to write + UnlockRead(); + } + m_lock.LockForWrite(); + + // if these have changed we need to insert + info.m_voxelMin = voxelMin; + info.m_voxelMax = voxelMax; + if ( m_AvailableVisitBits.Count() ) + { + info.m_nVisitBit[m_TreeId] = m_AvailableVisitBits.Tail(); + m_AvailableVisitBits.Remove( m_AvailableVisitBits.Count() - 1 ); + } + else + { + info.m_nVisitBit[m_TreeId] = m_nNextVisitBit++; + } + m_pVoxelHash[nLevel].InsertIntoTree( hPartition, voxelMin, voxelMax ); + m_lock.UnlockWrite(); + if ( bWasReading ) + { + LockForRead(); + } } } @@ -1832,7 +2072,7 @@ void CVoxelTree::RemoveFromTree( SpatialPartitionHandle_t hPartition ) int nLevel = info.m_nLevel[GetTreeId()]; if ( nLevel >= 0 ) { - bool bWasReading = ( m_pVisits != NULL ); + bool bWasReading = ( m_pVisits[g_nThreadID] != NULL ); if ( bWasReading ) { // If we're recursing in this thread, need to release our read lock to allow ourselves to write @@ -1852,6 +2092,18 @@ void CVoxelTree::RemoveFromTree( SpatialPartitionHandle_t hPartition ) } } +void CVoxelTree::UpdateListMask( SpatialPartitionHandle_t hPartition ) +{ + EntityInfo_t &info = EntityInfo( hPartition ); + int nLevel = info.m_nLevel[GetTreeId()]; + if ( nLevel >= 0 ) + { + m_lock.LockForRead(); + m_pVoxelHash[nLevel].UpdateListMask( hPartition ); + m_lock.UnlockRead(); + } +} + //----------------------------------------------------------------------------- // Called when an element moves @@ -1864,25 +2116,12 @@ void CVoxelTree::ElementMoved( SpatialPartitionHandle_t hPartition, const Vector EntityInfo_t &info = EntityInfo( hPartition ); if ( info.m_iLeafList[GetTreeId()] == CLeafList::InvalidIndex() ) { - InsertIntoTree( hPartition, mins, maxs ); + InsertIntoTree( hPartition, mins, maxs, false ); return; } - // Bloat by an eps before inserting the object into the tree. - // Need to do this here to get the test to work - Vector vecEpsMin( mins.x - SPHASH_EPS, mins.y - SPHASH_EPS, mins.z - SPHASH_EPS ); - Vector vecEpsMax( maxs.x + SPHASH_EPS, maxs.y + SPHASH_EPS, maxs.z + SPHASH_EPS ); - - if ( (info.m_vecMin == vecEpsMin) && (info.m_vecMax == vecEpsMax) ) - { - return; - } - - // Remove entity from voxel hash. - RemoveFromTree( hPartition ); - // Re-insert entity into voxel hash. - InsertIntoTree( hPartition, mins, maxs ); + InsertIntoTree( hPartition, mins, maxs, true ); } } @@ -2114,6 +2353,56 @@ void CVoxelTree::ComputeSweptRayBounds( const Ray_t &ray, const Vector &vecStart } } +bool CVoxelTree::EnumerateRayStartVoxels( SpatialPartitionListMask_t listMask, IPartitionEnumerator *pIterator, CIntersectSweptBox &intersectSweptBox, int voxelBounds[4][2][3] ) +{ + // Iterate over all voxels that intersect the box around the starting ray point + int nMinX = voxelBounds[0][0][0]; + int nMinY = voxelBounds[0][0][1]; + int nMinZ = voxelBounds[0][0][2]; + + int nMaxX = voxelBounds[0][1][0]; + int nMaxY = voxelBounds[0][1][1]; + int nMaxZ = voxelBounds[0][1][2]; + for ( int i = 0; i < m_nLevelCount; ++i ) + { + if ( i != 0 ) + { + nMinX >>= SPHASH_LEVEL_SKIP; + nMinY >>= SPHASH_LEVEL_SKIP; + nMinZ >>= SPHASH_LEVEL_SKIP; + nMaxX >>= SPHASH_LEVEL_SKIP; + nMaxY >>= SPHASH_LEVEL_SKIP; + nMaxZ >>= SPHASH_LEVEL_SKIP; + + voxelBounds[i][0][0] = nMinX; + voxelBounds[i][0][1] = nMinY; + voxelBounds[i][0][2] = nMinZ; + + voxelBounds[i][1][0] = nMaxX; + voxelBounds[i][1][1] = nMaxY; + voxelBounds[i][1][2] = nMaxZ; + } + + Voxel_t voxel; + int iX, iY, iZ; + for ( iX = nMinX; iX <= nMaxX; ++iX ) + { + voxel.bitsVoxel.x = iX; + for ( iY = nMinY; iY <= nMaxY; ++iY ) + { + voxel.bitsVoxel.y = iY; + for ( iZ = nMinZ; iZ <= nMaxZ; ++iZ ) + { + voxel.bitsVoxel.z = iZ; + if ( !m_pVoxelHash[i].EnumerateElementsInVoxel( voxel, intersectSweptBox, listMask, pIterator ) ) + return false; + } + } + } + } + + return true; +} //----------------------------------------------------------------------------- // Purpose: @@ -2134,40 +2423,21 @@ bool CVoxelTree::EnumerateElementsAlongRay_ExtrudedRay( SpatialPartitionListMask CIntersectSweptBox intersectSweptBox( this, ray, vecInvDelta ); - // Iterate over all voxels that intersect the box around the starting ray point - for ( int i = 0; i < m_nLevelCount; ++i ) - { - voxelBounds[i][0][0] = voxelBounds[0][0][0] >> ( i * SPHASH_LEVEL_SKIP ); - voxelBounds[i][0][1] = voxelBounds[0][0][1] >> ( i * SPHASH_LEVEL_SKIP ); - voxelBounds[i][0][2] = voxelBounds[0][0][2] >> ( i * SPHASH_LEVEL_SKIP ); - - voxelBounds[i][1][0] = voxelBounds[0][1][0] >> ( i * SPHASH_LEVEL_SKIP ); - voxelBounds[i][1][1] = voxelBounds[0][1][1] >> ( i * SPHASH_LEVEL_SKIP ); - voxelBounds[i][1][2] = voxelBounds[0][1][2] >> ( i * SPHASH_LEVEL_SKIP ); - - Voxel_t voxel; - int iX, iY, iZ; - for ( iX = voxelBounds[i][0][0]; iX <= voxelBounds[i][1][0]; ++iX ) - { - voxel.bitsVoxel.x = iX; - for ( iY = voxelBounds[i][0][1]; iY <= voxelBounds[i][1][1]; ++iY ) - { - voxel.bitsVoxel.y = iY; - for ( iZ = voxelBounds[i][0][2]; iZ <= voxelBounds[i][1][2]; ++iZ ) - { - voxel.bitsVoxel.z = iZ; - if ( !m_pVoxelHash[i].EnumerateElementsInVoxel( voxel, intersectSweptBox, listMask, pIterator ) ) - return false; - } - } - } - } + if ( !EnumerateRayStartVoxels( listMask, pIterator, intersectSweptBox, voxelBounds ) ) + return false; // Early out: Check to see if the range of voxels at the endpoint // is the same as the range at the start point. If so, we're done. +#if defined(_X360) || defined(_PS3) + fltx4 fl4RayEnd = LoadUnaligned3SIMD(vecEnd.Base()); + fltx4 fl4Extents = LoadAlignedSIMD(ray.m_Extents.Base()); + fltx4 vecEndMin = SubSIMD( fl4RayEnd, fl4Extents ); + fltx4 vecEndMax = AddSIMD( fl4RayEnd, fl4Extents ); +#else Vector vecEndMin, vecEndMax; VectorSubtract( vecEnd, ray.m_Extents, vecEndMin ); VectorAdd( vecEnd, ray.m_Extents, vecEndMax ); +#endif int endVoxelMin[3], endVoxelMax[3]; m_pVoxelHash[0].VoxelIndexFromPoint( vecEndMin, endVoxelMin ); @@ -2247,15 +2517,44 @@ bool CVoxelTree::EnumerateElementsAlongRay_ExtrudedRay( SpatialPartitionListMask return true; } +#ifndef _PS3 +#define THINK_TRACE_COUNTER_COMPILE_FUNCTIONS_ENGINE +#include "engine/thinktracecounter.h" +#endif + +#ifdef THINK_TRACE_COUNTER_COMPILED +ConVar think_trace_limit( "think_trace_limit", "0", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY, "Break into the debugger if this many or more traces are performed in a single think function. Negative numbers mean that the same think function may be broken into many times (once per [x] may traces), positive numbers mean each think will break only once." ); +CTHREADLOCALINT g_DebugTracesRemainingBeforeTrap(0); +#endif //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- - void CVoxelTree::EnumerateElementsAlongRay( SpatialPartitionListMask_t listMask, const Ray_t &ray, bool coarseTest, IPartitionEnumerator *pIterator ) { VPROF("EnumerateElementsAlongRay"); +#ifdef THINK_TRACE_COUNTER_COMPILED + if ( DEBUG_THINK_TRACE_COUNTER_ALLOWED() && think_trace_limit.GetInt() != 0 && g_DebugTracesRemainingBeforeTrap > 0 ) + { + if ( --g_DebugTracesRemainingBeforeTrap <= 0 ) + { + if ( Plat_IsInDebugSession() ) + { + + DebuggerBreakIfDebugging(); + if ( think_trace_limit.GetInt() < 0 ) + { + g_DebugTracesRemainingBeforeTrap = -think_trace_limit.GetInt(); + } + } + else + { + AssertMsg1( false, "Performed %d traces in a single think function!\n", think_trace_limit.GetInt() ); + } + } + } +#endif if ( !ray.m_IsSwept ) { @@ -2424,6 +2723,7 @@ CSpatialPartition::~CSpatialPartition() void CSpatialPartition::Init( const Vector &worldmin, const Vector &worldmax ) { // Clear the handle list and ensure some new memory. + MEM_ALLOC_CREDIT(); m_aHandles.Purge(); m_aHandles.EnsureCapacity( SPHASH_HANDLELIST_BLOCK ); @@ -2459,26 +2759,6 @@ void CSpatialPartition::InstallQueryCallback( IPartitionQueryCallback *pCallback return; m_pQueryCallback[m_nQueryCallbackCount] = pCallback; - m_bUseOldQueryCallback[m_nQueryCallbackCount] = false; - ++m_nQueryCallbackCount; -} - -//----------------------------------------------------------------------------- -// Purpose: Add a callback to the query callback list. Functions get called -// right before a query occurs. -// Input: pCallback - pointer to the callback function to add -//----------------------------------------------------------------------------- -void CSpatialPartition::InstallQueryCallback_V1( IPartitionQueryCallback *pCallback ) -{ - // Verify data. - Assert( pCallback && m_nQueryCallbackCount < MAX_QUERY_CALLBACK ); - if ( !pCallback || ( m_nQueryCallbackCount >= MAX_QUERY_CALLBACK ) ) - return; - - // NOTE: the query callbacks are not mutexed. Only add and remove when threads are joined - - m_pQueryCallback[m_nQueryCallbackCount] = pCallback; - m_bUseOldQueryCallback[m_nQueryCallbackCount] = true; ++m_nQueryCallbackCount; } @@ -2514,21 +2794,11 @@ void CSpatialPartition::InvokeQueryCallbacks( SpatialPartitionListMask_t listMas { if ( !bDone ) { - if ( m_bUseOldQueryCallback[iQuery] ) - { - m_pQueryCallback[iQuery]->OnPreQuery_V1(); - } - else - { - m_pQueryCallback[iQuery]->OnPreQuery( listMask ); - } + m_pQueryCallback[iQuery]->OnPreQuery( listMask ); } else { - if ( !m_bUseOldQueryCallback[iQuery] ) - { - m_pQueryCallback[iQuery]->OnPostQuery( listMask ); - } + m_pQueryCallback[iQuery]->OnPostQuery( listMask ); } } } @@ -2595,6 +2865,25 @@ SpatialPartitionHandle_t CSpatialPartition::CreateHandle( IHandleEntity *pHandle return hPartition; } + +void CSpatialPartition::UpdateListMask( SpatialPartitionHandle_t hPartition, uint16 nListMask ) +{ + EntityInfo_t &entityInfo = EntityInfo( hPartition ); + if ( entityInfo.m_fList != nListMask ) + { + entityInfo.m_fList = nListMask; + + if ( entityInfo.m_flags & IN_CLIENT_TREE ) + { + m_VoxelTrees[CLIENT_TREE].UpdateListMask( hPartition ); + } + + if ( entityInfo.m_flags & IN_SERVER_TREE ) + { + m_VoxelTrees[SERVER_TREE].UpdateListMask( hPartition ); + } + } +} //----------------------------------------------------------------------------- // Purpose: Insert object handle into group(s). // Input: listId - list(s) to insert the object handle into @@ -2604,7 +2893,7 @@ void CSpatialPartition::Insert( SpatialPartitionListMask_t listId, SpatialPartit { Assert( m_aHandles.IsValidIndex( handle ) ); Assert( listId <= USHRT_MAX ); - m_aHandles[handle].m_fList |= listId; + UpdateListMask( handle, m_aHandles[handle].m_fList | listId ); } //----------------------------------------------------------------------------- @@ -2616,7 +2905,7 @@ void CSpatialPartition::Remove( SpatialPartitionListMask_t listId, SpatialPartit { Assert( m_aHandles.IsValidIndex( handle ) ); Assert( listId <= USHRT_MAX ); - m_aHandles[handle].m_fList &= ~listId; + UpdateListMask( handle, m_aHandles[handle].m_fList & ~listId ); } //----------------------------------------------------------------------------- @@ -2628,8 +2917,9 @@ void CSpatialPartition::RemoveAndInsert( SpatialPartitionListMask_t removeMask, Assert( m_aHandles.IsValidIndex( handle ) ); Assert( removeMask <= USHRT_MAX ); Assert( insertMask <= USHRT_MAX ); - m_aHandles[handle].m_fList &= ~removeMask; - m_aHandles[handle].m_fList |= insertMask; + uint16 nOriginalListMask = m_aHandles[handle].m_fList; + uint16 nListMask = (nOriginalListMask & ~removeMask) | insertMask; + UpdateListMask( handle, nListMask ); } //----------------------------------------------------------------------------- @@ -2639,7 +2929,7 @@ void CSpatialPartition::RemoveAndInsert( SpatialPartitionListMask_t removeMask, void CSpatialPartition::Remove( SpatialPartitionHandle_t handle ) { Assert( m_aHandles.IsValidIndex( handle ) ); - m_aHandles[handle].m_fList = 0; + UpdateListMask( handle, 0 ); } //----------------------------------------------------------------------------- @@ -2656,6 +2946,7 @@ void CSpatialPartition::UnhideElement( SpatialPartitionHandle_t handle, SpatialT } + //----------------------------------------------------------------------------- // Purpose: Remove handle quickly saving the old list data, to be restored later // via the UnhideElement call. @@ -2787,19 +3078,19 @@ void CSpatialPartition::InsertIntoTree( SpatialPartitionHandle_t hPartition, con { if ( ( listMask & PARTITION_ALL_CLIENT_EDICTS ) && !( entityInfo.m_flags & IN_CLIENT_TREE ) ) { - m_VoxelTrees[CLIENT_TREE].InsertIntoTree( hPartition, mins, maxs ); + m_VoxelTrees[CLIENT_TREE].InsertIntoTree( hPartition, mins, maxs, false ); entityInfo.m_flags |= IN_CLIENT_TREE; } if ( ( listMask & ~PARTITION_ALL_CLIENT_EDICTS ) && !( entityInfo.m_flags & IN_SERVER_TREE ) ) { - m_VoxelTrees[SERVER_TREE].InsertIntoTree( hPartition, mins, maxs ); + m_VoxelTrees[SERVER_TREE].InsertIntoTree( hPartition, mins, maxs, false ); entityInfo.m_flags |= IN_SERVER_TREE; } } else if ( !( entityInfo.m_flags & IN_CLIENT_TREE ) ) { - m_VoxelTrees[CLIENT_TREE].InsertIntoTree( hPartition, mins, maxs ); + m_VoxelTrees[CLIENT_TREE].InsertIntoTree( hPartition, mins, maxs, false ); entityInfo.m_flags |= IN_CLIENT_TREE; } } @@ -2878,7 +3169,7 @@ void CVoxelTree::ReportStats( const char *pFileName ) void CSpatialPartition::ReportStats( const char *pFileName ) { - Msg( "Handle Count %d (%llu bytes)\n", m_aHandles.Count(), (uint64)( m_aHandles.Count() * ( sizeof(EntityInfo_t) + 2 * sizeof(SpatialPartitionHandle_t) ) ) ); + Msg( "Handle Count %d (%d bytes)\n", m_aHandles.Count(), m_aHandles.Count() * ( sizeof(EntityInfo_t) + 2 * sizeof(SpatialPartitionHandle_t) ) ); for ( int i = 0; i < NUM_TREES; i++ ) { m_VoxelTrees[i].ReportStats( pFileName ); @@ -2926,5 +3217,3 @@ void DestroySpatialPartition( ISpatialPartition *pPartition ) Assert( pPartition != (ISpatialPartition*)&g_SpatialPartition ); delete pPartition; } - - diff --git a/engine/sv_main.cpp b/engine/sv_main.cpp index 66fadb3c..1628c881 100644 --- a/engine/sv_main.cpp +++ b/engine/sv_main.cpp @@ -75,6 +75,7 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" +#include "tier0/memalloc.h" extern CNetworkStringTableContainer *networkStringTableContainerServer; extern CNetworkStringTableContainer *networkStringTableContainerClient; diff --git a/engine/sv_remoteaccess.cpp b/engine/sv_remoteaccess.cpp index 7d4f7a99..50839a55 100644 --- a/engine/sv_remoteaccess.cpp +++ b/engine/sv_remoteaccess.cpp @@ -284,53 +284,6 @@ void CServerRemoteAccess::WriteDataRequest( CRConServer *pNetworkListener, ra_li #endif } break; - -#ifdef VPROF_ENABLED - case SERVERDATA_VPROF: - { - char password[25]; - if ( !GetStringHelper( cmd, password, sizeof(password) ) ) - { - invalidRequest = true; - break; - } - if ( !GetStringHelper( cmd, password, sizeof(password) ) ) - { - invalidRequest = true; - break; - } - if ( IsAuthenticated(listener) ) - { - RegisterVProfDataListener( listener ); - LogCommand( listener, "Remote VProf started!\n" ); - RespondString( listener, requestID, "Remote VProf started!\n" ); - } - } - break; - - case SERVERDATA_REMOVE_VPROF: - { - char password[25]; - if ( !GetStringHelper( cmd, password, sizeof(password) ) ) - { - invalidRequest = true; - break; - } - if ( !GetStringHelper( cmd, password, sizeof(password) ) ) - { - invalidRequest = true; - break; - } - if ( IsAuthenticated(listener) ) - { - RemoveVProfDataListener( listener ); - LogCommand( listener, "Remote VProf finished!\n" ); - RespondString( listener, requestID, "Remote VProf finished!\n" ); - } - } - break; -#endif - default: Assert(!("Unknown requestType in CServerRemoteAccess::WriteDataRequest()")); cmd.Purge(); @@ -911,16 +864,6 @@ void CServerRemoteAccess::SendResponseToClient( ra_listener_id listenerID, Serve response.Put( pData, nDataLen ); } - -//----------------------------------------------------------------------------- -// Purpose: sends an opaque blob of data from VProf to a remote rcon listener -//----------------------------------------------------------------------------- -void CServerRemoteAccess::SendVProfData( ra_listener_id listenerID, bool bGroupData, void *data, int len ) -{ - Assert( listenerID != m_AdminUIID ); // only RCON clients support this right now - SendResponseToClient( listenerID, bGroupData ? SERVERDATA_VPROF_GROUPS : SERVERDATA_VPROF_DATA, data, len ); -} - //----------------------------------------------------------------------------- // Purpose: C function for rest of engine to access CServerRemoteAccess class //----------------------------------------------------------------------------- diff --git a/engine/sv_uploadgamestats.cpp b/engine/sv_uploadgamestats.cpp index 8665b061..f4836600 100644 --- a/engine/sv_uploadgamestats.cpp +++ b/engine/sv_uploadgamestats.cpp @@ -1099,7 +1099,7 @@ protected: }; public: - static unsigned CallbackThreadProc( void *pvParam ) { ((CAsyncUploaderThread*) pvParam)->ThreadProc(); return 0; } + static uintp CallbackThreadProc( void *pvParam ) { ((CAsyncUploaderThread*) pvParam)->ThreadProc(); return 0; } void QueueData( char const *szMapName, uint uiBlobVersion, uint uiBlobSize, const void *pvBlob ); void TerminateAndSelfDelete(); }; diff --git a/engine/sys_dll.cpp b/engine/sys_dll.cpp index a7795f44..2d8b30e2 100644 --- a/engine/sys_dll.cpp +++ b/engine/sys_dll.cpp @@ -797,7 +797,7 @@ void Sys_ShutdownAuthentication( void ) //----------------------------------------------------------------------------- // Debug library spew output //----------------------------------------------------------------------------- -CThreadLocalInt<> g_bInSpew; +CTHREADLOCALINT g_bInSpew; #include "tier1/fmtstr.h" diff --git a/engine/sys_dll2.cpp b/engine/sys_dll2.cpp index e6742211..6bcc2af8 100644 --- a/engine/sys_dll2.cpp +++ b/engine/sys_dll2.cpp @@ -100,6 +100,7 @@ // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" +#include "tier0/memalloc.h" //----------------------------------------------------------------------------- // Globals @@ -2260,7 +2261,7 @@ bool EnableLongTickWatcher() #ifdef POSIX (void*) #endif - LongTickWatcherThread, NULL, 0, (unsigned long int *)&nThreadID ); + LongTickWatcherThread, NULL, 0, (uintp *)&nThreadID ); bRet = true; } diff --git a/engine/sys_getmodes.cpp b/engine/sys_getmodes.cpp index 9e262439..1def8413 100644 --- a/engine/sys_getmodes.cpp +++ b/engine/sys_getmodes.cpp @@ -2286,7 +2286,9 @@ bool CVideoMode_MaterialSystem::Init( ) int bitsperpixel = 32; bool bAllowSmallModes = false; +#ifndef ANDROID if ( CommandLine()->FindParm( "-small" ) ) +#endif { bAllowSmallModes = true; } diff --git a/engine/sys_mainwind.cpp b/engine/sys_mainwind.cpp index ce46f8c8..21cb9487 100644 --- a/engine/sys_mainwind.cpp +++ b/engine/sys_mainwind.cpp @@ -355,7 +355,7 @@ void CGame::HandleMsg_Close( const InputEvent_t &event ) void CGame::DispatchInputEvent( const InputEvent_t &event ) { - switch( event.m_nType ) + switch( event.m_nType & 0xFFFF ) { // Handle button events specially, // since we have all manner of crazy filtering going on when dealing with them @@ -1566,7 +1566,7 @@ void *CGame::GetMainWindowPlatformSpecificHandle( void ) #ifdef OSX id nsWindow = (id)pInfo.info.cocoa.window; SEL selector = sel_registerName("windowRef"); - id windowRef = objc_msgSend( nsWindow, selector ); + id windowRef = ((id(*)(id, SEL))objc_msgSend)( nsWindow, selector ); return windowRef; #else // Not used on Linux. diff --git a/engine/tmessage.cpp b/engine/tmessage.cpp index a31ce050..72c65f22 100644 --- a/engine/tmessage.cpp +++ b/engine/tmessage.cpp @@ -192,7 +192,7 @@ int ParseString( char const *pText, char *buf, size_t bufsize ) char const *pStart = pTemp; pTemp = SkipText( pTemp ); - int len = min( pTemp - pStart + 1, (int)bufsize - 1 ); + intp len = min( pTemp - pStart + 1, (ptrdiff_t)bufsize - 1 ); Q_strncpy( buf, pStart, len ); buf[ len ] = 0; return 1; @@ -367,7 +367,8 @@ void TextMessageParse( byte *pMemFile, int fileSize ) client_textmessage_t textMessages[ MAX_MESSAGES ]; - int i, nameHeapSize, textHeapSize, messageSize, nameOffset; + int i, nameHeapSize, textHeapSize, messageSize; + intp nameOffset; lastNamePos = 0; lineNumber = 0; @@ -633,4 +634,4 @@ client_textmessage_t *TextMessageGet( const char *pName ) } return NULL; -} \ No newline at end of file +} diff --git a/engine/vengineserver_impl.cpp b/engine/vengineserver_impl.cpp index c10bc806..37dc07c6 100644 --- a/engine/vengineserver_impl.cpp +++ b/engine/vengineserver_impl.cpp @@ -48,6 +48,7 @@ #include "replay_internal.h" #include "replayserver.h" #include "replay/iserverengine.h" +#include "vcrmode.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" diff --git a/engine/vgui_baseui_interface.cpp b/engine/vgui_baseui_interface.cpp index 8d5f6f1d..2f29683c 100644 --- a/engine/vgui_baseui_interface.cpp +++ b/engine/vgui_baseui_interface.cpp @@ -696,10 +696,9 @@ void CEngineVGui::Init() COM_TimestampedLog( "Building Panels (staticGameUIPanel)" ); staticGameUIPanel = new CEnginePanel( staticPanel, "GameUI Panel" ); - if (IsAndroid() || CommandLine()->CheckParm("-gameuiproportionality")) - { + + if(NeedProportional()) staticGameUIPanel->SetProportional(true); - } staticGameUIPanel->SetBounds( 0, 0, videomode->GetModeUIWidth(), videomode->GetModeUIHeight() ); staticGameUIPanel->SetPaintBorderEnabled(false); diff --git a/engine/view.cpp b/engine/view.cpp index 7e7cf61b..04772894 100644 --- a/engine/view.cpp +++ b/engine/view.cpp @@ -523,7 +523,7 @@ public: int m_nLeafWaterDataID; }; - bool EnumerateLeaf( int leaf, int context ) + bool EnumerateLeaf( int leaf, intp context ) { BoxIntersectWaterContext_t *pSearchContext = ( BoxIntersectWaterContext_t * )context; mleaf_t *pLeaf = &host_state.worldmodel->brush.pShared->leafs[leaf]; @@ -541,7 +541,7 @@ public: BoxIntersectWaterContext_t context; context.m_bFoundWaterLeaf = false; context.m_nLeafWaterDataID = leafWaterDataID; - g_pToolBSPTree->EnumerateLeavesInBox( mins, maxs, this, ( int )&context ); + g_pToolBSPTree->EnumerateLeavesInBox( mins, maxs, this, ( intp )&context ); return context.m_bFoundWaterLeaf; } diff --git a/engine/voice_codecs/celt/opus/opus.h b/engine/voice_codecs/celt/opus/opus.h new file mode 100644 index 00000000..d282f21d --- /dev/null +++ b/engine/voice_codecs/celt/opus/opus.h @@ -0,0 +1,981 @@ +/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited + Written by Jean-Marc Valin and Koen Vos */ +/* + 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. +*/ + +/** + * @file opus.h + * @brief Opus reference implementation API + */ + +#ifndef OPUS_H +#define OPUS_H + +#include "opus_types.h" +#include "opus_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @mainpage Opus + * + * The Opus codec is designed for interactive speech and audio transmission over the Internet. + * It is designed by the IETF Codec Working Group and incorporates technology from + * Skype's SILK codec and Xiph.Org's CELT codec. + * + * The Opus codec is designed to handle a wide range of interactive audio applications, + * including Voice over IP, videoconferencing, in-game chat, and even remote live music + * performances. It can scale from low bit-rate narrowband speech to very high quality + * stereo music. Its main features are: + + * @li Sampling rates from 8 to 48 kHz + * @li Bit-rates from 6 kb/s to 510 kb/s + * @li Support for both constant bit-rate (CBR) and variable bit-rate (VBR) + * @li Audio bandwidth from narrowband to full-band + * @li Support for speech and music + * @li Support for mono and stereo + * @li Support for multichannel (up to 255 channels) + * @li Frame sizes from 2.5 ms to 60 ms + * @li Good loss robustness and packet loss concealment (PLC) + * @li Floating point and fixed-point implementation + * + * Documentation sections: + * @li @ref opus_encoder + * @li @ref opus_decoder + * @li @ref opus_repacketizer + * @li @ref opus_multistream + * @li @ref opus_libinfo + * @li @ref opus_custom + */ + +/** @defgroup opus_encoder Opus Encoder + * @{ + * + * @brief This page describes the process and functions used to encode Opus. + * + * Since Opus is a stateful codec, the encoding process starts with creating an encoder + * state. This can be done with: + * + * @code + * int error; + * OpusEncoder *enc; + * enc = opus_encoder_create(Fs, channels, application, &error); + * @endcode + * + * From this point, @c enc can be used for encoding an audio stream. An encoder state + * @b must @b not be used for more than one stream at the same time. Similarly, the encoder + * state @b must @b not be re-initialized for each frame. + * + * While opus_encoder_create() allocates memory for the state, it's also possible + * to initialize pre-allocated memory: + * + * @code + * int size; + * int error; + * OpusEncoder *enc; + * size = opus_encoder_get_size(channels); + * enc = malloc(size); + * error = opus_encoder_init(enc, Fs, channels, application); + * @endcode + * + * where opus_encoder_get_size() returns the required size for the encoder state. Note that + * future versions of this code may change the size, so no assuptions should be made about it. + * + * The encoder state is always continuous in memory and only a shallow copy is sufficient + * to copy it (e.g. memcpy()) + * + * It is possible to change some of the encoder's settings using the opus_encoder_ctl() + * interface. All these settings already default to the recommended value, so they should + * only be changed when necessary. The most common settings one may want to change are: + * + * @code + * opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate)); + * opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity)); + * opus_encoder_ctl(enc, OPUS_SET_SIGNAL(signal_type)); + * @endcode + * + * where + * + * @arg bitrate is in bits per second (b/s) + * @arg complexity is a value from 1 to 10, where 1 is the lowest complexity and 10 is the highest + * @arg signal_type is either OPUS_AUTO (default), OPUS_SIGNAL_VOICE, or OPUS_SIGNAL_MUSIC + * + * See @ref opus_encoderctls and @ref opus_genericctls for a complete list of parameters that can be set or queried. Most parameters can be set or changed at any time during a stream. + * + * To encode a frame, opus_encode() or opus_encode_float() must be called with exactly one frame (2.5, 5, 10, 20, 40 or 60 ms) of audio data: + * @code + * len = opus_encode(enc, audio_frame, frame_size, packet, max_packet); + * @endcode + * + * where + *
    + *
  • audio_frame is the audio data in opus_int16 (or float for opus_encode_float())
  • + *
  • frame_size is the duration of the frame in samples (per channel)
  • + *
  • packet is the byte array to which the compressed data is written
  • + *
  • max_packet is the maximum number of bytes that can be written in the packet (4000 bytes is recommended). + * Do not use max_packet to control VBR target bitrate, instead use the #OPUS_SET_BITRATE CTL.
  • + *
+ * + * opus_encode() and opus_encode_float() return the number of bytes actually written to the packet. + * The return value can be negative, which indicates that an error has occurred. If the return value + * is 2 bytes or less, then the packet does not need to be transmitted (DTX). + * + * Once the encoder state if no longer needed, it can be destroyed with + * + * @code + * opus_encoder_destroy(enc); + * @endcode + * + * If the encoder was created with opus_encoder_init() rather than opus_encoder_create(), + * then no action is required aside from potentially freeing the memory that was manually + * allocated for it (calling free(enc) for the example above) + * + */ + +/** Opus encoder state. + * This contains the complete state of an Opus encoder. + * It is position independent and can be freely copied. + * @see opus_encoder_create,opus_encoder_init + */ +typedef struct OpusEncoder OpusEncoder; + +/** Gets the size of an OpusEncoder structure. + * @param[in] channels int: Number of channels. + * This must be 1 or 2. + * @returns The size in bytes. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_encoder_get_size(int channels); + +/** + */ + +/** Allocates and initializes an encoder state. + * There are three coding modes: + * + * @ref OPUS_APPLICATION_VOIP gives best quality at a given bitrate for voice + * signals. It enhances the input signal by high-pass filtering and + * emphasizing formants and harmonics. Optionally it includes in-band + * forward error correction to protect against packet loss. Use this + * mode for typical VoIP applications. Because of the enhancement, + * even at high bitrates the output may sound different from the input. + * + * @ref OPUS_APPLICATION_AUDIO gives best quality at a given bitrate for most + * non-voice signals like music. Use this mode for music and mixed + * (music/voice) content, broadcast, and applications requiring less + * than 15 ms of coding delay. + * + * @ref OPUS_APPLICATION_RESTRICTED_LOWDELAY configures low-delay mode that + * disables the speech-optimized mode in exchange for slightly reduced delay. + * This mode can only be set on an newly initialized or freshly reset encoder + * because it changes the codec delay. + * + * This is useful when the caller knows that the speech-optimized modes will not be needed (use with caution). + * @param [in] Fs opus_int32: Sampling rate of input signal (Hz) + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param [in] channels int: Number of channels (1 or 2) in input signal + * @param [in] application int: Coding mode (@ref OPUS_APPLICATION_VOIP/@ref OPUS_APPLICATION_AUDIO/@ref OPUS_APPLICATION_RESTRICTED_LOWDELAY) + * @param [out] error int*: @ref opus_errorcodes + * @note Regardless of the sampling rate and number channels selected, the Opus encoder + * can switch to a lower audio bandwidth or number of channels if the bitrate + * selected is too low. This also means that it is safe to always use 48 kHz stereo input + * and let the encoder optimize the encoding. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusEncoder *opus_encoder_create( + opus_int32 Fs, + int channels, + int application, + int *error +); + +/** Initializes a previously allocated encoder state + * The memory pointed to by st must be at least the size returned by opus_encoder_get_size(). + * This is intended for applications which use their own allocator instead of malloc. + * @see opus_encoder_create(),opus_encoder_get_size() + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. + * @param [in] st OpusEncoder*: Encoder state + * @param [in] Fs opus_int32: Sampling rate of input signal (Hz) + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param [in] channels int: Number of channels (1 or 2) in input signal + * @param [in] application int: Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO/OPUS_APPLICATION_RESTRICTED_LOWDELAY) + * @retval #OPUS_OK Success or @ref opus_errorcodes + */ +OPUS_EXPORT int opus_encoder_init( + OpusEncoder *st, + opus_int32 Fs, + int channels, + int application +) OPUS_ARG_NONNULL(1); + +/** Encodes an Opus frame. + * @param [in] st OpusEncoder*: Encoder state + * @param [in] pcm opus_int16*: Input signal (interleaved if 2 channels). length is frame_size*channels*sizeof(opus_int16) + * @param [in] frame_size int: Number of samples per channel in the + * input signal. + * This must be an Opus frame size for + * the encoder's sampling rate. + * For example, at 48 kHz the permitted + * values are 120, 240, 480, 960, 1920, + * and 2880. + * Passing in a duration of less than + * 10 ms (480 samples at 48 kHz) will + * prevent the encoder from using the LPC + * or hybrid modes. + * @param [out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode( + OpusEncoder *st, + const opus_int16 *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Encodes an Opus frame from floating point input. + * @param [in] st OpusEncoder*: Encoder state + * @param [in] pcm float*: Input in float format (interleaved if 2 channels), with a normal range of +/-1.0. + * Samples with a range beyond +/-1.0 are supported but will + * be clipped by decoders using the integer API and should + * only be used if it is known that the far end supports + * extended dynamic range. + * length is frame_size*channels*sizeof(float) + * @param [in] frame_size int: Number of samples per channel in the + * input signal. + * This must be an Opus frame size for + * the encoder's sampling rate. + * For example, at 48 kHz the permitted + * values are 120, 240, 480, 960, 1920, + * and 2880. + * Passing in a duration of less than + * 10 ms (480 samples at 48 kHz) will + * prevent the encoder from using the LPC + * or hybrid modes. + * @param [out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode_float( + OpusEncoder *st, + const float *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Frees an OpusEncoder allocated by opus_encoder_create(). + * @param[in] st OpusEncoder*: State to be freed. + */ +OPUS_EXPORT void opus_encoder_destroy(OpusEncoder *st); + +/** Perform a CTL function on an Opus encoder. + * + * Generally the request and subsequent arguments are generated + * by a convenience macro. + * @param st OpusEncoder*: Encoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls or + * @ref opus_encoderctls. + * @see opus_genericctls + * @see opus_encoderctls + */ +OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...) OPUS_ARG_NONNULL(1); +/**@}*/ + +/** @defgroup opus_decoder Opus Decoder + * @{ + * + * @brief This page describes the process and functions used to decode Opus. + * + * The decoding process also starts with creating a decoder + * state. This can be done with: + * @code + * int error; + * OpusDecoder *dec; + * dec = opus_decoder_create(Fs, channels, &error); + * @endcode + * where + * @li Fs is the sampling rate and must be 8000, 12000, 16000, 24000, or 48000 + * @li channels is the number of channels (1 or 2) + * @li error will hold the error code in case of failure (or #OPUS_OK on success) + * @li the return value is a newly created decoder state to be used for decoding + * + * While opus_decoder_create() allocates memory for the state, it's also possible + * to initialize pre-allocated memory: + * @code + * int size; + * int error; + * OpusDecoder *dec; + * size = opus_decoder_get_size(channels); + * dec = malloc(size); + * error = opus_decoder_init(dec, Fs, channels); + * @endcode + * where opus_decoder_get_size() returns the required size for the decoder state. Note that + * future versions of this code may change the size, so no assuptions should be made about it. + * + * The decoder state is always continuous in memory and only a shallow copy is sufficient + * to copy it (e.g. memcpy()) + * + * To decode a frame, opus_decode() or opus_decode_float() must be called with a packet of compressed audio data: + * @code + * frame_size = opus_decode(dec, packet, len, decoded, max_size, 0); + * @endcode + * where + * + * @li packet is the byte array containing the compressed data + * @li len is the exact number of bytes contained in the packet + * @li decoded is the decoded audio data in opus_int16 (or float for opus_decode_float()) + * @li max_size is the max duration of the frame in samples (per channel) that can fit into the decoded_frame array + * + * opus_decode() and opus_decode_float() return the number of samples (per channel) decoded from the packet. + * If that value is negative, then an error has occurred. This can occur if the packet is corrupted or if the audio + * buffer is too small to hold the decoded audio. + * + * Opus is a stateful codec with overlapping blocks and as a result Opus + * packets are not coded independently of each other. Packets must be + * passed into the decoder serially and in the correct order for a correct + * decode. Lost packets can be replaced with loss concealment by calling + * the decoder with a null pointer and zero length for the missing packet. + * + * A single codec state may only be accessed from a single thread at + * a time and any required locking must be performed by the caller. Separate + * streams must be decoded with separate decoder states and can be decoded + * in parallel unless the library was compiled with NONTHREADSAFE_PSEUDOSTACK + * defined. + * + */ + +/** Opus decoder state. + * This contains the complete state of an Opus decoder. + * It is position independent and can be freely copied. + * @see opus_decoder_create,opus_decoder_init + */ +typedef struct OpusDecoder OpusDecoder; + +/** Gets the size of an OpusDecoder structure. + * @param [in] channels int: Number of channels. + * This must be 1 or 2. + * @returns The size in bytes. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_size(int channels); + +/** Allocates and initializes a decoder state. + * @param [in] Fs opus_int32: Sample rate to decode at (Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param [in] channels int: Number of channels (1 or 2) to decode + * @param [out] error int*: #OPUS_OK Success or @ref opus_errorcodes + * + * Internally Opus stores data at 48000 Hz, so that should be the default + * value for Fs. However, the decoder can efficiently decode to buffers + * at 8, 12, 16, and 24 kHz so if for some reason the caller cannot use + * data at the full sample rate, or knows the compressed data doesn't + * use the full frequency range, it can request decoding at a reduced + * rate. Likewise, the decoder is capable of filling in either mono or + * interleaved stereo pcm buffers, at the caller's request. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusDecoder *opus_decoder_create( + opus_int32 Fs, + int channels, + int *error +); + +/** Initializes a previously allocated decoder state. + * The state must be at least the size returned by opus_decoder_get_size(). + * This is intended for applications which use their own allocator instead of malloc. @see opus_decoder_create,opus_decoder_get_size + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. + * @param [in] st OpusDecoder*: Decoder state. + * @param [in] Fs opus_int32: Sampling rate to decode to (Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param [in] channels int: Number of channels (1 or 2) to decode + * @retval #OPUS_OK Success or @ref opus_errorcodes + */ +OPUS_EXPORT int opus_decoder_init( + OpusDecoder *st, + opus_int32 Fs, + int channels +) OPUS_ARG_NONNULL(1); + +/** Decode an Opus packet. + * @param [in] st OpusDecoder*: Decoder state + * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss + * @param [in] len opus_int32: Number of bytes in payload* + * @param [out] pcm opus_int16*: Output signal (interleaved if 2 channels). length + * is frame_size*channels*sizeof(opus_int16) + * @param [in] frame_size Number of samples per channel of available space in \a pcm. + * If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will + * not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1), + * then frame_size needs to be exactly the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the next incoming packet. For the PLC and + * FEC cases, frame_size must be a multiple of 2.5 ms. + * @param [in] decode_fec int: Flag (0 or 1) to request that any in-band forward error correction data be + * decoded. If no such data is available, the frame is decoded as if it were lost. + * @returns Number of decoded samples or @ref opus_errorcodes + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode( + OpusDecoder *st, + const unsigned char *data, + opus_int32 len, + opus_int16 *pcm, + int frame_size, + int decode_fec +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Decode an Opus packet with floating point output. + * @param [in] st OpusDecoder*: Decoder state + * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss + * @param [in] len opus_int32: Number of bytes in payload + * @param [out] pcm float*: Output signal (interleaved if 2 channels). length + * is frame_size*channels*sizeof(float) + * @param [in] frame_size Number of samples per channel of available space in \a pcm. + * If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will + * not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1), + * then frame_size needs to be exactly the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the next incoming packet. For the PLC and + * FEC cases, frame_size must be a multiple of 2.5 ms. + * @param [in] decode_fec int: Flag (0 or 1) to request that any in-band forward error correction data be + * decoded. If no such data is available the frame is decoded as if it were lost. + * @returns Number of decoded samples or @ref opus_errorcodes + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode_float( + OpusDecoder *st, + const unsigned char *data, + opus_int32 len, + float *pcm, + int frame_size, + int decode_fec +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Perform a CTL function on an Opus decoder. + * + * Generally the request and subsequent arguments are generated + * by a convenience macro. + * @param st OpusDecoder*: Decoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls or + * @ref opus_decoderctls. + * @see opus_genericctls + * @see opus_decoderctls + */ +OPUS_EXPORT int opus_decoder_ctl(OpusDecoder *st, int request, ...) OPUS_ARG_NONNULL(1); + +/** Frees an OpusDecoder allocated by opus_decoder_create(). + * @param[in] st OpusDecoder*: State to be freed. + */ +OPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st); + +/** Parse an opus packet into one or more frames. + * Opus_decode will perform this operation internally so most applications do + * not need to use this function. + * This function does not copy the frames, the returned pointers are pointers into + * the input packet. + * @param [in] data char*: Opus packet to be parsed + * @param [in] len opus_int32: size of data + * @param [out] out_toc char*: TOC pointer + * @param [out] frames char*[48] encapsulated frames + * @param [out] size opus_int16[48] sizes of the encapsulated frames + * @param [out] payload_offset int*: returns the position of the payload within the packet (in bytes) + * @returns number of frames + */ +OPUS_EXPORT int opus_packet_parse( + const unsigned char *data, + opus_int32 len, + unsigned char *out_toc, + const unsigned char *frames[48], + opus_int16 size[48], + int *payload_offset +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(5); + +/** Gets the bandwidth of an Opus packet. + * @param [in] data char*: Opus packet + * @retval OPUS_BANDWIDTH_NARROWBAND Narrowband (4kHz bandpass) + * @retval OPUS_BANDWIDTH_MEDIUMBAND Mediumband (6kHz bandpass) + * @retval OPUS_BANDWIDTH_WIDEBAND Wideband (8kHz bandpass) + * @retval OPUS_BANDWIDTH_SUPERWIDEBAND Superwideband (12kHz bandpass) + * @retval OPUS_BANDWIDTH_FULLBAND Fullband (20kHz bandpass) + * @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_bandwidth(const unsigned char *data) OPUS_ARG_NONNULL(1); + +/** Gets the number of samples per frame from an Opus packet. + * @param [in] data char*: Opus packet. + * This must contain at least one byte of + * data. + * @param [in] Fs opus_int32: Sampling rate in Hz. + * This must be a multiple of 400, or + * inaccurate results will be returned. + * @returns Number of samples per frame. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_samples_per_frame(const unsigned char *data, opus_int32 Fs) OPUS_ARG_NONNULL(1); + +/** Gets the number of channels from an Opus packet. + * @param [in] data char*: Opus packet + * @returns Number of channels + * @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_channels(const unsigned char *data) OPUS_ARG_NONNULL(1); + +/** Gets the number of frames in an Opus packet. + * @param [in] packet char*: Opus packet + * @param [in] len opus_int32: Length of packet + * @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 + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1); + +/** Gets the number of samples of an Opus packet. + * @param [in] packet char*: Opus packet + * @param [in] len opus_int32: Length of packet + * @param [in] Fs opus_int32: Sampling rate in Hz. + * This must be a multiple of 400, or + * inaccurate results will be returned. + * @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 + */ +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); + +/** Gets the number of samples of an Opus packet. + * @param [in] dec OpusDecoder*: Decoder state + * @param [in] packet char*: Opus packet + * @param [in] len opus_int32: Length of packet + * @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 + */ +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 float*: Input PCM and modified PCM + * @param [in] frame_size int Number of samples per channel to process + * @param [in] channels int: Number of channels + * @param [in,out] softclip_mem float*: 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 + * @{ + * + * The repacketizer can be used to merge multiple Opus packets into a single + * packet or alternatively to split Opus packets that have previously been + * merged. Splitting valid Opus packets is always guaranteed to succeed, + * whereas merging valid packets only succeeds if all frames have the same + * mode, bandwidth, and frame size, and when the total duration of the merged + * packet is no more than 120 ms. The 120 ms limit comes from the + * specification and limits decoder memory requirements at a point where + * framing overhead becomes negligible. + * + * The repacketizer currently only operates on elementary Opus + * streams. It will not manipualte multistream packets successfully, except in + * the degenerate case where they consist of data from a single stream. + * + * The repacketizing process starts with creating a repacketizer state, either + * by calling opus_repacketizer_create() or by allocating the memory yourself, + * e.g., + * @code + * OpusRepacketizer *rp; + * rp = (OpusRepacketizer*)malloc(opus_repacketizer_get_size()); + * if (rp != NULL) + * opus_repacketizer_init(rp); + * @endcode + * + * Then the application should submit packets with opus_repacketizer_cat(), + * extract new packets with opus_repacketizer_out() or + * opus_repacketizer_out_range(), and then reset the state for the next set of + * input packets via opus_repacketizer_init(). + * + * For example, to split a sequence of packets into individual frames: + * @code + * unsigned char *data; + * int len; + * while (get_next_packet(&data, &len)) + * { + * unsigned char out[1276]; + * opus_int32 out_len; + * int nb_frames; + * int err; + * int i; + * err = opus_repacketizer_cat(rp, data, len); + * if (err != OPUS_OK) + * { + * release_packet(data); + * return err; + * } + * nb_frames = opus_repacketizer_get_nb_frames(rp); + * for (i = 0; i < nb_frames; i++) + * { + * out_len = opus_repacketizer_out_range(rp, i, i+1, out, sizeof(out)); + * if (out_len < 0) + * { + * release_packet(data); + * return (int)out_len; + * } + * output_next_packet(out, out_len); + * } + * opus_repacketizer_init(rp); + * release_packet(data); + * } + * @endcode + * + * Alternatively, to combine a sequence of frames into packets that each + * contain up to TARGET_DURATION_MS milliseconds of data: + * @code + * // The maximum number of packets with duration TARGET_DURATION_MS occurs + * // when the frame size is 2.5 ms, for a total of (TARGET_DURATION_MS*2/5) + * // packets. + * unsigned char *data[(TARGET_DURATION_MS*2/5)+1]; + * opus_int32 len[(TARGET_DURATION_MS*2/5)+1]; + * int nb_packets; + * unsigned char out[1277*(TARGET_DURATION_MS*2/2)]; + * opus_int32 out_len; + * int prev_toc; + * nb_packets = 0; + * while (get_next_packet(data+nb_packets, len+nb_packets)) + * { + * int nb_frames; + * int err; + * nb_frames = opus_packet_get_nb_frames(data[nb_packets], len[nb_packets]); + * if (nb_frames < 1) + * { + * release_packets(data, nb_packets+1); + * return nb_frames; + * } + * nb_frames += opus_repacketizer_get_nb_frames(rp); + * // If adding the next packet would exceed our target, or it has an + * // incompatible TOC sequence, output the packets we already have before + * // submitting it. + * // N.B., The nb_packets > 0 check ensures we've submitted at least one + * // packet since the last call to opus_repacketizer_init(). Otherwise a + * // single packet longer than TARGET_DURATION_MS would cause us to try to + * // output an (invalid) empty packet. It also ensures that prev_toc has + * // been set to a valid value. Additionally, len[nb_packets] > 0 is + * // guaranteed by the call to opus_packet_get_nb_frames() above, so the + * // reference to data[nb_packets][0] should be valid. + * if (nb_packets > 0 && ( + * ((prev_toc & 0xFC) != (data[nb_packets][0] & 0xFC)) || + * opus_packet_get_samples_per_frame(data[nb_packets], 48000)*nb_frames > + * TARGET_DURATION_MS*48)) + * { + * out_len = opus_repacketizer_out(rp, out, sizeof(out)); + * if (out_len < 0) + * { + * release_packets(data, nb_packets+1); + * return (int)out_len; + * } + * output_next_packet(out, out_len); + * opus_repacketizer_init(rp); + * release_packets(data, nb_packets); + * data[0] = data[nb_packets]; + * len[0] = len[nb_packets]; + * nb_packets = 0; + * } + * err = opus_repacketizer_cat(rp, data[nb_packets], len[nb_packets]); + * if (err != OPUS_OK) + * { + * release_packets(data, nb_packets+1); + * return err; + * } + * prev_toc = data[nb_packets][0]; + * nb_packets++; + * } + * // Output the final, partial packet. + * if (nb_packets > 0) + * { + * out_len = opus_repacketizer_out(rp, out, sizeof(out)); + * release_packets(data, nb_packets); + * if (out_len < 0) + * return (int)out_len; + * output_next_packet(out, out_len); + * } + * @endcode + * + * An alternate way of merging packets is to simply call opus_repacketizer_cat() + * unconditionally until it fails. At that point, the merged packet can be + * obtained with opus_repacketizer_out() and the input packet for which + * opus_repacketizer_cat() needs to be re-added to a newly reinitialized + * repacketizer state. + */ + +typedef struct OpusRepacketizer OpusRepacketizer; + +/** Gets the size of an OpusRepacketizer structure. + * @returns The size in bytes. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_size(void); + +/** (Re)initializes a previously allocated repacketizer state. + * The state must be at least the size returned by opus_repacketizer_get_size(). + * This can be used for applications which use their own allocator instead of + * malloc(). + * It must also be called to reset the queue of packets waiting to be + * repacketized, which is necessary if the maximum packet duration of 120 ms + * is reached or if you wish to submit packets with a different Opus + * configuration (coding mode, audio bandwidth, frame size, or channel count). + * Failure to do so will prevent a new packet from being added with + * opus_repacketizer_cat(). + * @see opus_repacketizer_create + * @see opus_repacketizer_get_size + * @see opus_repacketizer_cat + * @param rp OpusRepacketizer*: The repacketizer state to + * (re)initialize. + * @returns A pointer to the same repacketizer state that was passed in. + */ +OPUS_EXPORT OpusRepacketizer *opus_repacketizer_init(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1); + +/** Allocates memory and initializes the new repacketizer with + * opus_repacketizer_init(). + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusRepacketizer *opus_repacketizer_create(void); + +/** Frees an OpusRepacketizer allocated by + * opus_repacketizer_create(). + * @param[in] rp OpusRepacketizer*: State to be freed. + */ +OPUS_EXPORT void opus_repacketizer_destroy(OpusRepacketizer *rp); + +/** Add a packet to the current repacketizer state. + * This packet must match the configuration of any packets already submitted + * for repacketization since the last call to opus_repacketizer_init(). + * This means that it must have the same coding mode, audio bandwidth, frame + * size, and channel count. + * This can be checked in advance by examining the top 6 bits of the first + * byte of the packet, and ensuring they match the top 6 bits of the first + * byte of any previously submitted packet. + * The total duration of audio in the repacketizer state also must not exceed + * 120 ms, the maximum duration of a single packet, after adding this packet. + * + * The contents of the current repacketizer state can be extracted into new + * packets using opus_repacketizer_out() or opus_repacketizer_out_range(). + * + * In order to add a packet with a different configuration or to add more + * audio beyond 120 ms, you must clear the repacketizer state by calling + * opus_repacketizer_init(). + * If a packet is too large to add to the current repacketizer state, no part + * of it is added, even if it contains multiple frames, some of which might + * fit. + * If you wish to be able to add parts of such packets, you should first use + * another repacketizer to split the packet into pieces and add them + * individually. + * @see opus_repacketizer_out_range + * @see opus_repacketizer_out + * @see opus_repacketizer_init + * @param rp OpusRepacketizer*: The repacketizer state to which to + * add the packet. + * @param[in] data const unsigned char*: The packet data. + * The application must ensure + * this pointer remains valid + * until the next call to + * opus_repacketizer_init() or + * opus_repacketizer_destroy(). + * @param len opus_int32: The number of bytes in the packet data. + * @returns An error code indicating whether or not the operation succeeded. + * @retval #OPUS_OK The packet's contents have been added to the repacketizer + * state. + * @retval #OPUS_INVALID_PACKET The packet did not have a valid TOC sequence, + * the packet's TOC sequence was not compatible + * with previously submitted packets (because + * the coding mode, audio bandwidth, frame size, + * or channel count did not match), or adding + * this packet would increase the total amount of + * audio stored in the repacketizer state to more + * than 120 ms. + */ +OPUS_EXPORT int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); + + +/** Construct a new packet from data previously submitted to the repacketizer + * state via opus_repacketizer_cat(). + * @param rp OpusRepacketizer*: The repacketizer state from which to + * construct the new packet. + * @param begin int: The index of the first frame in the current + * repacketizer state to include in the output. + * @param end int: One past the index of the last frame in the + * current repacketizer state to include in the + * output. + * @param[out] data const unsigned char*: The buffer in which to + * store the output packet. + * @param maxlen opus_int32: The maximum number of bytes to store in + * the output buffer. In order to guarantee + * success, this should be at least + * 1276 for a single frame, + * or for multiple frames, + * 1277*(end-begin). + * However, 1*(end-begin) plus + * the size of all packet data submitted to + * the repacketizer since the last call to + * opus_repacketizer_init() or + * opus_repacketizer_create() is also + * sufficient, and possibly much smaller. + * @returns The total size of the output packet on success, or an error code + * on failure. + * @retval #OPUS_BAD_ARG [begin,end) was an invalid range of + * frames (begin < 0, begin >= end, or end > + * opus_repacketizer_get_nb_frames()). + * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the + * complete output packet. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Return the total number of frames contained in packet data submitted to + * the repacketizer state so far via opus_repacketizer_cat() since the last + * call to opus_repacketizer_init() or opus_repacketizer_create(). + * This defines the valid range of packets that can be extracted with + * opus_repacketizer_out_range() or opus_repacketizer_out(). + * @param rp OpusRepacketizer*: The repacketizer state containing the + * frames. + * @returns The total number of frames contained in the packet data submitted + * to the repacketizer state. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1); + +/** Construct a new packet from data previously submitted to the repacketizer + * state via opus_repacketizer_cat(). + * This is a convenience routine that returns all the data submitted so far + * in a single packet. + * It is equivalent to calling + * @code + * opus_repacketizer_out_range(rp, 0, opus_repacketizer_get_nb_frames(rp), + * data, maxlen) + * @endcode + * @param rp OpusRepacketizer*: The repacketizer state from which to + * construct the new packet. + * @param[out] data const unsigned char*: The buffer in which to + * store the output packet. + * @param maxlen opus_int32: The maximum number of bytes to store in + * the output buffer. In order to guarantee + * success, this should be at least + * 1277*opus_repacketizer_get_nb_frames(rp). + * However, + * 1*opus_repacketizer_get_nb_frames(rp) + * plus the size of all packet data + * submitted to the repacketizer since the + * last call to opus_repacketizer_init() or + * opus_repacketizer_create() is also + * sufficient, and possibly much smaller. + * @returns The total size of the output packet on success, or an error code + * on failure. + * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the + * complete output packet. + */ +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 const unsigned char*: The buffer containing the + * packet to pad. + * @param len opus_int32: The size of the packet. + * This must be at least 1. + * @param new_len opus_int32: 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 const unsigned char*: The buffer containing the + * packet to strip. + * @param len opus_int32: 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 const unsigned char*: The buffer containing the + * packet to pad. + * @param len opus_int32: The size of the packet. + * This must be at least 1. + * @param new_len opus_int32: The desired size of the packet after padding. + * This must be at least 1. + * @param nb_streams opus_int32: 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 const unsigned char*: The buffer containing the + * packet to strip. + * @param len opus_int32: The size of the packet. + * This must be at least 1. + * @param nb_streams opus_int32: 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 +} +#endif + +#endif /* OPUS_H */ diff --git a/engine/voice_codecs/celt/opus/opus_custom.h b/engine/voice_codecs/celt/opus/opus_custom.h new file mode 100644 index 00000000..41f36bf2 --- /dev/null +++ b/engine/voice_codecs/celt/opus/opus_custom.h @@ -0,0 +1,342 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Copyright (c) 2008-2012 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. +*/ + +/** + @file opus_custom.h + @brief Opus-Custom reference implementation API + */ + +#ifndef OPUS_CUSTOM_H +#define OPUS_CUSTOM_H + +#include "opus_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef CUSTOM_MODES +# define OPUS_CUSTOM_EXPORT OPUS_EXPORT +# define OPUS_CUSTOM_EXPORT_STATIC OPUS_EXPORT +#else +# define OPUS_CUSTOM_EXPORT +# ifdef OPUS_BUILD +# define OPUS_CUSTOM_EXPORT_STATIC static OPUS_INLINE +# else +# define OPUS_CUSTOM_EXPORT_STATIC +# endif +#endif + +/** @defgroup opus_custom Opus Custom + * @{ + * Opus Custom is an optional part of the Opus specification and + * reference implementation which uses a distinct API from the regular + * API and supports frame sizes that are not normally supported.\ Use + * of Opus Custom is discouraged for all but very special applications + * for which a frame size different from 2.5, 5, 10, or 20 ms is needed + * (for either complexity or latency reasons) and where interoperability + * is less important. + * + * In addition to the interoperability limitations the use of Opus custom + * disables a substantial chunk of the codec and generally lowers the + * quality available at a given bitrate. Normally when an application needs + * a different frame size from the codec it should buffer to match the + * sizes but this adds a small amount of delay which may be important + * in some very low latency applications. Some transports (especially + * constant rate RF transports) may also work best with frames of + * particular durations. + * + * Libopus only supports custom modes if they are enabled at compile time. + * + * The Opus Custom API is similar to the regular API but the + * @ref opus_encoder_create and @ref opus_decoder_create calls take + * an additional mode parameter which is a structure produced by + * a call to @ref opus_custom_mode_create. Both the encoder and decoder + * must create a mode using the same sample rate (fs) and frame size + * (frame size) so these parameters must either be signaled out of band + * or fixed in a particular implementation. + * + * Similar to regular Opus the custom modes support on the fly frame size + * switching, but the sizes available depend on the particular frame size in + * use. For some initial frame sizes on a single on the fly size is available. + */ + +/** Contains the state of an encoder. One encoder state is needed + for each stream. It is initialized once at the beginning of the + stream. Do *not* re-initialize the state for every frame. + @brief Encoder state + */ +typedef struct OpusCustomEncoder OpusCustomEncoder; + +/** State of the decoder. One decoder state is needed for each stream. + It is initialized once at the beginning of the stream. Do *not* + re-initialize the state for every frame. + @brief Decoder state + */ +typedef struct OpusCustomDecoder OpusCustomDecoder; + +/** The mode contains all the information necessary to create an + encoder. Both the encoder and decoder need to be initialized + with exactly the same mode, otherwise the output will be + corrupted. + @brief Mode configuration + */ +typedef struct OpusCustomMode OpusCustomMode; + +/** Creates a new mode struct. This will be passed to an encoder or + * decoder. The mode MUST NOT BE DESTROYED until the encoders and + * decoders that use it are destroyed as well. + * @param [in] Fs int: Sampling rate (8000 to 96000 Hz) + * @param [in] frame_size int: Number of samples (per channel) to encode in each + * packet (64 - 1024, prime factorization must contain zero or more 2s, 3s, or 5s and no other primes) + * @param [out] error int*: Returned error code (if NULL, no error will be returned) + * @return A newly created mode + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error); + +/** Destroys a mode struct. Only call this after all encoders and + * decoders using this mode are destroyed as well. + * @param [in] mode OpusCustomMode*: Mode to be freed. + */ +OPUS_CUSTOM_EXPORT void opus_custom_mode_destroy(OpusCustomMode *mode); + + +#if !defined(OPUS_BUILD) || defined(CELT_ENCODER_C) + +/* Encoder */ +/** Gets the size of an OpusCustomEncoder structure. + * @param [in] mode OpusCustomMode *: Mode configuration + * @param [in] channels int: Number of channels + * @returns size + */ +OPUS_CUSTOM_EXPORT_STATIC OPUS_WARN_UNUSED_RESULT int opus_custom_encoder_get_size( + const OpusCustomMode *mode, + int channels +) 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 OpusCustomEncoder*: Encoder state + * @param [in] mode OpusCustomMode *: Contains all the information about the characteristics of + * the stream (must be the same characteristics as used for the + * decoder) + * @param [in] channels int: 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 + * state (can't be shared across simultaneous streams). + * @param [in] mode OpusCustomMode*: Contains all the information about the characteristics of + * the stream (must be the same characteristics as used for the + * decoder) + * @param [in] channels int: Number of channels + * @param [out] error int*: Returns an error code + * @return Newly created encoder state. +*/ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomEncoder *opus_custom_encoder_create( + const OpusCustomMode *mode, + int channels, + int *error +) OPUS_ARG_NONNULL(1); + + +/** Destroys a an encoder state. + * @param[in] st OpusCustomEncoder*: State to be freed. + */ +OPUS_CUSTOM_EXPORT void opus_custom_encoder_destroy(OpusCustomEncoder *st); + +/** Encodes a frame of audio. + * @param [in] st OpusCustomEncoder*: Encoder state + * @param [in] pcm float*: PCM audio in float format, with a normal range of +/-1.0. + * Samples with a range beyond +/-1.0 are supported but will + * be clipped by decoders using the integer API and should + * only be used if it is known that the far end supports + * extended dynamic range. There must be exactly + * frame_size samples per channel. + * @param [in] frame_size int: Number of samples per frame of input signal + * @param [out] compressed char *: The compressed data is written here. This may not alias pcm and must be at least maxCompressedBytes long. + * @param [in] maxCompressedBytes int: Maximum number of bytes to use for compressing the frame + * (can change from one frame to another) + * @return Number of bytes written to "compressed". + * If negative, an error has occurred (see error codes). It is IMPORTANT that + * the length returned be somehow transmitted to the decoder. Otherwise, no + * decoding is possible. + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode_float( + OpusCustomEncoder *st, + const float *pcm, + int frame_size, + unsigned char *compressed, + int maxCompressedBytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Encodes a frame of audio. + * @param [in] st OpusCustomEncoder*: Encoder state + * @param [in] pcm opus_int16*: PCM audio in signed 16-bit format (native endian). + * There must be exactly frame_size samples per channel. + * @param [in] frame_size int: Number of samples per frame of input signal + * @param [out] compressed char *: The compressed data is written here. This may not alias pcm and must be at least maxCompressedBytes long. + * @param [in] maxCompressedBytes int: Maximum number of bytes to use for compressing the frame + * (can change from one frame to another) + * @return Number of bytes written to "compressed". + * If negative, an error has occurred (see error codes). It is IMPORTANT that + * the length returned be somehow transmitted to the decoder. Otherwise, no + * decoding is possible. + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode( + OpusCustomEncoder *st, + const opus_int16 *pcm, + int frame_size, + unsigned char *compressed, + int maxCompressedBytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Perform a CTL function on an Opus custom encoder. + * + * Generally the request and subsequent arguments are generated + * by a convenience macro. + * @see opus_encoderctls + */ +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 */ + +/** Gets the size of an OpusCustomDecoder structure. + * @param [in] mode OpusCustomMode *: Mode configuration + * @param [in] channels int: Number of channels + * @returns size + */ +OPUS_CUSTOM_EXPORT_STATIC OPUS_WARN_UNUSED_RESULT int opus_custom_decoder_get_size( + const OpusCustomMode *mode, + int channels +) OPUS_ARG_NONNULL(1); + +/** Initializes a previously allocated decoder state + * 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. + * @see opus_custom_decoder_create(),opus_custom_decoder_get_size() + * To reset a previously initialized state use the OPUS_RESET_STATE CTL. + * @param [in] st OpusCustomDecoder*: Decoder state + * @param [in] mode OpusCustomMode *: Contains all the information about the characteristics of + * the stream (must be the same characteristics as used for the + * encoder) + * @param [in] channels int: Number of channels + * @return OPUS_OK Success or @ref opus_errorcodes + */ +OPUS_CUSTOM_EXPORT_STATIC int opus_custom_decoder_init( + OpusCustomDecoder *st, + const OpusCustomMode *mode, + int channels +) 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 OpusCustomMode: Contains all the information about the characteristics of the + * stream (must be the same characteristics as used for the encoder) + * @param [in] channels int: Number of channels + * @param [out] error int*: 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. + * @param[in] st OpusCustomDecoder*: State to be freed. + */ +OPUS_CUSTOM_EXPORT void opus_custom_decoder_destroy(OpusCustomDecoder *st); + +/** Decode an opus custom frame with floating point output + * @param [in] st OpusCustomDecoder*: Decoder state + * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss + * @param [in] len int: Number of bytes in payload + * @param [out] pcm float*: Output signal (interleaved if 2 channels). length + * is frame_size*channels*sizeof(float) + * @param [in] frame_size Number of samples per channel of available space in *pcm. + * @returns Number of decoded samples or @ref opus_errorcodes + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_decode_float( + OpusCustomDecoder *st, + const unsigned char *data, + int len, + float *pcm, + int frame_size +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Decode an opus custom frame + * @param [in] st OpusCustomDecoder*: Decoder state + * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss + * @param [in] len int: Number of bytes in payload + * @param [out] pcm opus_int16*: Output signal (interleaved if 2 channels). length + * is frame_size*channels*sizeof(opus_int16) + * @param [in] frame_size Number of samples per channel of available space in *pcm. + * @returns Number of decoded samples or @ref opus_errorcodes + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_decode( + OpusCustomDecoder *st, + const unsigned char *data, + int len, + opus_int16 *pcm, + int frame_size +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Perform a CTL function on an Opus custom decoder. + * + * Generally the request and subsequent arguments are generated + * by a convenience macro. + * @see opus_genericctls + */ +OPUS_CUSTOM_EXPORT int opus_custom_decoder_ctl(OpusCustomDecoder * OPUS_RESTRICT st, int request, ...) OPUS_ARG_NONNULL(1); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* OPUS_CUSTOM_H */ diff --git a/engine/voice_codecs/celt/opus/opus_defines.h b/engine/voice_codecs/celt/opus/opus_defines.h new file mode 100644 index 00000000..d141418b --- /dev/null +++ b/engine/voice_codecs/celt/opus/opus_defines.h @@ -0,0 +1,799 @@ +/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited + Written by Jean-Marc Valin and Koen Vos */ +/* + 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. +*/ + +/** + * @file opus_defines.h + * @brief Opus reference implementation constants + */ + +#ifndef OPUS_DEFINES_H +#define OPUS_DEFINES_H + +#include "opus_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup opus_errorcodes Error codes + * @{ + */ +/** No error @hideinitializer*/ +#define OPUS_OK 0 +/** One or more invalid/out of range arguments @hideinitializer*/ +#define OPUS_BAD_ARG -1 +/** Not enough bytes allocated in the buffer @hideinitializer*/ +#define OPUS_BUFFER_TOO_SMALL -2 +/** An internal error was detected @hideinitializer*/ +#define OPUS_INTERNAL_ERROR -3 +/** The compressed data passed is corrupted @hideinitializer*/ +#define OPUS_INVALID_PACKET -4 +/** Invalid/unsupported request number @hideinitializer*/ +#define OPUS_UNIMPLEMENTED -5 +/** An encoder or decoder structure is invalid or already freed @hideinitializer*/ +#define OPUS_INVALID_STATE -6 +/** Memory allocation has failed @hideinitializer*/ +#define OPUS_ALLOC_FAIL -7 +/**@}*/ + +/** @cond OPUS_INTERNAL_DOC */ +/**Export control for opus functions */ + +#ifndef OPUS_EXPORT +# if defined(WIN32) +# if defined(OPUS_BUILD) && defined(DLL_EXPORT) +# define OPUS_EXPORT __declspec(dllexport) +# else +# define OPUS_EXPORT +# endif +# elif defined(__GNUC__) && defined(OPUS_BUILD) +# define OPUS_EXPORT __attribute__ ((visibility ("default"))) +# else +# define OPUS_EXPORT +# endif +#endif + +# if !defined(OPUS_GNUC_PREREQ) +# if defined(__GNUC__)&&defined(__GNUC_MINOR__) +# define OPUS_GNUC_PREREQ(_maj,_min) \ + ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min)) +# else +# define OPUS_GNUC_PREREQ(_maj,_min) 0 +# endif +# endif + +#if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) +# if OPUS_GNUC_PREREQ(3,0) +# define OPUS_RESTRICT __restrict__ +# elif (defined(_MSC_VER) && _MSC_VER >= 1400) +# define OPUS_RESTRICT __restrict +# else +# define OPUS_RESTRICT +# endif +#else +# define OPUS_RESTRICT restrict +#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 + * NONNULL is not used in OPUS_BUILD to avoid the compiler optimizing out + * some paranoid null checks. */ +#if defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4) +# define OPUS_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__)) +#else +# define OPUS_WARN_UNUSED_RESULT +#endif +#if !defined(OPUS_BUILD) && defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4) +# define OPUS_ARG_NONNULL(_x) __attribute__ ((__nonnull__(_x))) +#else +# define OPUS_ARG_NONNULL(_x) +#endif + +/** These are the actual Encoder CTL ID numbers. + * They should not be used directly by applications. + * In general, SETs should be even and GETs should be odd.*/ +#define OPUS_SET_APPLICATION_REQUEST 4000 +#define OPUS_GET_APPLICATION_REQUEST 4001 +#define OPUS_SET_BITRATE_REQUEST 4002 +#define OPUS_GET_BITRATE_REQUEST 4003 +#define OPUS_SET_MAX_BANDWIDTH_REQUEST 4004 +#define OPUS_GET_MAX_BANDWIDTH_REQUEST 4005 +#define OPUS_SET_VBR_REQUEST 4006 +#define OPUS_GET_VBR_REQUEST 4007 +#define OPUS_SET_BANDWIDTH_REQUEST 4008 +#define OPUS_GET_BANDWIDTH_REQUEST 4009 +#define OPUS_SET_COMPLEXITY_REQUEST 4010 +#define OPUS_GET_COMPLEXITY_REQUEST 4011 +#define OPUS_SET_INBAND_FEC_REQUEST 4012 +#define OPUS_GET_INBAND_FEC_REQUEST 4013 +#define OPUS_SET_PACKET_LOSS_PERC_REQUEST 4014 +#define OPUS_GET_PACKET_LOSS_PERC_REQUEST 4015 +#define OPUS_SET_DTX_REQUEST 4016 +#define OPUS_GET_DTX_REQUEST 4017 +#define OPUS_SET_VBR_CONSTRAINT_REQUEST 4020 +#define OPUS_GET_VBR_CONSTRAINT_REQUEST 4021 +#define OPUS_SET_FORCE_CHANNELS_REQUEST 4022 +#define OPUS_GET_FORCE_CHANNELS_REQUEST 4023 +#define OPUS_SET_SIGNAL_REQUEST 4024 +#define OPUS_GET_SIGNAL_REQUEST 4025 +#define OPUS_GET_LOOKAHEAD_REQUEST 4027 +/* #define OPUS_RESET_STATE 4028 */ +#define OPUS_GET_SAMPLE_RATE_REQUEST 4029 +#define OPUS_GET_FINAL_RANGE_REQUEST 4031 +#define OPUS_GET_PITCH_REQUEST 4033 +#define OPUS_SET_GAIN_REQUEST 4034 +#define OPUS_GET_GAIN_REQUEST 4045 /* Should have been 4035 */ +#define OPUS_SET_LSB_DEPTH_REQUEST 4036 +#define OPUS_GET_LSB_DEPTH_REQUEST 4037 +#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 */ +#define OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST 4046 +#define OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST 4047 +#define OPUS_GET_IN_DTX_REQUEST 4049 + +/** Defines for the presence of extended APIs. */ +#define OPUS_HAVE_OPUS_PROJECTION_H + +/* Macros to trigger compilation errors when the wrong types are provided to a CTL */ +#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_uint_ptr(ptr) ((ptr) + ((ptr) - (opus_uint32*)(ptr))) +#define __opus_check_val16_ptr(ptr) ((ptr) + ((ptr) - (opus_val16*)(ptr))) +/** @endcond */ + +/** @defgroup opus_ctlvalues Pre-defined values for CTL interface + * @see opus_genericctls, opus_encoderctls + * @{ + */ +/* Values for the various encoder CTLs */ +#define OPUS_AUTO -1000 /**opus_int32: Allowed values: 0-10, inclusive. + * + * @hideinitializer */ +#define OPUS_SET_COMPLEXITY(x) OPUS_SET_COMPLEXITY_REQUEST, __opus_check_int(x) +/** Gets the encoder's complexity configuration. + * @see OPUS_SET_COMPLEXITY + * @param[out] x opus_int32 *: Returns a value in the range 0-10, + * inclusive. + * @hideinitializer */ +#define OPUS_GET_COMPLEXITY(x) OPUS_GET_COMPLEXITY_REQUEST, __opus_check_int_ptr(x) + +/** Configures the bitrate in the encoder. + * Rates from 500 to 512000 bits per second are meaningful, as well as the + * special values #OPUS_AUTO and #OPUS_BITRATE_MAX. + * The value #OPUS_BITRATE_MAX can be used to cause the codec to use as much + * rate as it can, which is useful for controlling the rate by adjusting the + * output buffer size. + * @see OPUS_GET_BITRATE + * @param[in] x opus_int32: Bitrate in bits per second. The default + * is determined based on the number of + * channels and the input sampling rate. + * @hideinitializer */ +#define OPUS_SET_BITRATE(x) OPUS_SET_BITRATE_REQUEST, __opus_check_int(x) +/** Gets the encoder's bitrate configuration. + * @see OPUS_SET_BITRATE + * @param[out] x opus_int32 *: Returns the bitrate in bits per second. + * The default is determined based on the + * number of channels and the input + * sampling rate. + * @hideinitializer */ +#define OPUS_GET_BITRATE(x) OPUS_GET_BITRATE_REQUEST, __opus_check_int_ptr(x) + +/** Enables or disables variable bitrate (VBR) in the encoder. + * The configured bitrate may not be met exactly because frames must + * be an integer number of bytes in length. + * @see OPUS_GET_VBR + * @see OPUS_SET_VBR_CONSTRAINT + * @param[in] x opus_int32: Allowed values: + *
+ *
0
Hard CBR. For LPC/hybrid modes at very low bit-rate, this can + * cause noticeable quality degradation.
+ *
1
VBR (default). The exact type of VBR is controlled by + * #OPUS_SET_VBR_CONSTRAINT.
+ *
+ * @hideinitializer */ +#define OPUS_SET_VBR(x) OPUS_SET_VBR_REQUEST, __opus_check_int(x) +/** Determine if variable bitrate (VBR) is enabled in the encoder. + * @see OPUS_SET_VBR + * @see OPUS_GET_VBR_CONSTRAINT + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
0
Hard CBR.
+ *
1
VBR (default). The exact type of VBR may be retrieved via + * #OPUS_GET_VBR_CONSTRAINT.
+ *
+ * @hideinitializer */ +#define OPUS_GET_VBR(x) OPUS_GET_VBR_REQUEST, __opus_check_int_ptr(x) + +/** Enables or disables constrained VBR in the encoder. + * This setting is ignored when the encoder is in CBR mode. + * @warning Only the MDCT mode of Opus currently heeds the constraint. + * Speech mode ignores it completely, hybrid mode may fail to obey it + * if the LPC layer uses more bitrate than the constraint would have + * permitted. + * @see OPUS_GET_VBR_CONSTRAINT + * @see OPUS_SET_VBR + * @param[in] x opus_int32: Allowed values: + *
+ *
0
Unconstrained VBR.
+ *
1
Constrained VBR (default). This creates a maximum of one + * frame of buffering delay assuming a transport with a + * serialization speed of the nominal bitrate.
+ *
+ * @hideinitializer */ +#define OPUS_SET_VBR_CONSTRAINT(x) OPUS_SET_VBR_CONSTRAINT_REQUEST, __opus_check_int(x) +/** Determine if constrained VBR is enabled in the encoder. + * @see OPUS_SET_VBR_CONSTRAINT + * @see OPUS_GET_VBR + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
0
Unconstrained VBR.
+ *
1
Constrained VBR (default).
+ *
+ * @hideinitializer */ +#define OPUS_GET_VBR_CONSTRAINT(x) OPUS_GET_VBR_CONSTRAINT_REQUEST, __opus_check_int_ptr(x) + +/** Configures mono/stereo forcing in the encoder. + * This can force the encoder to produce packets encoded as either mono or + * stereo, regardless of the format of the input audio. This is useful when + * the caller knows that the input signal is currently a mono source embedded + * in a stereo stream. + * @see OPUS_GET_FORCE_CHANNELS + * @param[in] x opus_int32: Allowed values: + *
+ *
#OPUS_AUTO
Not forced (default)
+ *
1
Forced mono
+ *
2
Forced stereo
+ *
+ * @hideinitializer */ +#define OPUS_SET_FORCE_CHANNELS(x) OPUS_SET_FORCE_CHANNELS_REQUEST, __opus_check_int(x) +/** Gets the encoder's forced channel configuration. + * @see OPUS_SET_FORCE_CHANNELS + * @param[out] x opus_int32 *: + *
+ *
#OPUS_AUTO
Not forced (default)
+ *
1
Forced mono
+ *
2
Forced stereo
+ *
+ * @hideinitializer */ +#define OPUS_GET_FORCE_CHANNELS(x) OPUS_GET_FORCE_CHANNELS_REQUEST, __opus_check_int_ptr(x) + +/** Configures the maximum bandpass that the encoder will select automatically. + * Applications should normally use this instead of #OPUS_SET_BANDWIDTH + * (leaving that set to the default, #OPUS_AUTO). This allows the + * application to set an upper bound based on the type of input it is + * providing, but still gives the encoder the freedom to reduce the bandpass + * when the bitrate becomes too low, for better overall quality. + * @see OPUS_GET_MAX_BANDWIDTH + * @param[in] x opus_int32: Allowed values: + *
+ *
OPUS_BANDWIDTH_NARROWBAND
4 kHz passband
+ *
OPUS_BANDWIDTH_MEDIUMBAND
6 kHz passband
+ *
OPUS_BANDWIDTH_WIDEBAND
8 kHz passband
+ *
OPUS_BANDWIDTH_SUPERWIDEBAND
12 kHz passband
+ *
OPUS_BANDWIDTH_FULLBAND
20 kHz passband (default)
+ *
+ * @hideinitializer */ +#define OPUS_SET_MAX_BANDWIDTH(x) OPUS_SET_MAX_BANDWIDTH_REQUEST, __opus_check_int(x) + +/** Gets the encoder's configured maximum allowed bandpass. + * @see OPUS_SET_MAX_BANDWIDTH + * @param[out] x opus_int32 *: Allowed values: + *
+ *
#OPUS_BANDWIDTH_NARROWBAND
4 kHz passband
+ *
#OPUS_BANDWIDTH_MEDIUMBAND
6 kHz passband
+ *
#OPUS_BANDWIDTH_WIDEBAND
8 kHz passband
+ *
#OPUS_BANDWIDTH_SUPERWIDEBAND
12 kHz passband
+ *
#OPUS_BANDWIDTH_FULLBAND
20 kHz passband (default)
+ *
+ * @hideinitializer */ +#define OPUS_GET_MAX_BANDWIDTH(x) OPUS_GET_MAX_BANDWIDTH_REQUEST, __opus_check_int_ptr(x) + +/** Sets the encoder's bandpass to a specific value. + * This prevents the encoder from automatically selecting the bandpass based + * on the available bitrate. If an application knows the bandpass of the input + * audio it is providing, it should normally use #OPUS_SET_MAX_BANDWIDTH + * instead, which still gives the encoder the freedom to reduce the bandpass + * when the bitrate becomes too low, for better overall quality. + * @see OPUS_GET_BANDWIDTH + * @param[in] x opus_int32: Allowed values: + *
+ *
#OPUS_AUTO
(default)
+ *
#OPUS_BANDWIDTH_NARROWBAND
4 kHz passband
+ *
#OPUS_BANDWIDTH_MEDIUMBAND
6 kHz passband
+ *
#OPUS_BANDWIDTH_WIDEBAND
8 kHz passband
+ *
#OPUS_BANDWIDTH_SUPERWIDEBAND
12 kHz passband
+ *
#OPUS_BANDWIDTH_FULLBAND
20 kHz passband
+ *
+ * @hideinitializer */ +#define OPUS_SET_BANDWIDTH(x) OPUS_SET_BANDWIDTH_REQUEST, __opus_check_int(x) + +/** Configures the type of signal being encoded. + * This is a hint which helps the encoder's mode selection. + * @see OPUS_GET_SIGNAL + * @param[in] x opus_int32: Allowed values: + *
+ *
#OPUS_AUTO
(default)
+ *
#OPUS_SIGNAL_VOICE
Bias thresholds towards choosing LPC or Hybrid modes.
+ *
#OPUS_SIGNAL_MUSIC
Bias thresholds towards choosing MDCT modes.
+ *
+ * @hideinitializer */ +#define OPUS_SET_SIGNAL(x) OPUS_SET_SIGNAL_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured signal type. + * @see OPUS_SET_SIGNAL + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
#OPUS_AUTO
(default)
+ *
#OPUS_SIGNAL_VOICE
Bias thresholds towards choosing LPC or Hybrid modes.
+ *
#OPUS_SIGNAL_MUSIC
Bias thresholds towards choosing MDCT modes.
+ *
+ * @hideinitializer */ +#define OPUS_GET_SIGNAL(x) OPUS_GET_SIGNAL_REQUEST, __opus_check_int_ptr(x) + + +/** Configures the encoder's intended application. + * The initial value is a mandatory argument to the encoder_create function. + * @see OPUS_GET_APPLICATION + * @param[in] x opus_int32: Returns one of the following values: + *
+ *
#OPUS_APPLICATION_VOIP
+ *
Process signal for improved speech intelligibility.
+ *
#OPUS_APPLICATION_AUDIO
+ *
Favor faithfulness to the original input.
+ *
#OPUS_APPLICATION_RESTRICTED_LOWDELAY
+ *
Configure the minimum possible coding delay by disabling certain modes + * of operation.
+ *
+ * @hideinitializer */ +#define OPUS_SET_APPLICATION(x) OPUS_SET_APPLICATION_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured application. + * @see OPUS_SET_APPLICATION + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
#OPUS_APPLICATION_VOIP
+ *
Process signal for improved speech intelligibility.
+ *
#OPUS_APPLICATION_AUDIO
+ *
Favor faithfulness to the original input.
+ *
#OPUS_APPLICATION_RESTRICTED_LOWDELAY
+ *
Configure the minimum possible coding delay by disabling certain modes + * of operation.
+ *
+ * @hideinitializer */ +#define OPUS_GET_APPLICATION(x) OPUS_GET_APPLICATION_REQUEST, __opus_check_int_ptr(x) + +/** Gets the total samples of delay added by the entire codec. + * This can be queried by the encoder and then the provided number of samples can be + * skipped on from the start of the decoder's output to provide time aligned input + * and output. From the perspective of a decoding application the real data begins this many + * samples late. + * + * The decoder contribution to this delay is identical for all decoders, but the + * encoder portion of the delay may vary from implementation to implementation, + * version to version, or even depend on the encoder's initial configuration. + * Applications needing delay compensation should call this CTL rather than + * hard-coding a value. + * @param[out] x opus_int32 *: Number of lookahead samples + * @hideinitializer */ +#define OPUS_GET_LOOKAHEAD(x) OPUS_GET_LOOKAHEAD_REQUEST, __opus_check_int_ptr(x) + +/** Configures the encoder's use of inband forward error correction (FEC). + * @note This is only applicable to the LPC layer + * @see OPUS_GET_INBAND_FEC + * @param[in] x opus_int32: Allowed values: + *
+ *
0
Disable inband FEC (default).
+ *
1
Enable inband FEC.
+ *
+ * @hideinitializer */ +#define OPUS_SET_INBAND_FEC(x) OPUS_SET_INBAND_FEC_REQUEST, __opus_check_int(x) +/** Gets encoder's configured use of inband forward error correction. + * @see OPUS_SET_INBAND_FEC + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
0
Inband FEC disabled (default).
+ *
1
Inband FEC enabled.
+ *
+ * @hideinitializer */ +#define OPUS_GET_INBAND_FEC(x) OPUS_GET_INBAND_FEC_REQUEST, __opus_check_int_ptr(x) + +/** Configures the encoder's expected packet loss percentage. + * Higher values trigger progressively more loss resistant behavior in the encoder + * at the expense of quality at a given bitrate in the absence of packet loss, but + * greater quality under loss. + * @see OPUS_GET_PACKET_LOSS_PERC + * @param[in] x opus_int32: Loss percentage in the range 0-100, inclusive (default: 0). + * @hideinitializer */ +#define OPUS_SET_PACKET_LOSS_PERC(x) OPUS_SET_PACKET_LOSS_PERC_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured packet loss percentage. + * @see OPUS_SET_PACKET_LOSS_PERC + * @param[out] x opus_int32 *: Returns the configured loss percentage + * in the range 0-100, inclusive (default: 0). + * @hideinitializer */ +#define OPUS_GET_PACKET_LOSS_PERC(x) OPUS_GET_PACKET_LOSS_PERC_REQUEST, __opus_check_int_ptr(x) + +/** Configures the encoder's use of discontinuous transmission (DTX). + * @note This is only applicable to the LPC layer + * @see OPUS_GET_DTX + * @param[in] x opus_int32: Allowed values: + *
+ *
0
Disable DTX (default).
+ *
1
Enabled DTX.
+ *
+ * @hideinitializer */ +#define OPUS_SET_DTX(x) OPUS_SET_DTX_REQUEST, __opus_check_int(x) +/** Gets encoder's configured use of discontinuous transmission. + * @see OPUS_SET_DTX + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
0
DTX disabled (default).
+ *
1
DTX enabled.
+ *
+ * @hideinitializer */ +#define OPUS_GET_DTX(x) OPUS_GET_DTX_REQUEST, __opus_check_int_ptr(x) +/** Configures the depth of signal being encoded. + * + * This is a hint which helps the encoder identify silence and near-silence. + * It represents the number of significant bits of linear intensity below + * which the signal contains ignorable quantization or other noise. + * + * For example, OPUS_SET_LSB_DEPTH(14) would be an appropriate setting + * for G.711 u-law input. OPUS_SET_LSB_DEPTH(16) would be appropriate + * for 16-bit linear pcm input with opus_encode_float(). + * + * When using opus_encode() instead of opus_encode_float(), or when libopus + * is compiled for fixed-point, the encoder uses the minimum of the value + * set here and the value 16. + * + * @see OPUS_GET_LSB_DEPTH + * @param[in] x opus_int32: Input precision in bits, between 8 and 24 + * (default: 24). + * @hideinitializer */ +#define OPUS_SET_LSB_DEPTH(x) OPUS_SET_LSB_DEPTH_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured signal depth. + * @see OPUS_SET_LSB_DEPTH + * @param[out] x opus_int32 *: Input precision in bits, between 8 and + * 24 (default: 24). + * @hideinitializer */ +#define OPUS_GET_LSB_DEPTH(x) OPUS_GET_LSB_DEPTH_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 really + * know what you are doing. + * @see OPUS_GET_EXPERT_FRAME_DURATION + * @param[in] x opus_int32: Allowed values: + *
+ *
OPUS_FRAMESIZE_ARG
Select frame size from the argument (default).
+ *
OPUS_FRAMESIZE_2_5_MS
Use 2.5 ms frames.
+ *
OPUS_FRAMESIZE_5_MS
Use 5 ms frames.
+ *
OPUS_FRAMESIZE_10_MS
Use 10 ms frames.
+ *
OPUS_FRAMESIZE_20_MS
Use 20 ms frames.
+ *
OPUS_FRAMESIZE_40_MS
Use 40 ms frames.
+ *
OPUS_FRAMESIZE_60_MS
Use 60 ms frames.
+ *
OPUS_FRAMESIZE_80_MS
Use 80 ms frames.
+ *
OPUS_FRAMESIZE_100_MS
Use 100 ms frames.
+ *
OPUS_FRAMESIZE_120_MS
Use 120 ms frames.
+ *
+ * @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_FRAME_DURATION + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
OPUS_FRAMESIZE_ARG
Select frame size from the argument (default).
+ *
OPUS_FRAMESIZE_2_5_MS
Use 2.5 ms frames.
+ *
OPUS_FRAMESIZE_5_MS
Use 5 ms frames.
+ *
OPUS_FRAMESIZE_10_MS
Use 10 ms frames.
+ *
OPUS_FRAMESIZE_20_MS
Use 20 ms frames.
+ *
OPUS_FRAMESIZE_40_MS
Use 40 ms frames.
+ *
OPUS_FRAMESIZE_60_MS
Use 60 ms frames.
+ *
OPUS_FRAMESIZE_80_MS
Use 80 ms frames.
+ *
OPUS_FRAMESIZE_100_MS
Use 100 ms frames.
+ *
OPUS_FRAMESIZE_120_MS
Use 120 ms frames.
+ *
+ * @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. + * @see OPUS_GET_PREDICTION_DISABLED + * @param[in] x opus_int32: Allowed values: + *
+ *
0
Enable prediction (default).
+ *
1
Disable prediction.
+ *
+ * @hideinitializer */ +#define OPUS_SET_PREDICTION_DISABLED(x) OPUS_SET_PREDICTION_DISABLED_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured prediction status. + * @see OPUS_SET_PREDICTION_DISABLED + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
0
Prediction enabled (default).
+ *
1
Prediction disabled.
+ *
+ * @hideinitializer */ +#define OPUS_GET_PREDICTION_DISABLED(x) OPUS_GET_PREDICTION_DISABLED_REQUEST, __opus_check_int_ptr(x) + +/**@}*/ + +/** @defgroup opus_genericctls Generic CTLs + * + * These macros are used with the \c opus_decoder_ctl and + * \c opus_encoder_ctl calls to generate a particular + * request. + * + * When called on an \c OpusDecoder they apply to that + * particular decoder instance. When called on an + * \c OpusEncoder they apply to the corresponding setting + * on that encoder instance, if present. + * + * Some usage examples: + * + * @code + * int ret; + * opus_int32 pitch; + * ret = opus_decoder_ctl(dec_ctx, OPUS_GET_PITCH(&pitch)); + * if (ret == OPUS_OK) return ret; + * + * opus_encoder_ctl(enc_ctx, OPUS_RESET_STATE); + * opus_decoder_ctl(dec_ctx, OPUS_RESET_STATE); + * + * opus_int32 enc_bw, dec_bw; + * opus_encoder_ctl(enc_ctx, OPUS_GET_BANDWIDTH(&enc_bw)); + * opus_decoder_ctl(dec_ctx, OPUS_GET_BANDWIDTH(&dec_bw)); + * if (enc_bw != dec_bw) { + * printf("packet bandwidth mismatch!\n"); + * } + * @endcode + * + * @see opus_encoder, opus_decoder_ctl, opus_encoder_ctl, opus_decoderctls, opus_encoderctls + * @{ + */ + +/** Resets the codec state to be equivalent to a freshly initialized state. + * This should be called when switching streams in order to prevent + * the back to back decoding from giving different results from + * one at a time decoding. + * @hideinitializer */ +#define OPUS_RESET_STATE 4028 + +/** Gets the final state of the codec's entropy coder. + * This is used for testing purposes, + * The encoder and decoder state should be identical after coding a payload + * (assuming no data corruption or software bugs) + * + * @param[out] x opus_uint32 *: Entropy coder state + * + * @hideinitializer */ +#define OPUS_GET_FINAL_RANGE(x) OPUS_GET_FINAL_RANGE_REQUEST, __opus_check_uint_ptr(x) + +/** Gets the encoder's configured bandpass or the decoder's last bandpass. + * @see OPUS_SET_BANDWIDTH + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
#OPUS_AUTO
(default)
+ *
#OPUS_BANDWIDTH_NARROWBAND
4 kHz passband
+ *
#OPUS_BANDWIDTH_MEDIUMBAND
6 kHz passband
+ *
#OPUS_BANDWIDTH_WIDEBAND
8 kHz passband
+ *
#OPUS_BANDWIDTH_SUPERWIDEBAND
12 kHz passband
+ *
#OPUS_BANDWIDTH_FULLBAND
20 kHz passband
+ *
+ * @hideinitializer */ +#define OPUS_GET_BANDWIDTH(x) OPUS_GET_BANDWIDTH_REQUEST, __opus_check_int_ptr(x) + +/** Gets the sampling rate the encoder or decoder was initialized with. + * This simply returns the Fs value passed to opus_encoder_init() + * or opus_decoder_init(). + * @param[out] x opus_int32 *: Sampling rate of encoder or decoder. + * @hideinitializer + */ +#define OPUS_GET_SAMPLE_RATE(x) OPUS_GET_SAMPLE_RATE_REQUEST, __opus_check_int_ptr(x) + +/** If set to 1, disables the use of phase inversion for intensity stereo, + * improving the quality of mono downmixes, but slightly reducing normal + * stereo quality. Disabling phase inversion in the decoder does not comply + * with RFC 6716, although it does not cause any interoperability issue and + * is expected to become part of the Opus standard once RFC 6716 is updated + * by draft-ietf-codec-opus-update. + * @see OPUS_GET_PHASE_INVERSION_DISABLED + * @param[in] x opus_int32: Allowed values: + *
+ *
0
Enable phase inversion (default).
+ *
1
Disable phase inversion.
+ *
+ * @hideinitializer */ +#define OPUS_SET_PHASE_INVERSION_DISABLED(x) OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured phase inversion status. + * @see OPUS_SET_PHASE_INVERSION_DISABLED + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
0
Stereo phase inversion enabled (default).
+ *
1
Stereo phase inversion disabled.
+ *
+ * @hideinitializer */ +#define OPUS_GET_PHASE_INVERSION_DISABLED(x) OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, __opus_check_int_ptr(x) +/** Gets the DTX state of the encoder. + * Returns whether the last encoded frame was either a comfort noise update + * during DTX or not encoded because of DTX. + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
0
The encoder is not in DTX.
+ *
1
The encoder is in DTX.
+ *
+ * @hideinitializer */ +#define OPUS_GET_IN_DTX(x) OPUS_GET_IN_DTX_REQUEST, __opus_check_int_ptr(x) + +/**@}*/ + +/** @defgroup opus_decoderctls Decoder related CTLs + * @see opus_genericctls, opus_encoderctls, opus_decoder + * @{ + */ + +/** Configures decoder gain adjustment. + * Scales the decoded output by a factor specified in Q8 dB units. + * This has a maximum range of -32768 to 32767 inclusive, and returns + * OPUS_BAD_ARG otherwise. The default is zero indicating no adjustment. + * This setting survives decoder reset. + * + * gain = pow(10, x/(20.0*256)) + * + * @param[in] x opus_int32: Amount to scale PCM signal by in Q8 dB units. + * @hideinitializer */ +#define OPUS_SET_GAIN(x) OPUS_SET_GAIN_REQUEST, __opus_check_int(x) +/** Gets the decoder's configured gain adjustment. @see OPUS_SET_GAIN + * + * @param[out] x opus_int32 *: Amount to scale PCM signal by in Q8 dB units. + * @hideinitializer */ +#define OPUS_GET_GAIN(x) OPUS_GET_GAIN_REQUEST, __opus_check_int_ptr(x) + +/** Gets the duration (in samples) of the last packet successfully decoded or concealed. + * @param[out] x opus_int32 *: Number of samples (at current sampling rate). + * @hideinitializer */ +#define OPUS_GET_LAST_PACKET_DURATION(x) OPUS_GET_LAST_PACKET_DURATION_REQUEST, __opus_check_int_ptr(x) + +/** Gets the pitch of the last decoded frame, if available. + * This can be used for any post-processing algorithm requiring the use of pitch, + * e.g. time stretching/shortening. If the last frame was not voiced, or if the + * pitch was not coded in the frame, then zero is returned. + * + * This CTL is only implemented for decoder instances. + * + * @param[out] x opus_int32 *: pitch period at 48 kHz (or 0 if not available) + * + * @hideinitializer */ +#define OPUS_GET_PITCH(x) OPUS_GET_PITCH_REQUEST, __opus_check_int_ptr(x) + +/**@}*/ + +/** @defgroup opus_libinfo Opus library information functions + * @{ + */ + +/** Converts an opus error code into a human readable string. + * + * @param[in] error int: Error number + * @returns Error string + */ +OPUS_EXPORT const char *opus_strerror(int error); + +/** Gets the libopus version string. + * + * Applications may look for the substring "-fixed" in the version string to + * determine whether they have a fixed-point or floating-point build at + * runtime. + * + * @returns Version string + */ +OPUS_EXPORT const char *opus_get_version_string(void); +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* OPUS_DEFINES_H */ diff --git a/engine/voice_codecs/celt/opus/opus_multistream.h b/engine/voice_codecs/celt/opus/opus_multistream.h new file mode 100644 index 00000000..babcee69 --- /dev/null +++ b/engine/voice_codecs/celt/opus/opus_multistream.h @@ -0,0 +1,660 @@ +/* Copyright (c) 2011 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. +*/ + +/** + * @file opus_multistream.h + * @brief Opus reference implementation multistream API + */ + +#ifndef OPUS_MULTISTREAM_H +#define OPUS_MULTISTREAM_H + +#include "opus.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond OPUS_INTERNAL_DOC */ + +/** Macros to trigger compilation errors when the wrong types are provided to a + * CTL. */ +/**@{*/ +#define __opus_check_encstate_ptr(ptr) ((ptr) + ((ptr) - (OpusEncoder**)(ptr))) +#define __opus_check_decstate_ptr(ptr) ((ptr) + ((ptr) - (OpusDecoder**)(ptr))) +/**@}*/ + +/** These are the actual encoder and decoder CTL ID numbers. + * They should not be used directly by applications. + * In general, SETs should be even and GETs should be odd.*/ +/**@{*/ +#define OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST 5120 +#define OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST 5122 +/**@}*/ + +/** @endcond */ + +/** @defgroup opus_multistream_ctls Multistream specific encoder and decoder CTLs + * + * These are convenience macros that are specific to the + * opus_multistream_encoder_ctl() and opus_multistream_decoder_ctl() + * interface. + * The CTLs from @ref opus_genericctls, @ref opus_encoderctls, and + * @ref opus_decoderctls may be applied to a multistream encoder or decoder as + * well. + * In addition, you may retrieve the encoder or decoder state for an specific + * stream via #OPUS_MULTISTREAM_GET_ENCODER_STATE or + * #OPUS_MULTISTREAM_GET_DECODER_STATE and apply CTLs to it individually. + */ +/**@{*/ + +/** Gets the encoder state for an individual stream of a multistream encoder. + * @param[in] x opus_int32: The index of the stream whose encoder you + * wish to retrieve. + * This must be non-negative and less than + * the streams parameter used + * to initialize the encoder. + * @param[out] y OpusEncoder**: Returns a pointer to the given + * encoder state. + * @retval OPUS_BAD_ARG The index of the requested stream was out of range. + * @hideinitializer + */ +#define OPUS_MULTISTREAM_GET_ENCODER_STATE(x,y) OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST, __opus_check_int(x), __opus_check_encstate_ptr(y) + +/** Gets the decoder state for an individual stream of a multistream decoder. + * @param[in] x opus_int32: The index of the stream whose decoder you + * wish to retrieve. + * This must be non-negative and less than + * the streams parameter used + * to initialize the decoder. + * @param[out] y OpusDecoder**: Returns a pointer to the given + * decoder state. + * @retval OPUS_BAD_ARG The index of the requested stream was out of range. + * @hideinitializer + */ +#define OPUS_MULTISTREAM_GET_DECODER_STATE(x,y) OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST, __opus_check_int(x), __opus_check_decstate_ptr(y) + +/**@}*/ + +/** @defgroup opus_multistream Opus Multistream API + * @{ + * + * The multistream API allows individual Opus streams to be combined into a + * single packet, enabling support for up to 255 channels. Unlike an + * elementary Opus stream, the encoder and decoder must negotiate the channel + * configuration before the decoder can successfully interpret the data in the + * packets produced by the encoder. Some basic information, such as packet + * duration, can be computed without any special negotiation. + * + * The format for multistream Opus packets is defined in + *
RFC 7845 + * and is based on the self-delimited Opus framing described in Appendix B of + * RFC 6716. + * Normal Opus packets are just a degenerate case of multistream Opus packets, + * and can be encoded or decoded with the multistream API by setting + * streams to 1 when initializing the encoder or + * decoder. + * + * Multistream Opus streams can contain up to 255 elementary Opus streams. + * These may be either "uncoupled" or "coupled", indicating that the decoder + * is configured to decode them to either 1 or 2 channels, respectively. + * The streams are ordered so that all coupled streams appear at the + * beginning. + * + * A mapping table defines which decoded channel i + * should be used for each input/output (I/O) channel j. This table is + * typically provided as an unsigned char array. + * Let i = mapping[j] be the index for I/O channel j. + * If i < 2*coupled_streams, then I/O channel j is + * encoded as the left channel of stream (i/2) if i + * is even, or as the right channel of stream (i/2) if + * i is odd. Otherwise, I/O channel j is encoded as + * mono in stream (i - coupled_streams), unless it has the special + * value 255, in which case it is omitted from the encoding entirely (the + * decoder will reproduce it as silence). Each value i must either + * be the special value 255 or be less than streams + coupled_streams. + * + * The output channels specified by the encoder + * should use the + * Vorbis + * channel ordering. A decoder may wish to apply an additional permutation + * to the mapping the encoder used to achieve a different output channel + * order (e.g. for outputing in WAV order). + * + * Each multistream packet contains an Opus packet for each stream, and all of + * the Opus packets in a single multistream packet must have the same + * duration. Therefore the duration of a multistream packet can be extracted + * from the TOC sequence of the first stream, which is located at the + * beginning of the packet, just like an elementary Opus stream: + * + * @code + * int nb_samples; + * int nb_frames; + * nb_frames = opus_packet_get_nb_frames(data, len); + * if (nb_frames < 1) + * return nb_frames; + * nb_samples = opus_packet_get_samples_per_frame(data, 48000) * nb_frames; + * @endcode + * + * The general encoding and decoding process proceeds exactly the same as in + * the normal @ref opus_encoder and @ref opus_decoder APIs. + * See their documentation for an overview of how to use the corresponding + * multistream functions. + */ + +/** Opus multistream encoder state. + * This contains the complete state of a multistream Opus encoder. + * It is position independent and can be freely copied. + * @see opus_multistream_encoder_create + * @see opus_multistream_encoder_init + */ +typedef struct OpusMSEncoder OpusMSEncoder; + +/** Opus multistream decoder state. + * This contains the complete state of a multistream Opus decoder. + * It is position independent and can be freely copied. + * @see opus_multistream_decoder_create + * @see opus_multistream_decoder_init + */ +typedef struct OpusMSDecoder OpusMSDecoder; + +/**\name Multistream encoder functions */ +/**@{*/ + +/** Gets the size of an OpusMSEncoder structure. + * @param streams int: The total number of streams to encode from the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number of coupled (2 channel) streams + * to encode. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * encoded channels (streams + + * coupled_streams) must be no + * more than 255. + * @returns The size in bytes on success, or a negative error code + * (see @ref opus_errorcodes) on error. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_encoder_get_size( + int 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. + * Call opus_multistream_encoder_destroy() to release + * this object when finished. + * @param Fs opus_int32: Sampling rate of the input signal (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels in the input signal. + * This must be at most 255. + * It may be greater than the number of + * coded channels (streams + + * coupled_streams). + * @param streams int: The total number of streams to encode from the + * input. + * This must be no more than the number of channels. + * @param coupled_streams int: Number of coupled (2 channel) streams + * to encode. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * encoded channels (streams + + * coupled_streams) must be no + * more than the number of input channels. + * @param[in] mapping const unsigned char[channels]: Mapping from + * encoded channels to input channels, as described in + * @ref opus_multistream. As an extra constraint, the + * multistream encoder does not allow encoding coupled + * streams for which one channel is unused since this + * is never a good idea. + * @param application int: The target encoder application. + * This must be one of the following: + *
+ *
#OPUS_APPLICATION_VOIP
+ *
Process signal for improved speech intelligibility.
+ *
#OPUS_APPLICATION_AUDIO
+ *
Favor faithfulness to the original input.
+ *
#OPUS_APPLICATION_RESTRICTED_LOWDELAY
+ *
Configure the minimum possible coding delay by disabling certain modes + * of operation.
+ *
+ * @param[out] error int *: Returns #OPUS_OK on success, or an error + * code (see @ref opus_errorcodes) on + * failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_encoder_create( + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping, + int application, + int *error +) 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(4) OPUS_ARG_NONNULL(5) OPUS_ARG_NONNULL(6); + +/** Initialize a previously allocated multistream encoder state. + * The memory pointed to by \a st must be at least the size returned by + * opus_multistream_encoder_get_size(). + * This is intended for applications which use their own allocator instead of + * malloc. + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. + * @see opus_multistream_encoder_create + * @see opus_multistream_encoder_get_size + * @param st OpusMSEncoder*: Multistream encoder state to initialize. + * @param Fs opus_int32: Sampling rate of the input signal (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels in the input signal. + * This must be at most 255. + * It may be greater than the number of + * coded channels (streams + + * coupled_streams). + * @param streams int: The total number of streams to encode from the + * input. + * This must be no more than the number of channels. + * @param coupled_streams int: Number of coupled (2 channel) streams + * to encode. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * encoded channels (streams + + * coupled_streams) must be no + * more than the number of input channels. + * @param[in] mapping const unsigned char[channels]: Mapping from + * encoded channels to input channels, as described in + * @ref opus_multistream. As an extra constraint, the + * multistream encoder does not allow encoding coupled + * streams for which one channel is unused since this + * is never a good idea. + * @param application int: The target encoder application. + * This must be one of the following: + *
+ *
#OPUS_APPLICATION_VOIP
+ *
Process signal for improved speech intelligibility.
+ *
#OPUS_APPLICATION_AUDIO
+ *
Favor faithfulness to the original input.
+ *
#OPUS_APPLICATION_RESTRICTED_LOWDELAY
+ *
Configure the minimum possible coding delay by disabling certain modes + * of operation.
+ *
+ * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes) + * on failure. + */ +OPUS_EXPORT int opus_multistream_encoder_init( + OpusMSEncoder *st, + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping, + int application +) 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(5) OPUS_ARG_NONNULL(6) OPUS_ARG_NONNULL(7); + +/** Encodes a multistream Opus frame. + * @param st OpusMSEncoder*: Multistream encoder state. + * @param[in] pcm const opus_int16*: The input signal as interleaved + * samples. + * This must contain + * frame_size*channels + * samples. + * @param frame_size int: Number of samples per channel in the input + * signal. + * This must be an Opus frame size for the + * encoder's sampling rate. + * For example, at 48 kHz the permitted values + * are 120, 240, 480, 960, 1920, and 2880. + * Passing in a duration of less than 10 ms + * (480 samples at 48 kHz) will prevent the + * encoder from using the LPC or hybrid modes. + * @param[out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode( + OpusMSEncoder *st, + const opus_int16 *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Encodes a multistream Opus frame from floating point input. + * @param st OpusMSEncoder*: Multistream encoder state. + * @param[in] pcm const float*: The input signal as interleaved + * samples with a normal range of + * +/-1.0. + * Samples with a range beyond +/-1.0 + * are supported but will be clipped by + * decoders using the integer API and + * should only be used if it is known + * that the far end supports extended + * dynamic range. + * This must contain + * frame_size*channels + * samples. + * @param frame_size int: Number of samples per channel in the input + * signal. + * This must be an Opus frame size for the + * encoder's sampling rate. + * For example, at 48 kHz the permitted values + * are 120, 240, 480, 960, 1920, and 2880. + * Passing in a duration of less than 10 ms + * (480 samples at 48 kHz) will prevent the + * encoder from using the LPC or hybrid modes. + * @param[out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode_float( + OpusMSEncoder *st, + const float *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Frees an OpusMSEncoder allocated by + * opus_multistream_encoder_create(). + * @param st OpusMSEncoder*: Multistream encoder state to be freed. + */ +OPUS_EXPORT void opus_multistream_encoder_destroy(OpusMSEncoder *st); + +/** Perform a CTL function on a multistream Opus encoder. + * + * Generally the request and subsequent arguments are generated by a + * convenience macro. + * @param st OpusMSEncoder*: Multistream encoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls, + * @ref opus_encoderctls, or @ref opus_multistream_ctls. + * @see opus_genericctls + * @see opus_encoderctls + * @see opus_multistream_ctls + */ +OPUS_EXPORT int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...) OPUS_ARG_NONNULL(1); + +/**@}*/ + +/**\name Multistream decoder functions */ +/**@{*/ + +/** Gets the size of an OpusMSDecoder structure. + * @param streams int: The total number of streams coded in the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number streams to decode as coupled + * (2 channel) streams. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * coded channels (streams + + * coupled_streams) must be no + * more than 255. + * @returns The size in bytes on success, or a negative error code + * (see @ref opus_errorcodes) on error. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_decoder_get_size( + int streams, + int coupled_streams +); + +/** Allocates and initializes a multistream decoder state. + * Call opus_multistream_decoder_destroy() to release + * this object when finished. + * @param Fs opus_int32: Sampling rate to decode at (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels to output. + * This must be at most 255. + * It may be different from the number of coded + * channels (streams + + * coupled_streams). + * @param streams int: The total number of streams coded in the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number of streams to decode as coupled + * (2 channel) streams. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * coded channels (streams + + * coupled_streams) must be no + * more than 255. + * @param[in] mapping const unsigned char[channels]: Mapping from + * coded channels to output channels, as described in + * @ref opus_multistream. + * @param[out] error int *: Returns #OPUS_OK on success, or an error + * code (see @ref opus_errorcodes) on + * failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSDecoder *opus_multistream_decoder_create( + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping, + int *error +) OPUS_ARG_NONNULL(5); + +/** Intialize a previously allocated decoder state object. + * The memory pointed to by \a st must be at least the size returned by + * opus_multistream_encoder_get_size(). + * This is intended for applications which use their own allocator instead of + * malloc. + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. + * @see opus_multistream_decoder_create + * @see opus_multistream_deocder_get_size + * @param st OpusMSEncoder*: Multistream encoder state to initialize. + * @param Fs opus_int32: Sampling rate to decode at (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels to output. + * This must be at most 255. + * It may be different from the number of coded + * channels (streams + + * coupled_streams). + * @param streams int: The total number of streams coded in the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number of streams to decode as coupled + * (2 channel) streams. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * coded channels (streams + + * coupled_streams) must be no + * more than 255. + * @param[in] mapping const unsigned char[channels]: Mapping from + * coded channels to output channels, as described in + * @ref opus_multistream. + * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes) + * on failure. + */ +OPUS_EXPORT int opus_multistream_decoder_init( + OpusMSDecoder *st, + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6); + +/** Decode a multistream Opus packet. + * @param st OpusMSDecoder*: Multistream decoder state. + * @param[in] data const unsigned char*: Input payload. + * Use a NULL + * pointer to indicate packet + * loss. + * @param len opus_int32: Number of bytes in payload. + * @param[out] pcm opus_int16*: Output signal, with interleaved + * samples. + * This must contain room for + * frame_size*channels + * samples. + * @param frame_size int: The number of samples per channel of + * available space in \a pcm. + * If this is less than the maximum packet duration + * (120 ms; 5760 for 48kHz), this function will not be capable + * of decoding some packets. In the case of PLC (data==NULL) + * or FEC (decode_fec=1), then frame_size needs to be exactly + * the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the + * next incoming packet. For the PLC and FEC cases, frame_size + * must be a multiple of 2.5 ms. + * @param decode_fec int: Flag (0 or 1) to request that any in-band + * forward error correction data be decoded. + * If no such data is available, the frame is + * decoded as if it were lost. + * @returns Number of samples decoded on success or a negative error code + * (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode( + OpusMSDecoder *st, + const unsigned char *data, + opus_int32 len, + opus_int16 *pcm, + int frame_size, + int decode_fec +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Decode a multistream Opus packet with floating point output. + * @param st OpusMSDecoder*: Multistream decoder state. + * @param[in] data const unsigned char*: Input payload. + * Use a NULL + * pointer to indicate packet + * loss. + * @param len opus_int32: Number of bytes in payload. + * @param[out] pcm opus_int16*: Output signal, with interleaved + * samples. + * This must contain room for + * frame_size*channels + * samples. + * @param frame_size int: The number of samples per channel of + * available space in \a pcm. + * If this is less than the maximum packet duration + * (120 ms; 5760 for 48kHz), this function will not be capable + * of decoding some packets. In the case of PLC (data==NULL) + * or FEC (decode_fec=1), then frame_size needs to be exactly + * the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the + * next incoming packet. For the PLC and FEC cases, frame_size + * must be a multiple of 2.5 ms. + * @param decode_fec int: Flag (0 or 1) to request that any in-band + * forward error correction data be decoded. + * If no such data is available, the frame is + * decoded as if it were lost. + * @returns Number of samples decoded on success or a negative error code + * (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode_float( + OpusMSDecoder *st, + const unsigned char *data, + opus_int32 len, + float *pcm, + int frame_size, + int decode_fec +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Perform a CTL function on a multistream Opus decoder. + * + * Generally the request and subsequent arguments are generated by a + * convenience macro. + * @param st OpusMSDecoder*: Multistream decoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls, + * @ref opus_decoderctls, or @ref opus_multistream_ctls. + * @see opus_genericctls + * @see opus_decoderctls + * @see opus_multistream_ctls + */ +OPUS_EXPORT int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) OPUS_ARG_NONNULL(1); + +/** Frees an OpusMSDecoder allocated by + * opus_multistream_decoder_create(). + * @param st OpusMSDecoder: Multistream decoder state to be freed. + */ +OPUS_EXPORT void opus_multistream_decoder_destroy(OpusMSDecoder *st); + +/**@}*/ + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* OPUS_MULTISTREAM_H */ diff --git a/engine/voice_codecs/celt/opus/opus_projection.h b/engine/voice_codecs/celt/opus/opus_projection.h new file mode 100644 index 00000000..9dabf4e8 --- /dev/null +++ b/engine/voice_codecs/celt/opus/opus_projection.h @@ -0,0 +1,568 @@ +/* Copyright (c) 2017 Google Inc. + Written by Andrew Allen */ +/* + 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. +*/ + +/** + * @file opus_projection.h + * @brief Opus projection reference API + */ + +#ifndef OPUS_PROJECTION_H +#define OPUS_PROJECTION_H + +#include "opus_multistream.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond OPUS_INTERNAL_DOC */ + +/** These are the actual encoder and decoder CTL ID numbers. + * They should not be used directly by applications.c + * In general, SETs should be even and GETs should be odd.*/ +/**@{*/ +#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN_REQUEST 6001 +#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST 6003 +#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST 6005 +/**@}*/ + + +/** @endcond */ + +/** @defgroup opus_projection_ctls Projection specific encoder and decoder CTLs + * + * These are convenience macros that are specific to the + * opus_projection_encoder_ctl() and opus_projection_decoder_ctl() + * interface. + * The CTLs from @ref opus_genericctls, @ref opus_encoderctls, + * @ref opus_decoderctls, and @ref opus_multistream_ctls may be applied to a + * projection encoder or decoder as well. + */ +/**@{*/ + +/** Gets the gain (in dB. S7.8-format) of the demixing matrix from the encoder. + * @param[out] x opus_int32 *: Returns the gain (in dB. S7.8-format) + * of the demixing matrix. + * @hideinitializer + */ +#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN(x) OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN_REQUEST, __opus_check_int_ptr(x) + + +/** Gets the size in bytes of the demixing matrix from the encoder. + * @param[out] x opus_int32 *: Returns the size in bytes of the + * demixing matrix. + * @hideinitializer + */ +#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE(x) OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST, __opus_check_int_ptr(x) + + +/** Copies the demixing matrix to the supplied pointer location. + * @param[out] x unsigned char *: Returns the demixing matrix to the + * supplied pointer location. + * @param y opus_int32: The size in bytes of the reserved memory at the + * pointer location. + * @hideinitializer + */ +#define OPUS_PROJECTION_GET_DEMIXING_MATRIX(x,y) OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST, x, __opus_check_int(y) + + +/**@}*/ + +/** Opus projection encoder state. + * This contains the complete state of a projection Opus encoder. + * It is position independent and can be freely copied. + * @see opus_projection_ambisonics_encoder_create + */ +typedef struct OpusProjectionEncoder OpusProjectionEncoder; + + +/** Opus projection decoder state. + * This contains the complete state of a projection Opus decoder. + * It is position independent and can be freely copied. + * @see opus_projection_decoder_create + * @see opus_projection_decoder_init + */ +typedef struct OpusProjectionDecoder OpusProjectionDecoder; + + +/**\name Projection encoder functions */ +/**@{*/ + +/** Gets the size of an OpusProjectionEncoder structure. + * @param channels int: The total number of input channels to encode. + * This must be no more than 255. + * @param mapping_family int: The mapping family to use for selecting + * the appropriate projection. + * @returns The size in bytes on success, or a negative error code + * (see @ref opus_errorcodes) on error. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_projection_ambisonics_encoder_get_size( + int channels, + int mapping_family +); + + +/** Allocates and initializes a projection encoder state. + * Call opus_projection_encoder_destroy() to release + * this object when finished. + * @param Fs opus_int32: Sampling rate of the input signal (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels in the input signal. + * This must be at most 255. + * It may be greater than the number of + * coded channels (streams + + * coupled_streams). + * @param mapping_family int: The mapping family to use for selecting + * the appropriate projection. + * @param[out] streams int *: The total number of streams that will + * be encoded from the input. + * @param[out] coupled_streams int *: Number of coupled (2 channel) + * streams that will be encoded from the input. + * @param application int: The target encoder application. + * This must be one of the following: + *
+ *
#OPUS_APPLICATION_VOIP
+ *
Process signal for improved speech intelligibility.
+ *
#OPUS_APPLICATION_AUDIO
+ *
Favor faithfulness to the original input.
+ *
#OPUS_APPLICATION_RESTRICTED_LOWDELAY
+ *
Configure the minimum possible coding delay by disabling certain modes + * of operation.
+ *
+ * @param[out] error int *: Returns #OPUS_OK on success, or an error + * code (see @ref opus_errorcodes) on + * failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusProjectionEncoder *opus_projection_ambisonics_encoder_create( + opus_int32 Fs, + int channels, + int mapping_family, + int *streams, + int *coupled_streams, + int application, + int *error +) OPUS_ARG_NONNULL(4) OPUS_ARG_NONNULL(5); + + +/** Initialize a previously allocated projection encoder state. + * The memory pointed to by \a st must be at least the size returned by + * opus_projection_ambisonics_encoder_get_size(). + * This is intended for applications which use their own allocator instead of + * malloc. + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. + * @see opus_projection_ambisonics_encoder_create + * @see opus_projection_ambisonics_encoder_get_size + * @param st OpusProjectionEncoder*: Projection encoder state to initialize. + * @param Fs opus_int32: Sampling rate of the input signal (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels in the input signal. + * This must be at most 255. + * It may be greater than the number of + * coded channels (streams + + * coupled_streams). + * @param streams int: The total number of streams to encode from the + * input. + * This must be no more than the number of channels. + * @param coupled_streams int: Number of coupled (2 channel) streams + * to encode. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * encoded channels (streams + + * coupled_streams) must be no + * more than the number of input channels. + * @param application int: The target encoder application. + * This must be one of the following: + *
+ *
#OPUS_APPLICATION_VOIP
+ *
Process signal for improved speech intelligibility.
+ *
#OPUS_APPLICATION_AUDIO
+ *
Favor faithfulness to the original input.
+ *
#OPUS_APPLICATION_RESTRICTED_LOWDELAY
+ *
Configure the minimum possible coding delay by disabling certain modes + * of operation.
+ *
+ * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes) + * on failure. + */ +OPUS_EXPORT int opus_projection_ambisonics_encoder_init( + OpusProjectionEncoder *st, + opus_int32 Fs, + int channels, + int mapping_family, + int *streams, + int *coupled_streams, + int application +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(5) OPUS_ARG_NONNULL(6); + + +/** Encodes a projection Opus frame. + * @param st OpusProjectionEncoder*: Projection encoder state. + * @param[in] pcm const opus_int16*: The input signal as interleaved + * samples. + * This must contain + * frame_size*channels + * samples. + * @param frame_size int: Number of samples per channel in the input + * signal. + * This must be an Opus frame size for the + * encoder's sampling rate. + * For example, at 48 kHz the permitted values + * are 120, 240, 480, 960, 1920, and 2880. + * Passing in a duration of less than 10 ms + * (480 samples at 48 kHz) will prevent the + * encoder from using the LPC or hybrid modes. + * @param[out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_encode( + OpusProjectionEncoder *st, + const opus_int16 *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + + +/** Encodes a projection Opus frame from floating point input. + * @param st OpusProjectionEncoder*: Projection encoder state. + * @param[in] pcm const float*: The input signal as interleaved + * samples with a normal range of + * +/-1.0. + * Samples with a range beyond +/-1.0 + * are supported but will be clipped by + * decoders using the integer API and + * should only be used if it is known + * that the far end supports extended + * dynamic range. + * This must contain + * frame_size*channels + * samples. + * @param frame_size int: Number of samples per channel in the input + * signal. + * This must be an Opus frame size for the + * encoder's sampling rate. + * For example, at 48 kHz the permitted values + * are 120, 240, 480, 960, 1920, and 2880. + * Passing in a duration of less than 10 ms + * (480 samples at 48 kHz) will prevent the + * encoder from using the LPC or hybrid modes. + * @param[out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_encode_float( + OpusProjectionEncoder *st, + const float *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + + +/** Frees an OpusProjectionEncoder allocated by + * opus_projection_ambisonics_encoder_create(). + * @param st OpusProjectionEncoder*: Projection encoder state to be freed. + */ +OPUS_EXPORT void opus_projection_encoder_destroy(OpusProjectionEncoder *st); + + +/** Perform a CTL function on a projection Opus encoder. + * + * Generally the request and subsequent arguments are generated by a + * convenience macro. + * @param st OpusProjectionEncoder*: Projection encoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls, + * @ref opus_encoderctls, @ref opus_multistream_ctls, or + * @ref opus_projection_ctls + * @see opus_genericctls + * @see opus_encoderctls + * @see opus_multistream_ctls + * @see opus_projection_ctls + */ +OPUS_EXPORT int opus_projection_encoder_ctl(OpusProjectionEncoder *st, int request, ...) OPUS_ARG_NONNULL(1); + + +/**@}*/ + +/**\name Projection decoder functions */ +/**@{*/ + +/** Gets the size of an OpusProjectionDecoder structure. + * @param channels int: The total number of output channels. + * This must be no more than 255. + * @param streams int: The total number of streams coded in the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number streams to decode as coupled + * (2 channel) streams. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * coded channels (streams + + * coupled_streams) must be no + * more than 255. + * @returns The size in bytes on success, or a negative error code + * (see @ref opus_errorcodes) on error. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_projection_decoder_get_size( + int channels, + int streams, + int coupled_streams +); + + +/** Allocates and initializes a projection decoder state. + * Call opus_projection_decoder_destroy() to release + * this object when finished. + * @param Fs opus_int32: Sampling rate to decode at (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels to output. + * This must be at most 255. + * It may be different from the number of coded + * channels (streams + + * coupled_streams). + * @param streams int: The total number of streams coded in the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number of streams to decode as coupled + * (2 channel) streams. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * coded channels (streams + + * coupled_streams) must be no + * more than 255. + * @param[in] demixing_matrix const unsigned char[demixing_matrix_size]: Demixing matrix + * that mapping from coded channels to output channels, + * as described in @ref opus_projection and + * @ref opus_projection_ctls. + * @param demixing_matrix_size opus_int32: The size in bytes of the + * demixing matrix, as + * described in @ref + * opus_projection_ctls. + * @param[out] error int *: Returns #OPUS_OK on success, or an error + * code (see @ref opus_errorcodes) on + * failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusProjectionDecoder *opus_projection_decoder_create( + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + unsigned char *demixing_matrix, + opus_int32 demixing_matrix_size, + int *error +) OPUS_ARG_NONNULL(5); + + +/** Intialize a previously allocated projection decoder state object. + * The memory pointed to by \a st must be at least the size returned by + * opus_projection_decoder_get_size(). + * This is intended for applications which use their own allocator instead of + * malloc. + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. + * @see opus_projection_decoder_create + * @see opus_projection_deocder_get_size + * @param st OpusProjectionDecoder*: Projection encoder state to initialize. + * @param Fs opus_int32: Sampling rate to decode at (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels to output. + * This must be at most 255. + * It may be different from the number of coded + * channels (streams + + * coupled_streams). + * @param streams int: The total number of streams coded in the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number of streams to decode as coupled + * (2 channel) streams. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * coded channels (streams + + * coupled_streams) must be no + * more than 255. + * @param[in] demixing_matrix const unsigned char[demixing_matrix_size]: Demixing matrix + * that mapping from coded channels to output channels, + * as described in @ref opus_projection and + * @ref opus_projection_ctls. + * @param demixing_matrix_size opus_int32: The size in bytes of the + * demixing matrix, as + * described in @ref + * opus_projection_ctls. + * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes) + * on failure. + */ +OPUS_EXPORT int opus_projection_decoder_init( + OpusProjectionDecoder *st, + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + unsigned char *demixing_matrix, + opus_int32 demixing_matrix_size +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6); + + +/** Decode a projection Opus packet. + * @param st OpusProjectionDecoder*: Projection decoder state. + * @param[in] data const unsigned char*: Input payload. + * Use a NULL + * pointer to indicate packet + * loss. + * @param len opus_int32: Number of bytes in payload. + * @param[out] pcm opus_int16*: Output signal, with interleaved + * samples. + * This must contain room for + * frame_size*channels + * samples. + * @param frame_size int: The number of samples per channel of + * available space in \a pcm. + * If this is less than the maximum packet duration + * (120 ms; 5760 for 48kHz), this function will not be capable + * of decoding some packets. In the case of PLC (data==NULL) + * or FEC (decode_fec=1), then frame_size needs to be exactly + * the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the + * next incoming packet. For the PLC and FEC cases, frame_size + * must be a multiple of 2.5 ms. + * @param decode_fec int: Flag (0 or 1) to request that any in-band + * forward error correction data be decoded. + * If no such data is available, the frame is + * decoded as if it were lost. + * @returns Number of samples decoded on success or a negative error code + * (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_decode( + OpusProjectionDecoder *st, + const unsigned char *data, + opus_int32 len, + opus_int16 *pcm, + int frame_size, + int decode_fec +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + + +/** Decode a projection Opus packet with floating point output. + * @param st OpusProjectionDecoder*: Projection decoder state. + * @param[in] data const unsigned char*: Input payload. + * Use a NULL + * pointer to indicate packet + * loss. + * @param len opus_int32: Number of bytes in payload. + * @param[out] pcm opus_int16*: Output signal, with interleaved + * samples. + * This must contain room for + * frame_size*channels + * samples. + * @param frame_size int: The number of samples per channel of + * available space in \a pcm. + * If this is less than the maximum packet duration + * (120 ms; 5760 for 48kHz), this function will not be capable + * of decoding some packets. In the case of PLC (data==NULL) + * or FEC (decode_fec=1), then frame_size needs to be exactly + * the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the + * next incoming packet. For the PLC and FEC cases, frame_size + * must be a multiple of 2.5 ms. + * @param decode_fec int: Flag (0 or 1) to request that any in-band + * forward error correction data be decoded. + * If no such data is available, the frame is + * decoded as if it were lost. + * @returns Number of samples decoded on success or a negative error code + * (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_decode_float( + OpusProjectionDecoder *st, + const unsigned char *data, + opus_int32 len, + float *pcm, + int frame_size, + int decode_fec +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + + +/** Perform a CTL function on a projection Opus decoder. + * + * Generally the request and subsequent arguments are generated by a + * convenience macro. + * @param st OpusProjectionDecoder*: Projection decoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls, + * @ref opus_decoderctls, @ref opus_multistream_ctls, or + * @ref opus_projection_ctls. + * @see opus_genericctls + * @see opus_decoderctls + * @see opus_multistream_ctls + * @see opus_projection_ctls + */ +OPUS_EXPORT int opus_projection_decoder_ctl(OpusProjectionDecoder *st, int request, ...) OPUS_ARG_NONNULL(1); + + +/** Frees an OpusProjectionDecoder allocated by + * opus_projection_decoder_create(). + * @param st OpusProjectionDecoder: Projection decoder state to be freed. + */ +OPUS_EXPORT void opus_projection_decoder_destroy(OpusProjectionDecoder *st); + + +/**@}*/ + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* OPUS_PROJECTION_H */ diff --git a/engine/voice_codecs/celt/opus/opus_types.h b/engine/voice_codecs/celt/opus/opus_types.h new file mode 100644 index 00000000..7cf67558 --- /dev/null +++ b/engine/voice_codecs/celt/opus/opus_types.h @@ -0,0 +1,166 @@ +/* (C) COPYRIGHT 1994-2002 Xiph.Org Foundation */ +/* Modified 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. +*/ +/* opus_types.h based on ogg_types.h from libogg */ + +/** + @file opus_types.h + @brief Opus reference implementation types +*/ +#ifndef OPUS_TYPES_H +#define OPUS_TYPES_H + +#define opus_int int /* used for counters etc; at least 16 bits */ +#define opus_int64 long long +#define opus_int8 signed char + +#define opus_uint unsigned int /* used for counters etc; at least 16 bits */ +#define opus_uint64 unsigned long long +#define opus_uint8 unsigned char + +/* Use the real stdint.h if it's there (taken from Paul Hsieh's pstdint.h) */ +#if (defined(__STDC__) && __STDC__ && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) || defined (HAVE_STDINT_H)) +#include +# undef opus_int64 +# undef opus_int8 +# undef opus_uint64 +# undef opus_uint8 + typedef int8_t opus_int8; + typedef uint8_t opus_uint8; + typedef int16_t opus_int16; + typedef uint16_t opus_uint16; + typedef int32_t opus_int32; + typedef uint32_t opus_uint32; + typedef int64_t opus_int64; + typedef uint64_t opus_uint64; +#elif defined(_WIN32) + +# if defined(__CYGWIN__) +# include <_G_config.h> + typedef _G_int32_t opus_int32; + typedef _G_uint32_t opus_uint32; + typedef _G_int16 opus_int16; + typedef _G_uint16 opus_uint16; +# elif defined(__MINGW32__) + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; +# elif defined(__MWERKS__) + typedef int opus_int32; + typedef unsigned int opus_uint32; + typedef short opus_int16; + typedef unsigned short opus_uint16; +# else + /* MSVC/Borland */ + typedef __int32 opus_int32; + typedef unsigned __int32 opus_uint32; + typedef __int16 opus_int16; + typedef unsigned __int16 opus_uint16; +# endif + +#elif defined(__MACOS__) + +# include + typedef SInt16 opus_int16; + typedef UInt16 opus_uint16; + typedef SInt32 opus_int32; + typedef UInt32 opus_uint32; + +#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ + +# include + typedef int16_t opus_int16; + typedef u_int16_t opus_uint16; + typedef int32_t opus_int32; + typedef u_int32_t opus_uint32; + +#elif defined(__BEOS__) + + /* Be */ +# include + typedef int16 opus_int16; + typedef u_int16 opus_uint16; + typedef int32_t opus_int32; + typedef u_int32_t opus_uint32; + +#elif defined (__EMX__) + + /* OS/2 GCC */ + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; + +#elif defined (DJGPP) + + /* DJGPP */ + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; + +#elif defined(R5900) + + /* PS2 EE */ + typedef int opus_int32; + typedef unsigned opus_uint32; + typedef short opus_int16; + typedef unsigned short opus_uint16; + +#elif defined(__SYMBIAN32__) + + /* Symbian GCC */ + typedef signed short opus_int16; + typedef unsigned short opus_uint16; + typedef signed int opus_int32; + typedef unsigned int opus_uint32; + +#elif defined(CONFIG_TI_C54X) || defined (CONFIG_TI_C55X) + + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef long opus_int32; + typedef unsigned long opus_uint32; + +#elif defined(CONFIG_TI_C6X) + + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; + +#else + + /* Give up, take a reasonable guess */ + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; + +#endif + +#endif /* OPUS_TYPES_H */ diff --git a/engine/voice_codecs/celt/opus/opusfile.h b/engine/voice_codecs/celt/opus/opusfile.h new file mode 100644 index 00000000..7c1c89e0 --- /dev/null +++ b/engine/voice_codecs/celt/opus/opusfile.h @@ -0,0 +1,2164 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE libopusfile SOURCE CODE IS (C) COPYRIGHT 1994-2012 * + * by the Xiph.Org Foundation and contributors https://xiph.org/ * + * * + ******************************************************************** + + function: stdio-based convenience library for opening/seeking/decoding + last mod: $Id: vorbisfile.h 17182 2010-04-29 03:48:32Z xiphmont $ + + ********************************************************************/ +#if !defined(_opusfile_h) +# define _opusfile_h (1) + +/**\mainpage + \section Introduction + + This is the documentation for the libopusfile C API. + + The libopusfile package provides a convenient high-level API for + decoding and basic manipulation of all Ogg Opus audio streams. + libopusfile is implemented as a layer on top of Xiph.Org's + reference + libogg + and + libopus + libraries. + + libopusfile provides several sets of built-in routines for + file/stream access, and may also use custom stream I/O routines provided by + the embedded environment. + There are built-in I/O routines provided for ANSI-compliant + stdio (FILE *), memory buffers, and URLs + (including URLs, plus optionally and URLs). + + \section Organization + + The main API is divided into several sections: + - \ref stream_open_close + - \ref stream_info + - \ref stream_decoding + - \ref stream_seeking + + Several additional sections are not tied to the main API. + - \ref stream_callbacks + - \ref header_info + - \ref error_codes + + \section Overview + + The libopusfile API always decodes files to 48 kHz. + The original sample rate is not preserved by the lossy compression, though + it is stored in the header to allow you to resample to it after decoding + (the libopusfile API does not currently provide a resampler, + but the + the + Speex resampler is a good choice if you need one). + In general, if you are playing back the audio, you should leave it at + 48 kHz, provided your audio hardware supports it. + When decoding to a file, it may be worth resampling back to the original + sample rate, so as not to surprise users who might not expect the sample + rate to change after encoding to Opus and decoding. + + Opus files can contain anywhere from 1 to 255 channels of audio. + The channel mappings for up to 8 channels are the same as the + Vorbis + mappings. + A special stereo API can convert everything to 2 channels, making it simple + to support multichannel files in an application which only has stereo + output. + Although the libopusfile ABI provides support for the theoretical + maximum number of channels, the current implementation does not support + files with more than 8 channels, as they do not have well-defined channel + mappings. + + Like all Ogg files, Opus files may be "chained". + That is, multiple Opus files may be combined into a single, longer file just + by concatenating the original files. + This is commonly done in internet radio streaming, as it allows the title + and artist to be updated each time the song changes, since each link in the + chain includes its own set of metadata. + + libopusfile fully supports chained files. + It will decode the first Opus stream found in each link of a chained file + (ignoring any other streams that might be concurrently multiplexed with it, + such as a video stream). + + The channel count can also change between links. + If your application is not prepared to deal with this, it can use the stereo + API to ensure the audio from all links will always get decoded into a + common format. + Since libopusfile always decodes to 48 kHz, you do not have to + worry about the sample rate changing between links (as was possible with + Vorbis). + This makes application support for chained files with libopusfile + very easy.*/ + +# if defined(__cplusplus) +extern "C" { +# endif + +# include +# include +# include +# include + +/**@cond PRIVATE*/ + +/*Enable special features for gcc and gcc-compatible compilers.*/ +# if !defined(OP_GNUC_PREREQ) +# if defined(__GNUC__)&&defined(__GNUC_MINOR__) +# define OP_GNUC_PREREQ(_maj,_min) \ + ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min)) +# else +# define OP_GNUC_PREREQ(_maj,_min) 0 +# endif +# endif + +# if OP_GNUC_PREREQ(4,0) +# pragma GCC visibility push(default) +# endif + +typedef struct OpusHead OpusHead; +typedef struct OpusTags OpusTags; +typedef struct OpusPictureTag OpusPictureTag; +typedef struct OpusServerInfo OpusServerInfo; +typedef struct OpusFileCallbacks OpusFileCallbacks; +typedef struct OggOpusFile OggOpusFile; + +/*Warning attributes for libopusfile functions.*/ +# if OP_GNUC_PREREQ(3,4) +# define OP_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) +# else +# define OP_WARN_UNUSED_RESULT +# endif +# if OP_GNUC_PREREQ(3,4) +# define OP_ARG_NONNULL(_x) __attribute__((__nonnull__(_x))) +# else +# define OP_ARG_NONNULL(_x) +# endif + +/**@endcond*/ + +/**\defgroup error_codes Error Codes*/ +/*@{*/ +/**\name List of possible error codes + Many of the functions in this library return a negative error code when a + function fails. + This list provides a brief explanation of the common errors. + See each individual function for more details on what a specific error code + means in that context.*/ +/*@{*/ + +/**A request did not succeed.*/ +#define OP_FALSE (-1) +/*Currently not used externally.*/ +#define OP_EOF (-2) +/**There was a hole in the page sequence numbers (e.g., a page was corrupt or + missing).*/ +#define OP_HOLE (-3) +/**An underlying read, seek, or tell operation failed when it should have + succeeded.*/ +#define OP_EREAD (-128) +/**A NULL pointer was passed where one was unexpected, or an + internal memory allocation failed, or an internal library error was + encountered.*/ +#define OP_EFAULT (-129) +/**The stream used a feature that is not implemented, such as an unsupported + channel family.*/ +#define OP_EIMPL (-130) +/**One or more parameters to a function were invalid.*/ +#define OP_EINVAL (-131) +/**A purported Ogg Opus stream did not begin with an Ogg page, a purported + header packet did not start with one of the required strings, "OpusHead" or + "OpusTags", or a link in a chained file was encountered that did not + contain any logical Opus streams.*/ +#define OP_ENOTFORMAT (-132) +/**A required header packet was not properly formatted, contained illegal + values, or was missing altogether.*/ +#define OP_EBADHEADER (-133) +/**The ID header contained an unrecognized version number.*/ +#define OP_EVERSION (-134) +/*Currently not used at all.*/ +#define OP_ENOTAUDIO (-135) +/**An audio packet failed to decode properly. + This is usually caused by a multistream Ogg packet where the durations of + the individual Opus packets contained in it are not all the same.*/ +#define OP_EBADPACKET (-136) +/**We failed to find data we had seen before, or the bitstream structure was + sufficiently malformed that seeking to the target destination was + impossible.*/ +#define OP_EBADLINK (-137) +/**An operation that requires seeking was requested on an unseekable stream.*/ +#define OP_ENOSEEK (-138) +/**The first or last granule position of a link failed basic validity checks.*/ +#define OP_EBADTIMESTAMP (-139) + +/*@}*/ +/*@}*/ + +/**\defgroup header_info Header Information*/ +/*@{*/ + +/**The maximum number of channels in an Ogg Opus stream.*/ +#define OPUS_CHANNEL_COUNT_MAX (255) + +/**Ogg Opus bitstream information. + This contains the basic playback parameters for a stream, and corresponds to + the initial ID header packet of an Ogg Opus stream.*/ +struct OpusHead{ + /**The Ogg Opus format version, in the range 0...255. + The top 4 bits represent a "major" version, and the bottom four bits + represent backwards-compatible "minor" revisions. + The current specification describes version 1. + This library will recognize versions up through 15 as backwards compatible + with the current specification. + An earlier draft of the specification described a version 0, but the only + difference between version 1 and version 0 is that version 0 did + not specify the semantics for handling the version field.*/ + int version; + /**The number of channels, in the range 1...255.*/ + int channel_count; + /**The number of samples that should be discarded from the beginning of the + stream.*/ + unsigned pre_skip; + /**The sampling rate of the original input. + All Opus audio is coded at 48 kHz, and should also be decoded at 48 kHz + for playback (unless the target hardware does not support this sampling + rate). + However, this field may be used to resample the audio back to the original + sampling rate, for example, when saving the output to a file.*/ + opus_uint32 input_sample_rate; + /**The gain to apply to the decoded output, in dB, as a Q8 value in the range + -32768...32767. + The libopusfile API will automatically apply this gain to the + decoded output before returning it, scaling it by + pow(10,output_gain/(20.0*256)). + You can adjust this behavior with op_set_gain_offset().*/ + int output_gain; + /**The channel mapping family, in the range 0...255. + Channel mapping family 0 covers mono or stereo in a single stream. + Channel mapping family 1 covers 1 to 8 channels in one or more streams, + using the Vorbis speaker assignments. + Channel mapping family 255 covers 1 to 255 channels in one or more + streams, but without any defined speaker assignment.*/ + int mapping_family; + /**The number of Opus streams in each Ogg packet, in the range 1...255.*/ + int stream_count; + /**The number of coupled Opus streams in each Ogg packet, in the range + 0...127. + This must satisfy 0 <= coupled_count <= stream_count and + coupled_count + stream_count <= 255. + The coupled streams appear first, before all uncoupled streams, in an Ogg + Opus packet.*/ + int coupled_count; + /**The mapping from coded stream channels to output channels. + Let index=mapping[k] be the value for channel k. + If index<2*coupled_count, then it refers to the left channel + from stream (index/2) if even, and the right channel from + stream (index/2) if odd. + Otherwise, it refers to the output of the uncoupled stream + (index-coupled_count).*/ + unsigned char mapping[OPUS_CHANNEL_COUNT_MAX]; +}; + +/**The metadata from an Ogg Opus stream. + + This structure holds the in-stream metadata corresponding to the 'comment' + header packet of an Ogg Opus stream. + The comment header is meant to be used much like someone jotting a quick + note on the label of a CD. + It should be a short, to the point text note that can be more than a couple + words, but not more than a short paragraph. + + The metadata is stored as a series of (tag, value) pairs, in length-encoded + string vectors, using the same format as Vorbis (without the final "framing + bit"), Theora, and Speex, except for the packet header. + The first occurrence of the '=' character delimits the tag and value. + A particular tag may occur more than once, and order is significant. + The character set encoding for the strings is always UTF-8, but the tag + names are limited to ASCII, and treated as case-insensitive. + See the Vorbis + comment header specification for details. + + In filling in this structure, libopusfile will null-terminate the + #user_comments strings for safety. + However, the bitstream format itself treats them as 8-bit clean vectors, + possibly containing NUL characters, so the #comment_lengths array should be + treated as their authoritative length. + + This structure is binary and source-compatible with a + vorbis_comment, and pointers to it may be freely cast to + vorbis_comment pointers, and vice versa. + It is provided as a separate type to avoid introducing a compile-time + dependency on the libvorbis headers.*/ +struct OpusTags{ + /**The array of comment string vectors.*/ + char **user_comments; + /**An array of the corresponding length of each vector, in bytes.*/ + int *comment_lengths; + /**The total number of comment streams.*/ + int comments; + /**The null-terminated vendor string. + This identifies the software used to encode the stream.*/ + char *vendor; +}; + +/**\name Picture tag image formats*/ +/*@{*/ + +/**The MIME type was not recognized, or the image data did not match the + declared MIME type.*/ +#define OP_PIC_FORMAT_UNKNOWN (-1) +/**The MIME type indicates the image data is really a URL.*/ +#define OP_PIC_FORMAT_URL (0) +/**The image is a JPEG.*/ +#define OP_PIC_FORMAT_JPEG (1) +/**The image is a PNG.*/ +#define OP_PIC_FORMAT_PNG (2) +/**The image is a GIF.*/ +#define OP_PIC_FORMAT_GIF (3) + +/*@}*/ + +/**The contents of a METADATA_BLOCK_PICTURE tag.*/ +struct OpusPictureTag{ + /**The picture type according to the ID3v2 APIC frame: +
    +
  1. Other
  2. +
  3. 32x32 pixels 'file icon' (PNG only)
  4. +
  5. Other file icon
  6. +
  7. Cover (front)
  8. +
  9. Cover (back)
  10. +
  11. Leaflet page
  12. +
  13. Media (e.g. label side of CD)
  14. +
  15. Lead artist/lead performer/soloist
  16. +
  17. Artist/performer
  18. +
  19. Conductor
  20. +
  21. Band/Orchestra
  22. +
  23. Composer
  24. +
  25. Lyricist/text writer
  26. +
  27. Recording Location
  28. +
  29. During recording
  30. +
  31. During performance
  32. +
  33. Movie/video screen capture
  34. +
  35. A bright colored fish
  36. +
  37. Illustration
  38. +
  39. Band/artist logotype
  40. +
  41. Publisher/Studio logotype
  42. +
+ Others are reserved and should not be used. + There may only be one each of picture type 1 and 2 in a file.*/ + opus_int32 type; + /**The MIME type of the picture, in printable ASCII characters 0x20-0x7E. + The MIME type may also be "-->" to signify that the data part + is a URL pointing to the picture instead of the picture data itself. + In this case, a terminating NUL is appended to the URL string in #data, + but #data_length is set to the length of the string excluding that + terminating NUL.*/ + char *mime_type; + /**The description of the picture, in UTF-8.*/ + char *description; + /**The width of the picture in pixels.*/ + opus_uint32 width; + /**The height of the picture in pixels.*/ + opus_uint32 height; + /**The color depth of the picture in bits-per-pixel (not + bits-per-channel).*/ + opus_uint32 depth; + /**For indexed-color pictures (e.g., GIF), the number of colors used, or 0 + for non-indexed pictures.*/ + opus_uint32 colors; + /**The length of the picture data in bytes.*/ + opus_uint32 data_length; + /**The binary picture data.*/ + unsigned char *data; + /**The format of the picture data, if known. + One of +
    +
  • #OP_PIC_FORMAT_UNKNOWN,
  • +
  • #OP_PIC_FORMAT_URL,
  • +
  • #OP_PIC_FORMAT_JPEG,
  • +
  • #OP_PIC_FORMAT_PNG, or
  • +
  • #OP_PIC_FORMAT_GIF.
  • +
*/ + int format; +}; + +/**\name Functions for manipulating header data + + These functions manipulate the #OpusHead and #OpusTags structures, + which describe the audio parameters and tag-value metadata, respectively. + These can be used to query the headers returned by libopusfile, or + to parse Opus headers from sources other than an Ogg Opus stream, provided + they use the same format.*/ +/*@{*/ + +/**Parses the contents of the ID header packet of an Ogg Opus stream. + \param[out] _head Returns the contents of the parsed packet. + The contents of this structure are untouched on error. + This may be NULL to merely test the header + for validity. + \param[in] _data The contents of the ID header packet. + \param _len The number of bytes of data in the ID header packet. + \return 0 on success or a negative value on error. + \retval #OP_ENOTFORMAT If the data does not start with the "OpusHead" + string. + \retval #OP_EVERSION If the version field signaled a version this library + does not know how to parse. + \retval #OP_EIMPL If the channel mapping family was 255, which general + purpose players should not attempt to play. + \retval #OP_EBADHEADER If the contents of the packet otherwise violate the + Ogg Opus specification: +
    +
  • Insufficient data,
  • +
  • Too much data for the known minor versions,
  • +
  • An unrecognized channel mapping family,
  • +
  • Zero channels or too many channels,
  • +
  • Zero coded streams,
  • +
  • Too many coupled streams, or
  • +
  • An invalid channel mapping index.
  • +
*/ +OP_WARN_UNUSED_RESULT int opus_head_parse(OpusHead *_head, + const unsigned char *_data,size_t _len) OP_ARG_NONNULL(2); + +/**Converts a granule position to a sample offset for a given Ogg Opus stream. + The sample offset is simply _gp-_head->pre_skip. + Granule position values smaller than OpusHead#pre_skip correspond to audio + that should never be played, and thus have no associated sample offset. + This function returns -1 for such values. + This function also correctly handles extremely large granule positions, + which may have wrapped around to a negative number when stored in a signed + ogg_int64_t value. + \param _head The #OpusHead information from the ID header of the stream. + \param _gp The granule position to convert. + \return The sample offset associated with the given granule position + (counting at a 48 kHz sampling rate), or the special value -1 on + error (i.e., the granule position was smaller than the pre-skip + amount).*/ +ogg_int64_t opus_granule_sample(const OpusHead *_head,ogg_int64_t _gp) + OP_ARG_NONNULL(1); + +/**Parses the contents of the 'comment' header packet of an Ogg Opus stream. + \param[out] _tags An uninitialized #OpusTags structure. + This returns the contents of the parsed packet. + The contents of this structure are untouched on error. + This may be NULL to merely test the header + for validity. + \param[in] _data The contents of the 'comment' header packet. + \param _len The number of bytes of data in the 'info' header packet. + \retval 0 Success. + \retval #OP_ENOTFORMAT If the data does not start with the "OpusTags" + string. + \retval #OP_EBADHEADER If the contents of the packet otherwise violate the + Ogg Opus specification. + \retval #OP_EFAULT If there wasn't enough memory to store the tags.*/ +OP_WARN_UNUSED_RESULT int opus_tags_parse(OpusTags *_tags, + const unsigned char *_data,size_t _len) OP_ARG_NONNULL(2); + +/**Performs a deep copy of an #OpusTags structure. + \param _dst The #OpusTags structure to copy into. + If this function fails, the contents of this structure remain + untouched. + \param _src The #OpusTags structure to copy from. + \retval 0 Success. + \retval #OP_EFAULT If there wasn't enough memory to copy the tags.*/ +int opus_tags_copy(OpusTags *_dst,const OpusTags *_src) OP_ARG_NONNULL(1); + +/**Initializes an #OpusTags structure. + This should be called on a freshly allocated #OpusTags structure before + attempting to use it. + \param _tags The #OpusTags structure to initialize.*/ +void opus_tags_init(OpusTags *_tags) OP_ARG_NONNULL(1); + +/**Add a (tag, value) pair to an initialized #OpusTags structure. + \note Neither opus_tags_add() nor opus_tags_add_comment() support values + containing embedded NULs, although the bitstream format does support them. + To add such tags, you will need to manipulate the #OpusTags structure + directly. + \param _tags The #OpusTags structure to add the (tag, value) pair to. + \param _tag A NUL-terminated, case-insensitive, ASCII string containing + the tag to add (without an '=' character). + \param _value A NUL-terminated UTF-8 containing the corresponding value. + \return 0 on success, or a negative value on failure. + \retval #OP_EFAULT An internal memory allocation failed.*/ +int opus_tags_add(OpusTags *_tags,const char *_tag,const char *_value) + OP_ARG_NONNULL(1) OP_ARG_NONNULL(2) OP_ARG_NONNULL(3); + +/**Add a comment to an initialized #OpusTags structure. + \note Neither opus_tags_add_comment() nor opus_tags_add() support comments + containing embedded NULs, although the bitstream format does support them. + To add such tags, you will need to manipulate the #OpusTags structure + directly. + \param _tags The #OpusTags structure to add the comment to. + \param _comment A NUL-terminated UTF-8 string containing the comment in + "TAG=value" form. + \return 0 on success, or a negative value on failure. + \retval #OP_EFAULT An internal memory allocation failed.*/ +int opus_tags_add_comment(OpusTags *_tags,const char *_comment) + OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); + +/**Replace the binary suffix data at the end of the packet (if any). + \param _tags An initialized #OpusTags structure. + \param _data A buffer of binary data to append after the encoded user + comments. + The least significant bit of the first byte of this data must + be set (to ensure the data is preserved by other editors). + \param _len The number of bytes of binary data to append. + This may be zero to remove any existing binary suffix data. + \return 0 on success, or a negative value on error. + \retval #OP_EINVAL \a _len was negative, or \a _len was positive but + \a _data was NULL or the least significant + bit of the first byte was not set. + \retval #OP_EFAULT An internal memory allocation failed.*/ +int opus_tags_set_binary_suffix(OpusTags *_tags, + const unsigned char *_data,int _len) OP_ARG_NONNULL(1); + +/**Look up a comment value by its tag. + \param _tags An initialized #OpusTags structure. + \param _tag The tag to look up. + \param _count The instance of the tag. + The same tag can appear multiple times, each with a distinct + value, so an index is required to retrieve them all. + The order in which these values appear is significant and + should be preserved. + Use opus_tags_query_count() to get the legal range for the + \a _count parameter. + \return A pointer to the queried tag's value. + This points directly to data in the #OpusTags structure. + It should not be modified or freed by the application, and + modifications to the structure may invalidate the pointer. + \retval NULL If no matching tag is found.*/ +const char *opus_tags_query(const OpusTags *_tags,const char *_tag,int _count) + OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); + +/**Look up the number of instances of a tag. + Call this first when querying for a specific tag and then iterate over the + number of instances with separate calls to opus_tags_query() to retrieve + all the values for that tag in order. + \param _tags An initialized #OpusTags structure. + \param _tag The tag to look up. + \return The number of instances of this particular tag.*/ +int opus_tags_query_count(const OpusTags *_tags,const char *_tag) + OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); + +/**Retrieve the binary suffix data at the end of the packet (if any). + \param _tags An initialized #OpusTags structure. + \param[out] _len Returns the number of bytes of binary suffix data returned. + \return A pointer to the binary suffix data, or NULL if none + was present.*/ +const unsigned char *opus_tags_get_binary_suffix(const OpusTags *_tags, + int *_len) OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); + +/**Get the album gain from an R128_ALBUM_GAIN tag, if one was specified. + This searches for the first R128_ALBUM_GAIN tag with a valid signed, + 16-bit decimal integer value and returns the value. + This routine is exposed merely for convenience for applications which wish + to do something special with the album gain (i.e., display it). + If you simply wish to apply the album gain instead of the header gain, you + can use op_set_gain_offset() with an #OP_ALBUM_GAIN type and no offset. + \param _tags An initialized #OpusTags structure. + \param[out] _gain_q8 The album gain, in 1/256ths of a dB. + This will lie in the range [-32768,32767], and should + be applied in addition to the header gain. + On error, no value is returned, and the previous + contents remain unchanged. + \return 0 on success, or a negative value on error. + \retval #OP_FALSE There was no album gain available in the given tags.*/ +int opus_tags_get_album_gain(const OpusTags *_tags,int *_gain_q8) + OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); + +/**Get the track gain from an R128_TRACK_GAIN tag, if one was specified. + This searches for the first R128_TRACK_GAIN tag with a valid signed, + 16-bit decimal integer value and returns the value. + This routine is exposed merely for convenience for applications which wish + to do something special with the track gain (i.e., display it). + If you simply wish to apply the track gain instead of the header gain, you + can use op_set_gain_offset() with an #OP_TRACK_GAIN type and no offset. + \param _tags An initialized #OpusTags structure. + \param[out] _gain_q8 The track gain, in 1/256ths of a dB. + This will lie in the range [-32768,32767], and should + be applied in addition to the header gain. + On error, no value is returned, and the previous + contents remain unchanged. + \return 0 on success, or a negative value on error. + \retval #OP_FALSE There was no track gain available in the given tags.*/ +int opus_tags_get_track_gain(const OpusTags *_tags,int *_gain_q8) + OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); + +/**Clears the #OpusTags structure. + This should be called on an #OpusTags structure after it is no longer + needed. + It will free all memory used by the structure members. + \param _tags The #OpusTags structure to clear.*/ +void opus_tags_clear(OpusTags *_tags) OP_ARG_NONNULL(1); + +/**Check if \a _comment is an instance of a \a _tag_name tag. + \see opus_tagncompare + \param _tag_name A NUL-terminated, case-insensitive, ASCII string containing + the name of the tag to check for (without the terminating + '=' character). + \param _comment The comment string to check. + \return An integer less than, equal to, or greater than zero if \a _comment + is found respectively, to be less than, to match, or be greater + than a "tag=value" string whose tag matches \a _tag_name.*/ +int opus_tagcompare(const char *_tag_name,const char *_comment); + +/**Check if \a _comment is an instance of a \a _tag_name tag. + This version is slightly more efficient than opus_tagcompare() if the length + of the tag name is already known (e.g., because it is a constant). + \see opus_tagcompare + \param _tag_name A case-insensitive ASCII string containing the name of the + tag to check for (without the terminating '=' character). + \param _tag_len The number of characters in the tag name. + This must be non-negative. + \param _comment The comment string to check. + \return An integer less than, equal to, or greater than zero if \a _comment + is found respectively, to be less than, to match, or be greater + than a "tag=value" string whose tag matches the first \a _tag_len + characters of \a _tag_name.*/ +int opus_tagncompare(const char *_tag_name,int _tag_len,const char *_comment); + +/**Parse a single METADATA_BLOCK_PICTURE tag. + This decodes the BASE64-encoded content of the tag and returns a structure + with the MIME type, description, image parameters (if known), and the + compressed image data. + If the MIME type indicates the presence of an image format we recognize + (JPEG, PNG, or GIF) and the actual image data contains the magic signature + associated with that format, then the OpusPictureTag::format field will be + set to the corresponding format. + This is provided as a convenience to avoid requiring applications to parse + the MIME type and/or do their own format detection for the commonly used + formats. + In this case, we also attempt to extract the image parameters directly from + the image data (overriding any that were present in the tag, which the + specification says applications are not meant to rely on). + The application must still provide its own support for actually decoding the + image data and, if applicable, retrieving that data from URLs. + \param[out] _pic Returns the parsed picture data. + No sanitation is done on the type, MIME type, or + description fields, so these might return invalid values. + The contents of this structure are left unmodified on + failure. + \param _tag The METADATA_BLOCK_PICTURE tag contents. + The leading "METADATA_BLOCK_PICTURE=" portion is optional, + to allow the function to be used on either directly on the + values in OpusTags::user_comments or on the return value + of opus_tags_query(). + \return 0 on success or a negative value on error. + \retval #OP_ENOTFORMAT The METADATA_BLOCK_PICTURE contents were not valid. + \retval #OP_EFAULT There was not enough memory to store the picture tag + contents.*/ +OP_WARN_UNUSED_RESULT int opus_picture_tag_parse(OpusPictureTag *_pic, + const char *_tag) OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); + +/**Initializes an #OpusPictureTag structure. + This should be called on a freshly allocated #OpusPictureTag structure + before attempting to use it. + \param _pic The #OpusPictureTag structure to initialize.*/ +void opus_picture_tag_init(OpusPictureTag *_pic) OP_ARG_NONNULL(1); + +/**Clears the #OpusPictureTag structure. + This should be called on an #OpusPictureTag structure after it is no longer + needed. + It will free all memory used by the structure members. + \param _pic The #OpusPictureTag structure to clear.*/ +void opus_picture_tag_clear(OpusPictureTag *_pic) OP_ARG_NONNULL(1); + +/*@}*/ + +/*@}*/ + +/**\defgroup url_options URL Reading Options*/ +/*@{*/ +/**\name URL reading options + Options for op_url_stream_create() and associated functions. + These allow you to provide proxy configuration parameters, skip SSL + certificate checks, etc. + Options are processed in order, and if the same option is passed multiple + times, only the value specified by the last occurrence has an effect + (unless otherwise specified). + They may be expanded in the future.*/ +/*@{*/ + +/**@cond PRIVATE*/ + +/*These are the raw numbers used to define the request codes. + They should not be used directly.*/ +#define OP_SSL_SKIP_CERTIFICATE_CHECK_REQUEST (6464) +#define OP_HTTP_PROXY_HOST_REQUEST (6528) +#define OP_HTTP_PROXY_PORT_REQUEST (6592) +#define OP_HTTP_PROXY_USER_REQUEST (6656) +#define OP_HTTP_PROXY_PASS_REQUEST (6720) +#define OP_GET_SERVER_INFO_REQUEST (6784) + +#define OP_URL_OPT(_request) ((char *)(_request)) + +/*These macros trigger compilation errors or warnings if the wrong types are + provided to one of the URL options.*/ +#define OP_CHECK_INT(_x) ((void)((_x)==(opus_int32)0),(opus_int32)(_x)) +#define OP_CHECK_CONST_CHAR_PTR(_x) ((_x)+((_x)-(const char *)(_x))) +#define OP_CHECK_SERVER_INFO_PTR(_x) ((_x)+((_x)-(OpusServerInfo *)(_x))) + +/**@endcond*/ + +/**HTTP/Shoutcast/Icecast server information associated with a URL.*/ +struct OpusServerInfo{ + /**The name of the server (icy-name/ice-name). + This is NULL if there was no icy-name or + ice-name header.*/ + char *name; + /**A short description of the server (icy-description/ice-description). + This is NULL if there was no icy-description or + ice-description header.*/ + char *description; + /**The genre the server falls under (icy-genre/ice-genre). + This is NULL if there was no icy-genre or + ice-genre header.*/ + char *genre; + /**The homepage for the server (icy-url/ice-url). + This is NULL if there was no icy-url or + ice-url header.*/ + char *url; + /**The software used by the origin server (Server). + This is NULL if there was no Server header.*/ + char *server; + /**The media type of the entity sent to the recepient (Content-Type). + This is NULL if there was no Content-Type + header.*/ + char *content_type; + /**The nominal stream bitrate in kbps (icy-br/ice-bitrate). + This is -1 if there was no icy-br or + ice-bitrate header.*/ + opus_int32 bitrate_kbps; + /**Flag indicating whether the server is public (1) or not + (0) (icy-pub/ice-public). + This is -1 if there was no icy-pub or + ice-public header.*/ + int is_public; + /**Flag indicating whether the server is using HTTPS instead of HTTP. + This is 0 unless HTTPS is being used. + This may not match the protocol used in the original URL if there were + redirections.*/ + int is_ssl; +}; + +/**Initializes an #OpusServerInfo structure. + All fields are set as if the corresponding header was not available. + \param _info The #OpusServerInfo structure to initialize. + \note If you use this function, you must link against libopusurl.*/ +void opus_server_info_init(OpusServerInfo *_info) OP_ARG_NONNULL(1); + +/**Clears the #OpusServerInfo structure. + This should be called on an #OpusServerInfo structure after it is no longer + needed. + It will free all memory used by the structure members. + \param _info The #OpusServerInfo structure to clear. + \note If you use this function, you must link against libopusurl.*/ +void opus_server_info_clear(OpusServerInfo *_info) OP_ARG_NONNULL(1); + +/**Skip the certificate check when connecting via TLS/SSL (https). + \param _b opus_int32: Whether or not to skip the certificate + check. + The check will be skipped if \a _b is non-zero, and will not be + skipped if \a _b is zero. + \hideinitializer*/ +#define OP_SSL_SKIP_CERTIFICATE_CHECK(_b) \ + OP_URL_OPT(OP_SSL_SKIP_CERTIFICATE_CHECK_REQUEST),OP_CHECK_INT(_b) + +/**Proxy connections through the given host. + If no port is specified via #OP_HTTP_PROXY_PORT, the port number defaults + to 8080 (http-alt). + All proxy parameters are ignored for non-http and non-https URLs. + \param _host const char *: The proxy server hostname. + This may be NULL to disable the use of a proxy + server. + \hideinitializer*/ +#define OP_HTTP_PROXY_HOST(_host) \ + OP_URL_OPT(OP_HTTP_PROXY_HOST_REQUEST),OP_CHECK_CONST_CHAR_PTR(_host) + +/**Use the given port when proxying connections. + This option only has an effect if #OP_HTTP_PROXY_HOST is specified with a + non-NULL \a _host. + If this option is not provided, the proxy port number defaults to 8080 + (http-alt). + All proxy parameters are ignored for non-http and non-https URLs. + \param _port opus_int32: The proxy server port. + This must be in the range 0...65535 (inclusive), or the + URL function this is passed to will fail. + \hideinitializer*/ +#define OP_HTTP_PROXY_PORT(_port) \ + OP_URL_OPT(OP_HTTP_PROXY_PORT_REQUEST),OP_CHECK_INT(_port) + +/**Use the given user name for authentication when proxying connections. + All proxy parameters are ignored for non-http and non-https URLs. + \param _user const char *: The proxy server user name. + This may be NULL to disable proxy + authentication. + A non-NULL value only has an effect + if #OP_HTTP_PROXY_HOST and #OP_HTTP_PROXY_PASS + are also specified with non-NULL + arguments. + \hideinitializer*/ +#define OP_HTTP_PROXY_USER(_user) \ + OP_URL_OPT(OP_HTTP_PROXY_USER_REQUEST),OP_CHECK_CONST_CHAR_PTR(_user) + +/**Use the given password for authentication when proxying connections. + All proxy parameters are ignored for non-http and non-https URLs. + \param _pass const char *: The proxy server password. + This may be NULL to disable proxy + authentication. + A non-NULL value only has an effect + if #OP_HTTP_PROXY_HOST and #OP_HTTP_PROXY_USER + are also specified with non-NULL + arguments. + \hideinitializer*/ +#define OP_HTTP_PROXY_PASS(_pass) \ + OP_URL_OPT(OP_HTTP_PROXY_PASS_REQUEST),OP_CHECK_CONST_CHAR_PTR(_pass) + +/**Parse information about the streaming server (if any) and return it. + Very little validation is done. + In particular, OpusServerInfo::url may not be a valid URL, + OpusServerInfo::bitrate_kbps may not really be in kbps, and + OpusServerInfo::content_type may not be a valid MIME type. + The character set of the string fields is not specified anywhere, and should + not be assumed to be valid UTF-8. + \param _info OpusServerInfo *: Returns information about the server. + If there is any error opening the stream, the + contents of this structure remain + unmodified. + On success, fills in the structure with the + server information that was available, if + any. + After a successful return, the contents of + this structure should be freed by calling + opus_server_info_clear(). + \hideinitializer*/ +#define OP_GET_SERVER_INFO(_info) \ + OP_URL_OPT(OP_GET_SERVER_INFO_REQUEST),OP_CHECK_SERVER_INFO_PTR(_info) + +/*@}*/ +/*@}*/ + +/**\defgroup stream_callbacks Abstract Stream Reading Interface*/ +/*@{*/ +/**\name Functions for reading from streams + These functions define the interface used to read from and seek in a stream + of data. + A stream does not need to implement seeking, but the decoder will not be + able to seek if it does not do so. + These functions also include some convenience routines for working with + standard FILE pointers, complete streams stored in a single + block of memory, or URLs.*/ +/*@{*/ + +/**Reads up to \a _nbytes bytes of data from \a _stream. + \param _stream The stream to read from. + \param[out] _ptr The buffer to store the data in. + \param _nbytes The maximum number of bytes to read. + This function may return fewer, though it will not + return zero unless it reaches end-of-file. + \return The number of bytes successfully read, or a negative value on + error.*/ +typedef int (*op_read_func)(void *_stream,unsigned char *_ptr,int _nbytes); + +/**Sets the position indicator for \a _stream. + The new position, measured in bytes, is obtained by adding \a _offset + bytes to the position specified by \a _whence. + If \a _whence is set to SEEK_SET, SEEK_CUR, or + SEEK_END, the offset is relative to the start of the stream, + the current position indicator, or end-of-file, respectively. + \retval 0 Success. + \retval -1 Seeking is not supported or an error occurred. + errno need not be set.*/ +typedef int (*op_seek_func)(void *_stream,opus_int64 _offset,int _whence); + +/**Obtains the current value of the position indicator for \a _stream. + \return The current position indicator.*/ +typedef opus_int64 (*op_tell_func)(void *_stream); + +/**Closes the underlying stream. + \retval 0 Success. + \retval EOF An error occurred. + errno need not be set.*/ +typedef int (*op_close_func)(void *_stream); + +/**The callbacks used to access non-FILE stream resources. + The function prototypes are basically the same as for the stdio functions + fread(), fseek(), ftell(), and + fclose(). + The differences are that the FILE * arguments have been + replaced with a void *, which is to be used as a pointer to + whatever internal data these functions might need, that #seek and #tell + take and return 64-bit offsets, and that #seek must return -1 if + the stream is unseekable.*/ +struct OpusFileCallbacks{ + /**Used to read data from the stream. + This must not be NULL.*/ + op_read_func read; + /**Used to seek in the stream. + This may be NULL if seeking is not implemented.*/ + op_seek_func seek; + /**Used to return the current read position in the stream. + This may be NULL if seeking is not implemented.*/ + op_tell_func tell; + /**Used to close the stream when the decoder is freed. + This may be NULL to leave the stream open.*/ + op_close_func close; +}; + +/**Opens a stream with fopen() and fills in a set of callbacks + that can be used to access it. + This is useful to avoid writing your own portable 64-bit seeking wrappers, + and also avoids cross-module linking issues on Windows, where a + FILE * must be accessed by routines defined in the same module + that opened it. + \param[out] _cb The callbacks to use for this file. + If there is an error opening the file, nothing will be + filled in here. + \param _path The path to the file to open. + On Windows, this string must be UTF-8 (to allow access to + files whose names cannot be represented in the current + MBCS code page). + All other systems use the native character encoding. + \param _mode The mode to open the file in. + \return A stream handle to use with the callbacks, or NULL on + error.*/ +OP_WARN_UNUSED_RESULT void *op_fopen(OpusFileCallbacks *_cb, + const char *_path,const char *_mode) OP_ARG_NONNULL(1) OP_ARG_NONNULL(2) + OP_ARG_NONNULL(3); + +/**Opens a stream with fdopen() and fills in a set of callbacks + that can be used to access it. + This is useful to avoid writing your own portable 64-bit seeking wrappers, + and also avoids cross-module linking issues on Windows, where a + FILE * must be accessed by routines defined in the same module + that opened it. + \param[out] _cb The callbacks to use for this file. + If there is an error opening the file, nothing will be + filled in here. + \param _fd The file descriptor to open. + \param _mode The mode to open the file in. + \return A stream handle to use with the callbacks, or NULL on + error.*/ +OP_WARN_UNUSED_RESULT void *op_fdopen(OpusFileCallbacks *_cb, + int _fd,const char *_mode) OP_ARG_NONNULL(1) OP_ARG_NONNULL(3); + +/**Opens a stream with freopen() and fills in a set of callbacks + that can be used to access it. + This is useful to avoid writing your own portable 64-bit seeking wrappers, + and also avoids cross-module linking issues on Windows, where a + FILE * must be accessed by routines defined in the same module + that opened it. + \param[out] _cb The callbacks to use for this file. + If there is an error opening the file, nothing will be + filled in here. + \param _path The path to the file to open. + On Windows, this string must be UTF-8 (to allow access + to files whose names cannot be represented in the + current MBCS code page). + All other systems use the native character encoding. + \param _mode The mode to open the file in. + \param _stream A stream previously returned by op_fopen(), op_fdopen(), + or op_freopen(). + \return A stream handle to use with the callbacks, or NULL on + error.*/ +OP_WARN_UNUSED_RESULT void *op_freopen(OpusFileCallbacks *_cb, + const char *_path,const char *_mode,void *_stream) OP_ARG_NONNULL(1) + OP_ARG_NONNULL(2) OP_ARG_NONNULL(3) OP_ARG_NONNULL(4); + +/**Creates a stream that reads from the given block of memory. + This block of memory must contain the complete stream to decode. + This is useful for caching small streams (e.g., sound effects) in RAM. + \param[out] _cb The callbacks to use for this stream. + If there is an error creating the stream, nothing will be + filled in here. + \param _data The block of memory to read from. + \param _size The size of the block of memory. + \return A stream handle to use with the callbacks, or NULL on + error.*/ +OP_WARN_UNUSED_RESULT void *op_mem_stream_create(OpusFileCallbacks *_cb, + const unsigned char *_data,size_t _size) OP_ARG_NONNULL(1); + +/**Creates a stream that reads from the given URL. + This function behaves identically to op_url_stream_create(), except that it + takes a va_list instead of a variable number of arguments. + It does not call the va_end macro, and because it invokes the + va_arg macro, the value of \a _ap is undefined after the call. + \note If you use this function, you must link against libopusurl. + \param[out] _cb The callbacks to use for this stream. + If there is an error creating the stream, nothing will + be filled in here. + \param _url The URL to read from. + Currently only the , , and + schemes are supported. + Both and may be disabled at compile + time, in which case opening such URLs will always fail. + Currently this only supports URIs. + IRIs should be converted to UTF-8 and URL-escaped, with + internationalized domain names encoded in punycode, + before passing them to this function. + \param[in,out] _ap A list of the \ref url_options "optional flags" to use. + This is a variable-length list of options terminated + with NULL. + \return A stream handle to use with the callbacks, or NULL on + error.*/ +OP_WARN_UNUSED_RESULT void *op_url_stream_vcreate(OpusFileCallbacks *_cb, + const char *_url,va_list _ap) OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); + +/**Creates a stream that reads from the given URL. + \note If you use this function, you must link against libopusurl. + \param[out] _cb The callbacks to use for this stream. + If there is an error creating the stream, nothing will be + filled in here. + \param _url The URL to read from. + Currently only the , , and schemes + are supported. + Both and may be disabled at compile time, + in which case opening such URLs will always fail. + Currently this only supports URIs. + IRIs should be converted to UTF-8 and URL-escaped, with + internationalized domain names encoded in punycode, before + passing them to this function. + \param ... The \ref url_options "optional flags" to use. + This is a variable-length list of options terminated with + NULL. + \return A stream handle to use with the callbacks, or NULL on + error.*/ +OP_WARN_UNUSED_RESULT void *op_url_stream_create(OpusFileCallbacks *_cb, + const char *_url,...) OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); + +/*@}*/ +/*@}*/ + +/**\defgroup stream_open_close Opening and Closing*/ +/*@{*/ +/**\name Functions for opening and closing streams + + These functions allow you to test a stream to see if it is Opus, open it, + and close it. + Several flavors are provided for each of the built-in stream types, plus a + more general version which takes a set of application-provided callbacks.*/ +/*@{*/ + +/**Test to see if this is an Opus stream. + For good results, you will need at least 57 bytes (for a pure Opus-only + stream). + Something like 512 bytes will give more reliable results for multiplexed + streams. + This function is meant to be a quick-rejection filter. + Its purpose is not to guarantee that a stream is a valid Opus stream, but to + ensure that it looks enough like Opus that it isn't going to be recognized + as some other format (except possibly an Opus stream that is also + multiplexed with other codecs, such as video). + \param[out] _head The parsed ID header contents. + You may pass NULL if you do not need + this information. + If the function fails, the contents of this structure + remain untouched. + \param _initial_data An initial buffer of data from the start of the + stream. + \param _initial_bytes The number of bytes in \a _initial_data. + \return 0 if the data appears to be Opus, or a negative value on error. + \retval #OP_FALSE There was not enough data to tell if this was an Opus + stream or not. + \retval #OP_EFAULT An internal memory allocation failed. + \retval #OP_EIMPL The stream used a feature that is not implemented, + such as an unsupported channel family. + \retval #OP_ENOTFORMAT If the data did not contain a recognizable ID + header for an Opus stream. + \retval #OP_EVERSION If the version field signaled a version this library + does not know how to parse. + \retval #OP_EBADHEADER The ID header was not properly formatted or contained + illegal values.*/ +int op_test(OpusHead *_head, + const unsigned char *_initial_data,size_t _initial_bytes); + +/**Open a stream from the given file path. + \param _path The path to the file to open. + \param[out] _error Returns 0 on success, or a failure code on error. + You may pass in NULL if you don't want the + failure code. + The failure code will be #OP_EFAULT if the file could not + be opened, or one of the other failure codes from + op_open_callbacks() otherwise. + \return A freshly opened \c OggOpusFile, or NULL on error.*/ +OP_WARN_UNUSED_RESULT OggOpusFile *op_open_file(const char *_path,int *_error) + OP_ARG_NONNULL(1); + +/**Open a stream from a memory buffer. + \param _data The memory buffer to open. + \param _size The number of bytes in the buffer. + \param[out] _error Returns 0 on success, or a failure code on error. + You may pass in NULL if you don't want the + failure code. + See op_open_callbacks() for a full list of failure codes. + \return A freshly opened \c OggOpusFile, or NULL on error.*/ +OP_WARN_UNUSED_RESULT OggOpusFile *op_open_memory(const unsigned char *_data, + size_t _size,int *_error); + +/**Open a stream from a URL. + This function behaves identically to op_open_url(), except that it + takes a va_list instead of a variable number of arguments. + It does not call the va_end macro, and because it invokes the + va_arg macro, the value of \a _ap is undefined after the call. + \note If you use this function, you must link against libopusurl. + \param _url The URL to open. + Currently only the , , and + schemes are supported. + Both and may be disabled at compile + time, in which case opening such URLs will always + fail. + Currently this only supports URIs. + IRIs should be converted to UTF-8 and URL-escaped, + with internationalized domain names encoded in + punycode, before passing them to this function. + \param[out] _error Returns 0 on success, or a failure code on error. + You may pass in NULL if you don't want + the failure code. + See op_open_callbacks() for a full list of failure + codes. + \param[in,out] _ap A list of the \ref url_options "optional flags" to + use. + This is a variable-length list of options terminated + with NULL. + \return A freshly opened \c OggOpusFile, or NULL on error.*/ +OP_WARN_UNUSED_RESULT OggOpusFile *op_vopen_url(const char *_url, + int *_error,va_list _ap) OP_ARG_NONNULL(1); + +/**Open a stream from a URL. + \note If you use this function, you must link against libopusurl. + \param _url The URL to open. + Currently only the , , and schemes + are supported. + Both and may be disabled at compile + time, in which case opening such URLs will always fail. + Currently this only supports URIs. + IRIs should be converted to UTF-8 and URL-escaped, with + internationalized domain names encoded in punycode, + before passing them to this function. + \param[out] _error Returns 0 on success, or a failure code on error. + You may pass in NULL if you don't want the + failure code. + See op_open_callbacks() for a full list of failure codes. + \param ... The \ref url_options "optional flags" to use. + This is a variable-length list of options terminated with + NULL. + \return A freshly opened \c OggOpusFile, or NULL on error.*/ +OP_WARN_UNUSED_RESULT OggOpusFile *op_open_url(const char *_url, + int *_error,...) OP_ARG_NONNULL(1); + +/**Open a stream using the given set of callbacks to access it. + \param _stream The stream to read from (e.g., a FILE *). + This value will be passed verbatim as the first + argument to all of the callbacks. + \param _cb The callbacks with which to access the stream. + read() must + be implemented. + seek() and + tell() may + be NULL, or may always return -1 to + indicate a stream is unseekable, but if + seek() is + implemented and succeeds on a particular stream, then + tell() must + also. + close() may + be NULL, but if it is not, it will be + called when the \c OggOpusFile is destroyed by + op_free(). + It will not be called if op_open_callbacks() fails + with an error. + \param _initial_data An initial buffer of data from the start of the + stream. + Applications can read some number of bytes from the + start of the stream to help identify this as an Opus + stream, and then provide them here to allow the + stream to be opened, even if it is unseekable. + \param _initial_bytes The number of bytes in \a _initial_data. + If the stream is seekable, its current position (as + reported by + tell() + at the start of this function) must be equal to + \a _initial_bytes. + Otherwise, seeking to absolute positions will + generate inconsistent results. + \param[out] _error Returns 0 on success, or a failure code on error. + You may pass in NULL if you don't want + the failure code. + The failure code will be one of +
+
#OP_EREAD
+
An underlying read, seek, or tell operation + failed when it should have succeeded, or we failed + to find data in the stream we had seen before.
+
#OP_EFAULT
+
There was a memory allocation failure, or an + internal library error.
+
#OP_EIMPL
+
The stream used a feature that is not + implemented, such as an unsupported channel + family.
+
#OP_EINVAL
+
seek() + was implemented and succeeded on this source, but + tell() + did not, or the starting position indicator was + not equal to \a _initial_bytes.
+
#OP_ENOTFORMAT
+
The stream contained a link that did not have + any logical Opus streams in it.
+
#OP_EBADHEADER
+
A required header packet was not properly + formatted, contained illegal values, or was missing + altogether.
+
#OP_EVERSION
+
An ID header contained an unrecognized version + number.
+
#OP_EBADLINK
+
We failed to find data we had seen before after + seeking.
+
#OP_EBADTIMESTAMP
+
The first or last timestamp in a link failed + basic validity checks.
+
+ \return A freshly opened \c OggOpusFile, or NULL on error. + libopusfile does not take ownership of the stream + if the call fails. + The calling application is responsible for closing the stream if + this call returns an error.*/ +OP_WARN_UNUSED_RESULT OggOpusFile *op_open_callbacks(void *_stream, + const OpusFileCallbacks *_cb,const unsigned char *_initial_data, + size_t _initial_bytes,int *_error) OP_ARG_NONNULL(2); + +/**Partially open a stream from the given file path. + \see op_test_callbacks + \param _path The path to the file to open. + \param[out] _error Returns 0 on success, or a failure code on error. + You may pass in NULL if you don't want the + failure code. + The failure code will be #OP_EFAULT if the file could not + be opened, or one of the other failure codes from + op_open_callbacks() otherwise. + \return A partially opened \c OggOpusFile, or NULL on error.*/ +OP_WARN_UNUSED_RESULT OggOpusFile *op_test_file(const char *_path,int *_error) + OP_ARG_NONNULL(1); + +/**Partially open a stream from a memory buffer. + \see op_test_callbacks + \param _data The memory buffer to open. + \param _size The number of bytes in the buffer. + \param[out] _error Returns 0 on success, or a failure code on error. + You may pass in NULL if you don't want the + failure code. + See op_open_callbacks() for a full list of failure codes. + \return A partially opened \c OggOpusFile, or NULL on error.*/ +OP_WARN_UNUSED_RESULT OggOpusFile *op_test_memory(const unsigned char *_data, + size_t _size,int *_error); + +/**Partially open a stream from a URL. + This function behaves identically to op_test_url(), except that it + takes a va_list instead of a variable number of arguments. + It does not call the va_end macro, and because it invokes the + va_arg macro, the value of \a _ap is undefined after the call. + \note If you use this function, you must link against libopusurl. + \see op_test_url + \see op_test_callbacks + \param _url The URL to open. + Currently only the , , and + schemes are supported. + Both and may be disabled at compile + time, in which case opening such URLs will always + fail. + Currently this only supports URIs. + IRIs should be converted to UTF-8 and URL-escaped, + with internationalized domain names encoded in + punycode, before passing them to this function. + \param[out] _error Returns 0 on success, or a failure code on error. + You may pass in NULL if you don't want + the failure code. + See op_open_callbacks() for a full list of failure + codes. + \param[in,out] _ap A list of the \ref url_options "optional flags" to + use. + This is a variable-length list of options terminated + with NULL. + \return A partially opened \c OggOpusFile, or NULL on error.*/ +OP_WARN_UNUSED_RESULT OggOpusFile *op_vtest_url(const char *_url, + int *_error,va_list _ap) OP_ARG_NONNULL(1); + +/**Partially open a stream from a URL. + \note If you use this function, you must link against libopusurl. + \see op_test_callbacks + \param _url The URL to open. + Currently only the , , and + schemes are supported. + Both and may be disabled at compile + time, in which case opening such URLs will always fail. + Currently this only supports URIs. + IRIs should be converted to UTF-8 and URL-escaped, with + internationalized domain names encoded in punycode, + before passing them to this function. + \param[out] _error Returns 0 on success, or a failure code on error. + You may pass in NULL if you don't want the + failure code. + See op_open_callbacks() for a full list of failure + codes. + \param ... The \ref url_options "optional flags" to use. + This is a variable-length list of options terminated + with NULL. + \return A partially opened \c OggOpusFile, or NULL on error.*/ +OP_WARN_UNUSED_RESULT OggOpusFile *op_test_url(const char *_url, + int *_error,...) OP_ARG_NONNULL(1); + +/**Partially open a stream using the given set of callbacks to access it. + This tests for Opusness and loads the headers for the first link. + It does not seek (although it tests for seekability). + You can query a partially open stream for the few pieces of basic + information returned by op_serialno(), op_channel_count(), op_head(), and + op_tags() (but only for the first link). + You may also determine if it is seekable via a call to op_seekable(). + You cannot read audio from the stream, seek, get the size or duration, + get information from links other than the first one, or even get the total + number of links until you finish opening the stream with op_test_open(). + If you do not need to do any of these things, you can dispose of it with + op_free() instead. + + This function is provided mostly to simplify porting existing code that used + libvorbisfile. + For new code, you are likely better off using op_test() instead, which + is less resource-intensive, requires less data to succeed, and imposes a + hard limit on the amount of data it examines (important for unseekable + streams, where all such data must be buffered until you are sure of the + stream type). + \param _stream The stream to read from (e.g., a FILE *). + This value will be passed verbatim as the first + argument to all of the callbacks. + \param _cb The callbacks with which to access the stream. + read() must + be implemented. + seek() and + tell() may + be NULL, or may always return -1 to + indicate a stream is unseekable, but if + seek() is + implemented and succeeds on a particular stream, then + tell() must + also. + close() may + be NULL, but if it is not, it will be + called when the \c OggOpusFile is destroyed by + op_free(). + It will not be called if op_open_callbacks() fails + with an error. + \param _initial_data An initial buffer of data from the start of the + stream. + Applications can read some number of bytes from the + start of the stream to help identify this as an Opus + stream, and then provide them here to allow the + stream to be tested more thoroughly, even if it is + unseekable. + \param _initial_bytes The number of bytes in \a _initial_data. + If the stream is seekable, its current position (as + reported by + tell() + at the start of this function) must be equal to + \a _initial_bytes. + Otherwise, seeking to absolute positions will + generate inconsistent results. + \param[out] _error Returns 0 on success, or a failure code on error. + You may pass in NULL if you don't want + the failure code. + See op_open_callbacks() for a full list of failure + codes. + \return A partially opened \c OggOpusFile, or NULL on error. + libopusfile does not take ownership of the stream + if the call fails. + The calling application is responsible for closing the stream if + this call returns an error.*/ +OP_WARN_UNUSED_RESULT OggOpusFile *op_test_callbacks(void *_stream, + const OpusFileCallbacks *_cb,const unsigned char *_initial_data, + size_t _initial_bytes,int *_error) OP_ARG_NONNULL(2); + +/**Finish opening a stream partially opened with op_test_callbacks() or one of + the associated convenience functions. + If this function fails, you are still responsible for freeing the + \c OggOpusFile with op_free(). + \param _of The \c OggOpusFile to finish opening. + \return 0 on success, or a negative value on error. + \retval #OP_EREAD An underlying read, seek, or tell operation failed + when it should have succeeded. + \retval #OP_EFAULT There was a memory allocation failure, or an + internal library error. + \retval #OP_EIMPL The stream used a feature that is not implemented, + such as an unsupported channel family. + \retval #OP_EINVAL The stream was not partially opened with + op_test_callbacks() or one of the associated + convenience functions. + \retval #OP_ENOTFORMAT The stream contained a link that did not have any + logical Opus streams in it. + \retval #OP_EBADHEADER A required header packet was not properly + formatted, contained illegal values, or was + missing altogether. + \retval #OP_EVERSION An ID header contained an unrecognized version + number. + \retval #OP_EBADLINK We failed to find data we had seen before after + seeking. + \retval #OP_EBADTIMESTAMP The first or last timestamp in a link failed basic + validity checks.*/ +int op_test_open(OggOpusFile *_of) OP_ARG_NONNULL(1); + +/**Release all memory used by an \c OggOpusFile. + \param _of The \c OggOpusFile to free.*/ +void op_free(OggOpusFile *_of); + +/*@}*/ +/*@}*/ + +/**\defgroup stream_info Stream Information*/ +/*@{*/ +/**\name Functions for obtaining information about streams + + These functions allow you to get basic information about a stream, including + seekability, the number of links (for chained streams), plus the size, + duration, bitrate, header parameters, and meta information for each link + (or, where available, the stream as a whole). + Some of these (size, duration) are only available for seekable streams. + You can also query the current stream position, link, and playback time, + and instantaneous bitrate during playback. + + Some of these functions may be used successfully on the partially open + streams returned by op_test_callbacks() or one of the associated + convenience functions. + Their documention will indicate so explicitly.*/ +/*@{*/ + +/**Returns whether or not the stream being read is seekable. + This is true if +
    +
  1. The seek() and + tell() callbacks are both + non-NULL,
  2. +
  3. The seek() callback was + successfully executed at least once, and
  4. +
  5. The tell() callback was + successfully able to report the position indicator afterwards.
  6. +
+ This function may be called on partially-opened streams. + \param _of The \c OggOpusFile whose seekable status is to be returned. + \return A non-zero value if seekable, and 0 if unseekable.*/ +int op_seekable(const OggOpusFile *_of) OP_ARG_NONNULL(1); + +/**Returns the number of links in this chained stream. + This function may be called on partially-opened streams, but it will always + return 1. + The actual number of links is not known until the stream is fully opened. + \param _of The \c OggOpusFile from which to retrieve the link count. + \return For fully-open seekable streams, this returns the total number of + links in the whole stream, which will be at least 1. + For partially-open or unseekable streams, this always returns 1.*/ +int op_link_count(const OggOpusFile *_of) OP_ARG_NONNULL(1); + +/**Get the serial number of the given link in a (possibly-chained) Ogg Opus + stream. + This function may be called on partially-opened streams, but it will always + return the serial number of the Opus stream in the first link. + \param _of The \c OggOpusFile from which to retrieve the serial number. + \param _li The index of the link whose serial number should be retrieved. + Use a negative number to get the serial number of the current + link. + \return The serial number of the given link. + If \a _li is greater than the total number of links, this returns + the serial number of the last link. + If the stream is not seekable, this always returns the serial number + of the current link.*/ +opus_uint32 op_serialno(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1); + +/**Get the channel count of the given link in a (possibly-chained) Ogg Opus + stream. + This is equivalent to op_head(_of,_li)->channel_count, but + is provided for convenience. + This function may be called on partially-opened streams, but it will always + return the channel count of the Opus stream in the first link. + \param _of The \c OggOpusFile from which to retrieve the channel count. + \param _li The index of the link whose channel count should be retrieved. + Use a negative number to get the channel count of the current + link. + \return The channel count of the given link. + If \a _li is greater than the total number of links, this returns + the channel count of the last link. + If the stream is not seekable, this always returns the channel count + of the current link.*/ +int op_channel_count(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1); + +/**Get the total (compressed) size of the stream, or of an individual link in + a (possibly-chained) Ogg Opus stream, including all headers and Ogg muxing + overhead. + \warning If the Opus stream (or link) is concurrently multiplexed with other + logical streams (e.g., video), this returns the size of the entire stream + (or link), not just the number of bytes in the first logical Opus stream. + Returning the latter would require scanning the entire file. + \param _of The \c OggOpusFile from which to retrieve the compressed size. + \param _li The index of the link whose compressed size should be computed. + Use a negative number to get the compressed size of the entire + stream. + \return The compressed size of the entire stream if \a _li is negative, the + compressed size of link \a _li if it is non-negative, or a negative + value on error. + The compressed size of the entire stream may be smaller than that + of the underlying stream if trailing garbage was detected in the + file. + \retval #OP_EINVAL The stream is not seekable (so we can't know the length), + \a _li wasn't less than the total number of links in + the stream, or the stream was only partially open.*/ +opus_int64 op_raw_total(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1); + +/**Get the total PCM length (number of samples at 48 kHz) of the stream, or of + an individual link in a (possibly-chained) Ogg Opus stream. + Users looking for op_time_total() should use op_pcm_total() + instead. + Because timestamps in Opus are fixed at 48 kHz, there is no need for a + separate function to convert this to seconds (and leaving it out avoids + introducing floating point to the API, for those that wish to avoid it). + \param _of The \c OggOpusFile from which to retrieve the PCM offset. + \param _li The index of the link whose PCM length should be computed. + Use a negative number to get the PCM length of the entire stream. + \return The PCM length of the entire stream if \a _li is negative, the PCM + length of link \a _li if it is non-negative, or a negative value on + error. + \retval #OP_EINVAL The stream is not seekable (so we can't know the length), + \a _li wasn't less than the total number of links in + the stream, or the stream was only partially open.*/ +ogg_int64_t op_pcm_total(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1); + +/**Get the ID header information for the given link in a (possibly chained) Ogg + Opus stream. + This function may be called on partially-opened streams, but it will always + return the ID header information of the Opus stream in the first link. + \param _of The \c OggOpusFile from which to retrieve the ID header + information. + \param _li The index of the link whose ID header information should be + retrieved. + Use a negative number to get the ID header information of the + current link. + For an unseekable stream, \a _li is ignored, and the ID header + information for the current link is always returned, if + available. + \return The contents of the ID header for the given link.*/ +const OpusHead *op_head(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1); + +/**Get the comment header information for the given link in a (possibly + chained) Ogg Opus stream. + This function may be called on partially-opened streams, but it will always + return the tags from the Opus stream in the first link. + \param _of The \c OggOpusFile from which to retrieve the comment header + information. + \param _li The index of the link whose comment header information should be + retrieved. + Use a negative number to get the comment header information of + the current link. + For an unseekable stream, \a _li is ignored, and the comment + header information for the current link is always returned, if + available. + \return The contents of the comment header for the given link, or + NULL if this is an unseekable stream that encountered + an invalid link.*/ +const OpusTags *op_tags(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1); + +/**Retrieve the index of the current link. + This is the link that produced the data most recently read by + op_read_float() or its associated functions, or, after a seek, the link + that the seek target landed in. + Reading more data may advance the link index (even on the first read after a + seek). + \param _of The \c OggOpusFile from which to retrieve the current link index. + \return The index of the current link on success, or a negative value on + failure. + For seekable streams, this is a number between 0 (inclusive) and the + value returned by op_link_count() (exclusive). + For unseekable streams, this value starts at 0 and increments by one + each time a new link is encountered (even though op_link_count() + always returns 1). + \retval #OP_EINVAL The stream was only partially open.*/ +int op_current_link(const OggOpusFile *_of) OP_ARG_NONNULL(1); + +/**Computes the bitrate of the stream, or of an individual link in a + (possibly-chained) Ogg Opus stream. + The stream must be seekable to compute the bitrate. + For unseekable streams, use op_bitrate_instant() to get periodic estimates. + \warning If the Opus stream (or link) is concurrently multiplexed with other + logical streams (e.g., video), this uses the size of the entire stream (or + link) to compute the bitrate, not just the number of bytes in the first + logical Opus stream. + Returning the latter requires scanning the entire file, but this may be done + by decoding the whole file and calling op_bitrate_instant() once at the + end. + Install a trivial decoding callback with op_set_decode_callback() if you + wish to skip actual decoding during this process. + \param _of The \c OggOpusFile from which to retrieve the bitrate. + \param _li The index of the link whose bitrate should be computed. + Use a negative number to get the bitrate of the whole stream. + \return The bitrate on success, or a negative value on error. + \retval #OP_EINVAL The stream was only partially open, the stream was not + seekable, or \a _li was larger than the number of + links.*/ +opus_int32 op_bitrate(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1); + +/**Compute the instantaneous bitrate, measured as the ratio of bits to playable + samples decoded since a) the last call to op_bitrate_instant(), b) the last + seek, or c) the start of playback, whichever was most recent. + This will spike somewhat after a seek or at the start/end of a chain + boundary, as pre-skip, pre-roll, and end-trimming causes samples to be + decoded but not played. + \param _of The \c OggOpusFile from which to retrieve the bitrate. + \return The bitrate, in bits per second, or a negative value on error. + \retval #OP_FALSE No data has been decoded since any of the events + described above. + \retval #OP_EINVAL The stream was only partially open.*/ +opus_int32 op_bitrate_instant(OggOpusFile *_of) OP_ARG_NONNULL(1); + +/**Obtain the current value of the position indicator for \a _of. + \param _of The \c OggOpusFile from which to retrieve the position indicator. + \return The byte position that is currently being read from. + \retval #OP_EINVAL The stream was only partially open.*/ +opus_int64 op_raw_tell(const OggOpusFile *_of) OP_ARG_NONNULL(1); + +/**Obtain the PCM offset of the next sample to be read. + If the stream is not properly timestamped, this might not increment by the + proper amount between reads, or even return monotonically increasing + values. + \param _of The \c OggOpusFile from which to retrieve the PCM offset. + \return The PCM offset of the next sample to be read. + \retval #OP_EINVAL The stream was only partially open.*/ +ogg_int64_t op_pcm_tell(const OggOpusFile *_of) OP_ARG_NONNULL(1); + +/*@}*/ +/*@}*/ + +/**\defgroup stream_seeking Seeking*/ +/*@{*/ +/**\name Functions for seeking in Opus streams + + These functions let you seek in Opus streams, if the underlying stream + support it. + Seeking is implemented for all built-in stream I/O routines, though some + individual streams may not be seekable (pipes, live HTTP streams, or HTTP + streams from a server that does not support Range requests). + + op_raw_seek() is the fastest: it is guaranteed to perform at most one + physical seek, but, since the target is a byte position, makes no guarantee + how close to a given time it will come. + op_pcm_seek() provides sample-accurate seeking. + The number of physical seeks it requires is still quite small (often 1 or + 2, even in highly variable bitrate streams). + + Seeking in Opus requires decoding some pre-roll amount before playback to + allow the internal state to converge (as if recovering from packet loss). + This is handled internally by libopusfile, but means there is + little extra overhead for decoding up to the exact position requested + (since it must decode some amount of audio anyway). + It also means that decoding after seeking may not return exactly the same + values as would be obtained by decoding the stream straight through. + However, such differences are expected to be smaller than the loss + introduced by Opus's lossy compression.*/ +/*@{*/ + +/**Seek to a byte offset relative to the compressed data. + This also scans packets to update the PCM cursor. + It will cross a logical bitstream boundary, but only if it can't get any + packets out of the tail of the link to which it seeks. + \param _of The \c OggOpusFile in which to seek. + \param _byte_offset The byte position to seek to. + This must be between 0 and #op_raw_total(\a _of,\c -1) + (inclusive). + \return 0 on success, or a negative error code on failure. + \retval #OP_EREAD The underlying seek operation failed. + \retval #OP_EINVAL The stream was only partially open, or the target was + outside the valid range for the stream. + \retval #OP_ENOSEEK This stream is not seekable. + \retval #OP_EBADLINK Failed to initialize a decoder for a stream for an + unknown reason.*/ +int op_raw_seek(OggOpusFile *_of,opus_int64 _byte_offset) OP_ARG_NONNULL(1); + +/**Seek to the specified PCM offset, such that decoding will begin at exactly + the requested position. + \param _of The \c OggOpusFile in which to seek. + \param _pcm_offset The PCM offset to seek to. + This is in samples at 48 kHz relative to the start of the + stream. + \return 0 on success, or a negative value on error. + \retval #OP_EREAD An underlying read or seek operation failed. + \retval #OP_EINVAL The stream was only partially open, or the target was + outside the valid range for the stream. + \retval #OP_ENOSEEK This stream is not seekable. + \retval #OP_EBADLINK We failed to find data we had seen before, or the + bitstream structure was sufficiently malformed that + seeking to the target destination was impossible.*/ +int op_pcm_seek(OggOpusFile *_of,ogg_int64_t _pcm_offset) OP_ARG_NONNULL(1); + +/*@}*/ +/*@}*/ + +/**\defgroup stream_decoding Decoding*/ +/*@{*/ +/**\name Functions for decoding audio data + + These functions retrieve actual decoded audio data from the stream. + The general functions, op_read() and op_read_float() return 16-bit or + floating-point output, both using native endian ordering. + The number of channels returned can change from link to link in a chained + stream. + There are special functions, op_read_stereo() and op_read_float_stereo(), + which always output two channels, to simplify applications which do not + wish to handle multichannel audio. + These downmix multichannel files to two channels, so they can always return + samples in the same format for every link in a chained file. + + If the rest of your audio processing chain can handle floating point, the + floating-point routines should be preferred, as they prevent clipping and + other issues which might be avoided entirely if, e.g., you scale down the + volume at some other stage. + However, if you intend to consume 16-bit samples directly, the conversion in + libopusfile provides noise-shaping dithering and, if compiled + against libopus 1.1 or later, soft-clipping prevention. + + libopusfile can also be configured at compile time to use the + fixed-point libopus API. + If so, libopusfile's floating-point API may also be disabled. + In that configuration, nothing in libopusfile will use any + floating-point operations, to simplify support on devices without an + adequate FPU. + + \warning HTTPS streams may be be vulnerable to truncation attacks if you do + not check the error return code from op_read_float() or its associated + functions. + If the remote peer does not close the connection gracefully (with a TLS + "close notify" message), these functions will return #OP_EREAD instead of 0 + when they reach the end of the file. + If you are reading from an URL (particularly if seeking is not + supported), you should make sure to check for this error and warn the user + appropriately.*/ +/*@{*/ + +/**Indicates that the decoding callback should produce signed 16-bit + native-endian output samples.*/ +#define OP_DEC_FORMAT_SHORT (7008) +/**Indicates that the decoding callback should produce 32-bit native-endian + float samples.*/ +#define OP_DEC_FORMAT_FLOAT (7040) + +/**Indicates that the decoding callback did not decode anything, and that + libopusfile should decode normally instead.*/ +#define OP_DEC_USE_DEFAULT (6720) + +/**Called to decode an Opus packet. + This should invoke the functional equivalent of opus_multistream_decode() or + opus_multistream_decode_float(), except that it returns 0 on success + instead of the number of decoded samples (which is known a priori). + \param _ctx The application-provided callback context. + \param _decoder The decoder to use to decode the packet. + \param[out] _pcm The buffer to decode into. + This will always have enough room for \a _nchannels of + \a _nsamples samples, which should be placed into this + buffer interleaved. + \param _op The packet to decode. + This will always have its granule position set to a valid + value. + \param _nsamples The number of samples expected from the packet. + \param _nchannels The number of channels expected from the packet. + \param _format The desired sample output format. + This is either #OP_DEC_FORMAT_SHORT or + #OP_DEC_FORMAT_FLOAT. + \param _li The index of the link from which this packet was decoded. + \return A non-negative value on success, or a negative value on error. + Any error codes should be the same as those returned by + opus_multistream_decode() or opus_multistream_decode_float(). + Success codes are as follows: + \retval 0 Decoding was successful. + The application has filled the buffer with + exactly \a _nsamples*\a + _nchannels samples in the requested + format. + \retval #OP_DEC_USE_DEFAULT No decoding was done. + libopusfile should do the decoding + by itself instead.*/ +typedef int (*op_decode_cb_func)(void *_ctx,OpusMSDecoder *_decoder,void *_pcm, + const ogg_packet *_op,int _nsamples,int _nchannels,int _format,int _li); + +/**Sets the packet decode callback function. + If set, this is called once for each packet that needs to be decoded. + This can be used by advanced applications to do additional processing on the + compressed or uncompressed data. + For example, an application might save the final entropy coder state for + debugging and testing purposes, or it might apply additional filters + before the downmixing, dithering, or soft-clipping performed by + libopusfile, so long as these filters do not introduce any + latency. + + A call to this function is no guarantee that the audio will eventually be + delivered to the application. + libopusfile may discard some or all of the decoded audio data + (i.e., at the beginning or end of a link, or after a seek), however the + callback is still required to provide all of it. + \param _of The \c OggOpusFile on which to set the decode callback. + \param _decode_cb The callback function to call. + This may be NULL to disable calling the + callback. + \param _ctx The application-provided context pointer to pass to the + callback on each call.*/ +void op_set_decode_callback(OggOpusFile *_of, + op_decode_cb_func _decode_cb,void *_ctx) OP_ARG_NONNULL(1); + +/**Gain offset type that indicates that the provided offset is relative to the + header gain. + This is the default.*/ +#define OP_HEADER_GAIN (0) + +/**Gain offset type that indicates that the provided offset is relative to the + R128_ALBUM_GAIN value (if any), in addition to the header gain.*/ +#define OP_ALBUM_GAIN (3007) + +/**Gain offset type that indicates that the provided offset is relative to the + R128_TRACK_GAIN value (if any), in addition to the header gain.*/ +#define OP_TRACK_GAIN (3008) + +/**Gain offset type that indicates that the provided offset should be used as + the gain directly, without applying any the header or track gains.*/ +#define OP_ABSOLUTE_GAIN (3009) + +/**Sets the gain to be used for decoded output. + By default, the gain in the header is applied with no additional offset. + The total gain (including header gain and/or track gain, if applicable, and + this offset), will be clamped to [-32768,32767]/256 dB. + This is more than enough to saturate or underflow 16-bit PCM. + \note The new gain will not be applied to any already buffered, decoded + output. + This means you cannot change it sample-by-sample, as at best it will be + updated packet-by-packet. + It is meant for setting a target volume level, rather than applying smooth + fades, etc. + \param _of The \c OggOpusFile on which to set the gain offset. + \param _gain_type One of #OP_HEADER_GAIN, #OP_ALBUM_GAIN, + #OP_TRACK_GAIN, or #OP_ABSOLUTE_GAIN. + \param _gain_offset_q8 The gain offset to apply, in 1/256ths of a dB. + \return 0 on success or a negative value on error. + \retval #OP_EINVAL The \a _gain_type was unrecognized.*/ +int op_set_gain_offset(OggOpusFile *_of, + int _gain_type,opus_int32 _gain_offset_q8) OP_ARG_NONNULL(1); + +/**Sets whether or not dithering is enabled for 16-bit decoding. + By default, when libopusfile is compiled to use floating-point + internally, calling op_read() or op_read_stereo() will first decode to + float, and then convert to fixed-point using noise-shaping dithering. + This flag can be used to disable that dithering. + When the application uses op_read_float() or op_read_float_stereo(), or when + the library has been compiled to decode directly to fixed point, this flag + has no effect. + \param _of The \c OggOpusFile on which to enable or disable dithering. + \param _enabled A non-zero value to enable dithering, or 0 to disable it.*/ +void op_set_dither_enabled(OggOpusFile *_of,int _enabled) OP_ARG_NONNULL(1); + +/**Reads more samples from the stream. + \note Although \a _buf_size must indicate the total number of values that + can be stored in \a _pcm, the return value is the number of samples + per channel. + This is done because +
    +
  1. The channel count cannot be known a priori (reading more samples might + advance us into the next link, with a different channel count), so + \a _buf_size cannot also be in units of samples per channel,
  2. +
  3. Returning the samples per channel matches the libopus API + as closely as we're able,
  4. +
  5. Returning the total number of values instead of samples per channel + would mean the caller would need a division to compute the samples per + channel, and might worry about the possibility of getting back samples + for some channels and not others, and
  6. +
  7. This approach is relatively fool-proof: if an application passes too + small a value to \a _buf_size, they will simply get fewer samples back, + and if they assume the return value is the total number of values, then + they will simply read too few (rather than reading too many and going + off the end of the buffer).
  8. +
+ \param _of The \c OggOpusFile from which to read. + \param[out] _pcm A buffer in which to store the output PCM samples, as + signed native-endian 16-bit values at 48 kHz + with a nominal range of [-32768,32767). + Multiple channels are interleaved using the + Vorbis + channel ordering. + This must have room for at least \a _buf_size values. + \param _buf_size The number of values that can be stored in \a _pcm. + It is recommended that this be large enough for at + least 120 ms of data at 48 kHz per channel (5760 + values per channel). + Smaller buffers will simply return less data, possibly + consuming more memory to buffer the data internally. + libopusfile may return less data than + requested. + If so, there is no guarantee that the remaining data + in \a _pcm will be unmodified. + \param[out] _li The index of the link this data was decoded from. + You may pass NULL if you do not need this + information. + If this function fails (returning a negative value), + this parameter is left unset. + \return The number of samples read per channel on success, or a negative + value on failure. + The channel count can be retrieved on success by calling + op_head(_of,*_li). + The number of samples returned may be 0 if the buffer was too small + to store even a single sample for all channels, or if end-of-file + was reached. + The list of possible failure codes follows. + Most of them can only be returned by unseekable, chained streams + that encounter a new link. + \retval #OP_HOLE There was a hole in the data, and some samples + may have been skipped. + Call this function again to continue decoding + past the hole. + \retval #OP_EREAD An underlying read operation failed. + This may signal a truncation attack from an + source. + \retval #OP_EFAULT An internal memory allocation failed. + \retval #OP_EIMPL An unseekable stream encountered a new link that + used a feature that is not implemented, such as + an unsupported channel family. + \retval #OP_EINVAL The stream was only partially open. + \retval #OP_ENOTFORMAT An unseekable stream encountered a new link that + did not have any logical Opus streams in it. + \retval #OP_EBADHEADER An unseekable stream encountered a new link with a + required header packet that was not properly + formatted, contained illegal values, or was + missing altogether. + \retval #OP_EVERSION An unseekable stream encountered a new link with + an ID header that contained an unrecognized + version number. + \retval #OP_EBADPACKET Failed to properly decode the next packet. + \retval #OP_EBADLINK We failed to find data we had seen before. + \retval #OP_EBADTIMESTAMP An unseekable stream encountered a new link with + a starting timestamp that failed basic validity + checks.*/ +OP_WARN_UNUSED_RESULT int op_read(OggOpusFile *_of, + opus_int16 *_pcm,int _buf_size,int *_li) OP_ARG_NONNULL(1); + +/**Reads more samples from the stream. + \note Although \a _buf_size must indicate the total number of values that + can be stored in \a _pcm, the return value is the number of samples + per channel. +
    +
  1. The channel count cannot be known a priori (reading more samples might + advance us into the next link, with a different channel count), so + \a _buf_size cannot also be in units of samples per channel,
  2. +
  3. Returning the samples per channel matches the libopus API + as closely as we're able,
  4. +
  5. Returning the total number of values instead of samples per channel + would mean the caller would need a division to compute the samples per + channel, and might worry about the possibility of getting back samples + for some channels and not others, and
  6. +
  7. This approach is relatively fool-proof: if an application passes too + small a value to \a _buf_size, they will simply get fewer samples back, + and if they assume the return value is the total number of values, then + they will simply read too few (rather than reading too many and going + off the end of the buffer).
  8. +
+ \param _of The \c OggOpusFile from which to read. + \param[out] _pcm A buffer in which to store the output PCM samples as + signed floats at 48 kHz with a nominal range of + [-1.0,1.0]. + Multiple channels are interleaved using the + Vorbis + channel ordering. + This must have room for at least \a _buf_size floats. + \param _buf_size The number of floats that can be stored in \a _pcm. + It is recommended that this be large enough for at + least 120 ms of data at 48 kHz per channel (5760 + samples per channel). + Smaller buffers will simply return less data, possibly + consuming more memory to buffer the data internally. + If less than \a _buf_size values are returned, + libopusfile makes no guarantee that the + remaining data in \a _pcm will be unmodified. + \param[out] _li The index of the link this data was decoded from. + You may pass NULL if you do not need this + information. + If this function fails (returning a negative value), + this parameter is left unset. + \return The number of samples read per channel on success, or a negative + value on failure. + The channel count can be retrieved on success by calling + op_head(_of,*_li). + The number of samples returned may be 0 if the buffer was too small + to store even a single sample for all channels, or if end-of-file + was reached. + The list of possible failure codes follows. + Most of them can only be returned by unseekable, chained streams + that encounter a new link. + \retval #OP_HOLE There was a hole in the data, and some samples + may have been skipped. + Call this function again to continue decoding + past the hole. + \retval #OP_EREAD An underlying read operation failed. + This may signal a truncation attack from an + source. + \retval #OP_EFAULT An internal memory allocation failed. + \retval #OP_EIMPL An unseekable stream encountered a new link that + used a feature that is not implemented, such as + an unsupported channel family. + \retval #OP_EINVAL The stream was only partially open. + \retval #OP_ENOTFORMAT An unseekable stream encountered a new link that + did not have any logical Opus streams in it. + \retval #OP_EBADHEADER An unseekable stream encountered a new link with a + required header packet that was not properly + formatted, contained illegal values, or was + missing altogether. + \retval #OP_EVERSION An unseekable stream encountered a new link with + an ID header that contained an unrecognized + version number. + \retval #OP_EBADPACKET Failed to properly decode the next packet. + \retval #OP_EBADLINK We failed to find data we had seen before. + \retval #OP_EBADTIMESTAMP An unseekable stream encountered a new link with + a starting timestamp that failed basic validity + checks.*/ +OP_WARN_UNUSED_RESULT int op_read_float(OggOpusFile *_of, + float *_pcm,int _buf_size,int *_li) OP_ARG_NONNULL(1); + +/**Reads more samples from the stream and downmixes to stereo, if necessary. + This function is intended for simple players that want a uniform output + format, even if the channel count changes between links in a chained + stream. + \note \a _buf_size indicates the total number of values that can be stored + in \a _pcm, while the return value is the number of samples per + channel, even though the channel count is known, for consistency with + op_read(). + \param _of The \c OggOpusFile from which to read. + \param[out] _pcm A buffer in which to store the output PCM samples, as + signed native-endian 16-bit values at 48 kHz + with a nominal range of [-32768,32767). + The left and right channels are interleaved in the + buffer. + This must have room for at least \a _buf_size values. + \param _buf_size The number of values that can be stored in \a _pcm. + It is recommended that this be large enough for at + least 120 ms of data at 48 kHz per channel (11520 + values total). + Smaller buffers will simply return less data, possibly + consuming more memory to buffer the data internally. + If less than \a _buf_size values are returned, + libopusfile makes no guarantee that the + remaining data in \a _pcm will be unmodified. + \return The number of samples read per channel on success, or a negative + value on failure. + The number of samples returned may be 0 if the buffer was too small + to store even a single sample for both channels, or if end-of-file + was reached. + The list of possible failure codes follows. + Most of them can only be returned by unseekable, chained streams + that encounter a new link. + \retval #OP_HOLE There was a hole in the data, and some samples + may have been skipped. + Call this function again to continue decoding + past the hole. + \retval #OP_EREAD An underlying read operation failed. + This may signal a truncation attack from an + source. + \retval #OP_EFAULT An internal memory allocation failed. + \retval #OP_EIMPL An unseekable stream encountered a new link that + used a feature that is not implemented, such as + an unsupported channel family. + \retval #OP_EINVAL The stream was only partially open. + \retval #OP_ENOTFORMAT An unseekable stream encountered a new link that + did not have any logical Opus streams in it. + \retval #OP_EBADHEADER An unseekable stream encountered a new link with a + required header packet that was not properly + formatted, contained illegal values, or was + missing altogether. + \retval #OP_EVERSION An unseekable stream encountered a new link with + an ID header that contained an unrecognized + version number. + \retval #OP_EBADPACKET Failed to properly decode the next packet. + \retval #OP_EBADLINK We failed to find data we had seen before. + \retval #OP_EBADTIMESTAMP An unseekable stream encountered a new link with + a starting timestamp that failed basic validity + checks.*/ +OP_WARN_UNUSED_RESULT int op_read_stereo(OggOpusFile *_of, + opus_int16 *_pcm,int _buf_size) OP_ARG_NONNULL(1); + +/**Reads more samples from the stream and downmixes to stereo, if necessary. + This function is intended for simple players that want a uniform output + format, even if the channel count changes between links in a chained + stream. + \note \a _buf_size indicates the total number of values that can be stored + in \a _pcm, while the return value is the number of samples per + channel, even though the channel count is known, for consistency with + op_read_float(). + \param _of The \c OggOpusFile from which to read. + \param[out] _pcm A buffer in which to store the output PCM samples, as + signed floats at 48 kHz with a nominal range of + [-1.0,1.0]. + The left and right channels are interleaved in the + buffer. + This must have room for at least \a _buf_size values. + \param _buf_size The number of values that can be stored in \a _pcm. + It is recommended that this be large enough for at + least 120 ms of data at 48 kHz per channel (11520 + values total). + Smaller buffers will simply return less data, possibly + consuming more memory to buffer the data internally. + If less than \a _buf_size values are returned, + libopusfile makes no guarantee that the + remaining data in \a _pcm will be unmodified. + \return The number of samples read per channel on success, or a negative + value on failure. + The number of samples returned may be 0 if the buffer was too small + to store even a single sample for both channels, or if end-of-file + was reached. + The list of possible failure codes follows. + Most of them can only be returned by unseekable, chained streams + that encounter a new link. + \retval #OP_HOLE There was a hole in the data, and some samples + may have been skipped. + Call this function again to continue decoding + past the hole. + \retval #OP_EREAD An underlying read operation failed. + This may signal a truncation attack from an + source. + \retval #OP_EFAULT An internal memory allocation failed. + \retval #OP_EIMPL An unseekable stream encountered a new link that + used a feature that is not implemented, such as + an unsupported channel family. + \retval #OP_EINVAL The stream was only partially open. + \retval #OP_ENOTFORMAT An unseekable stream encountered a new link that + that did not have any logical Opus streams in it. + \retval #OP_EBADHEADER An unseekable stream encountered a new link with a + required header packet that was not properly + formatted, contained illegal values, or was + missing altogether. + \retval #OP_EVERSION An unseekable stream encountered a new link with + an ID header that contained an unrecognized + version number. + \retval #OP_EBADPACKET Failed to properly decode the next packet. + \retval #OP_EBADLINK We failed to find data we had seen before. + \retval #OP_EBADTIMESTAMP An unseekable stream encountered a new link with + a starting timestamp that failed basic validity + checks.*/ +OP_WARN_UNUSED_RESULT int op_read_float_stereo(OggOpusFile *_of, + float *_pcm,int _buf_size) OP_ARG_NONNULL(1); + +/*@}*/ +/*@}*/ + +# if OP_GNUC_PREREQ(4,0) +# pragma GCC visibility pop +# endif + +# if defined(__cplusplus) +} +# endif + +#endif diff --git a/engine/voice_codecs/celt/voiceencoder_celt.cpp b/engine/voice_codecs/celt/voiceencoder_celt.cpp index 5c3ee628..6aab093f 100644 --- a/engine/voice_codecs/celt/voiceencoder_celt.cpp +++ b/engine/voice_codecs/celt/voiceencoder_celt.cpp @@ -41,13 +41,13 @@ damage. */ #include "ivoicecodec.h" #include "iframeencoder.h" -#ifdef POSIX +/*#ifdef POSIX #include "source/osx/config.h" #else #include "source/msvc/config.h" -#endif +#endif*/ #include -#include "celt.h" +#include // NOTE: This has to be the last file included! @@ -67,21 +67,10 @@ struct celt_versions celt_versions g_CeltVersion[CELT_VERSION] = { - { - 44100, 256, 120 - }, - - { - 22050, 120, 60 - }, - - { - 22050, 256, 60 - }, - - { - 22050, 512, 64 - }, + {44100, 256, 120}, + {22050, 120, 60}, + {22050, 256, 60}, + {22050, 512, 64}, }; class VoiceEncoder_Celt : public IFrameEncoder diff --git a/engine/voice_codecs/celt/wscript b/engine/voice_codecs/celt/wscript new file mode 100755 index 00000000..f67c4afe --- /dev/null +++ b/engine/voice_codecs/celt/wscript @@ -0,0 +1,54 @@ +#! /usr/bin/env python +# encoding: utf-8 + +from waflib import Utils +import os + +top = '.' +PROJECT_NAME = 'vaudio_celt' + +def options(opt): + # stub + return + +def configure(conf): + conf.define('SPEEX_EXPORTS',1) +# conf.define('NO_HOOK_MALLOC',1) + +def build(bld): + source = [ + 'voiceencoder_celt.cpp', + '../frame_encoder/voice_codec_frame.cpp', + '../../../tier1/interface.cpp' + ] + + includes = [ + '.', + '../frame_encoder', + '../../../public', + '../../../public/tier1', + '../../../public/tier0', + '../../', + '../../../common', + '../../audio/public' + ] + + defines = [] + + libs = ['tier0','tier1','vstdlib','CELT'] + + install_path = bld.env.LIBDIR + + bld.shlib( + source = source, + target = PROJECT_NAME, + name = PROJECT_NAME, + features = 'c cxx', + includes = includes, + defines = defines, + use = libs, + install_path = install_path, + subsystem = bld.env.MSVC_SUBSYSTEM, + idx = bld.get_taskgen_count() + ) + diff --git a/engine/voice_codecs/opus/opus/opus.h b/engine/voice_codecs/opus/opus/opus.h new file mode 100644 index 00000000..d282f21d --- /dev/null +++ b/engine/voice_codecs/opus/opus/opus.h @@ -0,0 +1,981 @@ +/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited + Written by Jean-Marc Valin and Koen Vos */ +/* + 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. +*/ + +/** + * @file opus.h + * @brief Opus reference implementation API + */ + +#ifndef OPUS_H +#define OPUS_H + +#include "opus_types.h" +#include "opus_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @mainpage Opus + * + * The Opus codec is designed for interactive speech and audio transmission over the Internet. + * It is designed by the IETF Codec Working Group and incorporates technology from + * Skype's SILK codec and Xiph.Org's CELT codec. + * + * The Opus codec is designed to handle a wide range of interactive audio applications, + * including Voice over IP, videoconferencing, in-game chat, and even remote live music + * performances. It can scale from low bit-rate narrowband speech to very high quality + * stereo music. Its main features are: + + * @li Sampling rates from 8 to 48 kHz + * @li Bit-rates from 6 kb/s to 510 kb/s + * @li Support for both constant bit-rate (CBR) and variable bit-rate (VBR) + * @li Audio bandwidth from narrowband to full-band + * @li Support for speech and music + * @li Support for mono and stereo + * @li Support for multichannel (up to 255 channels) + * @li Frame sizes from 2.5 ms to 60 ms + * @li Good loss robustness and packet loss concealment (PLC) + * @li Floating point and fixed-point implementation + * + * Documentation sections: + * @li @ref opus_encoder + * @li @ref opus_decoder + * @li @ref opus_repacketizer + * @li @ref opus_multistream + * @li @ref opus_libinfo + * @li @ref opus_custom + */ + +/** @defgroup opus_encoder Opus Encoder + * @{ + * + * @brief This page describes the process and functions used to encode Opus. + * + * Since Opus is a stateful codec, the encoding process starts with creating an encoder + * state. This can be done with: + * + * @code + * int error; + * OpusEncoder *enc; + * enc = opus_encoder_create(Fs, channels, application, &error); + * @endcode + * + * From this point, @c enc can be used for encoding an audio stream. An encoder state + * @b must @b not be used for more than one stream at the same time. Similarly, the encoder + * state @b must @b not be re-initialized for each frame. + * + * While opus_encoder_create() allocates memory for the state, it's also possible + * to initialize pre-allocated memory: + * + * @code + * int size; + * int error; + * OpusEncoder *enc; + * size = opus_encoder_get_size(channels); + * enc = malloc(size); + * error = opus_encoder_init(enc, Fs, channels, application); + * @endcode + * + * where opus_encoder_get_size() returns the required size for the encoder state. Note that + * future versions of this code may change the size, so no assuptions should be made about it. + * + * The encoder state is always continuous in memory and only a shallow copy is sufficient + * to copy it (e.g. memcpy()) + * + * It is possible to change some of the encoder's settings using the opus_encoder_ctl() + * interface. All these settings already default to the recommended value, so they should + * only be changed when necessary. The most common settings one may want to change are: + * + * @code + * opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate)); + * opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity)); + * opus_encoder_ctl(enc, OPUS_SET_SIGNAL(signal_type)); + * @endcode + * + * where + * + * @arg bitrate is in bits per second (b/s) + * @arg complexity is a value from 1 to 10, where 1 is the lowest complexity and 10 is the highest + * @arg signal_type is either OPUS_AUTO (default), OPUS_SIGNAL_VOICE, or OPUS_SIGNAL_MUSIC + * + * See @ref opus_encoderctls and @ref opus_genericctls for a complete list of parameters that can be set or queried. Most parameters can be set or changed at any time during a stream. + * + * To encode a frame, opus_encode() or opus_encode_float() must be called with exactly one frame (2.5, 5, 10, 20, 40 or 60 ms) of audio data: + * @code + * len = opus_encode(enc, audio_frame, frame_size, packet, max_packet); + * @endcode + * + * where + *
    + *
  • audio_frame is the audio data in opus_int16 (or float for opus_encode_float())
  • + *
  • frame_size is the duration of the frame in samples (per channel)
  • + *
  • packet is the byte array to which the compressed data is written
  • + *
  • max_packet is the maximum number of bytes that can be written in the packet (4000 bytes is recommended). + * Do not use max_packet to control VBR target bitrate, instead use the #OPUS_SET_BITRATE CTL.
  • + *
+ * + * opus_encode() and opus_encode_float() return the number of bytes actually written to the packet. + * The return value can be negative, which indicates that an error has occurred. If the return value + * is 2 bytes or less, then the packet does not need to be transmitted (DTX). + * + * Once the encoder state if no longer needed, it can be destroyed with + * + * @code + * opus_encoder_destroy(enc); + * @endcode + * + * If the encoder was created with opus_encoder_init() rather than opus_encoder_create(), + * then no action is required aside from potentially freeing the memory that was manually + * allocated for it (calling free(enc) for the example above) + * + */ + +/** Opus encoder state. + * This contains the complete state of an Opus encoder. + * It is position independent and can be freely copied. + * @see opus_encoder_create,opus_encoder_init + */ +typedef struct OpusEncoder OpusEncoder; + +/** Gets the size of an OpusEncoder structure. + * @param[in] channels int: Number of channels. + * This must be 1 or 2. + * @returns The size in bytes. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_encoder_get_size(int channels); + +/** + */ + +/** Allocates and initializes an encoder state. + * There are three coding modes: + * + * @ref OPUS_APPLICATION_VOIP gives best quality at a given bitrate for voice + * signals. It enhances the input signal by high-pass filtering and + * emphasizing formants and harmonics. Optionally it includes in-band + * forward error correction to protect against packet loss. Use this + * mode for typical VoIP applications. Because of the enhancement, + * even at high bitrates the output may sound different from the input. + * + * @ref OPUS_APPLICATION_AUDIO gives best quality at a given bitrate for most + * non-voice signals like music. Use this mode for music and mixed + * (music/voice) content, broadcast, and applications requiring less + * than 15 ms of coding delay. + * + * @ref OPUS_APPLICATION_RESTRICTED_LOWDELAY configures low-delay mode that + * disables the speech-optimized mode in exchange for slightly reduced delay. + * This mode can only be set on an newly initialized or freshly reset encoder + * because it changes the codec delay. + * + * This is useful when the caller knows that the speech-optimized modes will not be needed (use with caution). + * @param [in] Fs opus_int32: Sampling rate of input signal (Hz) + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param [in] channels int: Number of channels (1 or 2) in input signal + * @param [in] application int: Coding mode (@ref OPUS_APPLICATION_VOIP/@ref OPUS_APPLICATION_AUDIO/@ref OPUS_APPLICATION_RESTRICTED_LOWDELAY) + * @param [out] error int*: @ref opus_errorcodes + * @note Regardless of the sampling rate and number channels selected, the Opus encoder + * can switch to a lower audio bandwidth or number of channels if the bitrate + * selected is too low. This also means that it is safe to always use 48 kHz stereo input + * and let the encoder optimize the encoding. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusEncoder *opus_encoder_create( + opus_int32 Fs, + int channels, + int application, + int *error +); + +/** Initializes a previously allocated encoder state + * The memory pointed to by st must be at least the size returned by opus_encoder_get_size(). + * This is intended for applications which use their own allocator instead of malloc. + * @see opus_encoder_create(),opus_encoder_get_size() + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. + * @param [in] st OpusEncoder*: Encoder state + * @param [in] Fs opus_int32: Sampling rate of input signal (Hz) + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param [in] channels int: Number of channels (1 or 2) in input signal + * @param [in] application int: Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO/OPUS_APPLICATION_RESTRICTED_LOWDELAY) + * @retval #OPUS_OK Success or @ref opus_errorcodes + */ +OPUS_EXPORT int opus_encoder_init( + OpusEncoder *st, + opus_int32 Fs, + int channels, + int application +) OPUS_ARG_NONNULL(1); + +/** Encodes an Opus frame. + * @param [in] st OpusEncoder*: Encoder state + * @param [in] pcm opus_int16*: Input signal (interleaved if 2 channels). length is frame_size*channels*sizeof(opus_int16) + * @param [in] frame_size int: Number of samples per channel in the + * input signal. + * This must be an Opus frame size for + * the encoder's sampling rate. + * For example, at 48 kHz the permitted + * values are 120, 240, 480, 960, 1920, + * and 2880. + * Passing in a duration of less than + * 10 ms (480 samples at 48 kHz) will + * prevent the encoder from using the LPC + * or hybrid modes. + * @param [out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode( + OpusEncoder *st, + const opus_int16 *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Encodes an Opus frame from floating point input. + * @param [in] st OpusEncoder*: Encoder state + * @param [in] pcm float*: Input in float format (interleaved if 2 channels), with a normal range of +/-1.0. + * Samples with a range beyond +/-1.0 are supported but will + * be clipped by decoders using the integer API and should + * only be used if it is known that the far end supports + * extended dynamic range. + * length is frame_size*channels*sizeof(float) + * @param [in] frame_size int: Number of samples per channel in the + * input signal. + * This must be an Opus frame size for + * the encoder's sampling rate. + * For example, at 48 kHz the permitted + * values are 120, 240, 480, 960, 1920, + * and 2880. + * Passing in a duration of less than + * 10 ms (480 samples at 48 kHz) will + * prevent the encoder from using the LPC + * or hybrid modes. + * @param [out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode_float( + OpusEncoder *st, + const float *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Frees an OpusEncoder allocated by opus_encoder_create(). + * @param[in] st OpusEncoder*: State to be freed. + */ +OPUS_EXPORT void opus_encoder_destroy(OpusEncoder *st); + +/** Perform a CTL function on an Opus encoder. + * + * Generally the request and subsequent arguments are generated + * by a convenience macro. + * @param st OpusEncoder*: Encoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls or + * @ref opus_encoderctls. + * @see opus_genericctls + * @see opus_encoderctls + */ +OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...) OPUS_ARG_NONNULL(1); +/**@}*/ + +/** @defgroup opus_decoder Opus Decoder + * @{ + * + * @brief This page describes the process and functions used to decode Opus. + * + * The decoding process also starts with creating a decoder + * state. This can be done with: + * @code + * int error; + * OpusDecoder *dec; + * dec = opus_decoder_create(Fs, channels, &error); + * @endcode + * where + * @li Fs is the sampling rate and must be 8000, 12000, 16000, 24000, or 48000 + * @li channels is the number of channels (1 or 2) + * @li error will hold the error code in case of failure (or #OPUS_OK on success) + * @li the return value is a newly created decoder state to be used for decoding + * + * While opus_decoder_create() allocates memory for the state, it's also possible + * to initialize pre-allocated memory: + * @code + * int size; + * int error; + * OpusDecoder *dec; + * size = opus_decoder_get_size(channels); + * dec = malloc(size); + * error = opus_decoder_init(dec, Fs, channels); + * @endcode + * where opus_decoder_get_size() returns the required size for the decoder state. Note that + * future versions of this code may change the size, so no assuptions should be made about it. + * + * The decoder state is always continuous in memory and only a shallow copy is sufficient + * to copy it (e.g. memcpy()) + * + * To decode a frame, opus_decode() or opus_decode_float() must be called with a packet of compressed audio data: + * @code + * frame_size = opus_decode(dec, packet, len, decoded, max_size, 0); + * @endcode + * where + * + * @li packet is the byte array containing the compressed data + * @li len is the exact number of bytes contained in the packet + * @li decoded is the decoded audio data in opus_int16 (or float for opus_decode_float()) + * @li max_size is the max duration of the frame in samples (per channel) that can fit into the decoded_frame array + * + * opus_decode() and opus_decode_float() return the number of samples (per channel) decoded from the packet. + * If that value is negative, then an error has occurred. This can occur if the packet is corrupted or if the audio + * buffer is too small to hold the decoded audio. + * + * Opus is a stateful codec with overlapping blocks and as a result Opus + * packets are not coded independently of each other. Packets must be + * passed into the decoder serially and in the correct order for a correct + * decode. Lost packets can be replaced with loss concealment by calling + * the decoder with a null pointer and zero length for the missing packet. + * + * A single codec state may only be accessed from a single thread at + * a time and any required locking must be performed by the caller. Separate + * streams must be decoded with separate decoder states and can be decoded + * in parallel unless the library was compiled with NONTHREADSAFE_PSEUDOSTACK + * defined. + * + */ + +/** Opus decoder state. + * This contains the complete state of an Opus decoder. + * It is position independent and can be freely copied. + * @see opus_decoder_create,opus_decoder_init + */ +typedef struct OpusDecoder OpusDecoder; + +/** Gets the size of an OpusDecoder structure. + * @param [in] channels int: Number of channels. + * This must be 1 or 2. + * @returns The size in bytes. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_size(int channels); + +/** Allocates and initializes a decoder state. + * @param [in] Fs opus_int32: Sample rate to decode at (Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param [in] channels int: Number of channels (1 or 2) to decode + * @param [out] error int*: #OPUS_OK Success or @ref opus_errorcodes + * + * Internally Opus stores data at 48000 Hz, so that should be the default + * value for Fs. However, the decoder can efficiently decode to buffers + * at 8, 12, 16, and 24 kHz so if for some reason the caller cannot use + * data at the full sample rate, or knows the compressed data doesn't + * use the full frequency range, it can request decoding at a reduced + * rate. Likewise, the decoder is capable of filling in either mono or + * interleaved stereo pcm buffers, at the caller's request. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusDecoder *opus_decoder_create( + opus_int32 Fs, + int channels, + int *error +); + +/** Initializes a previously allocated decoder state. + * The state must be at least the size returned by opus_decoder_get_size(). + * This is intended for applications which use their own allocator instead of malloc. @see opus_decoder_create,opus_decoder_get_size + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. + * @param [in] st OpusDecoder*: Decoder state. + * @param [in] Fs opus_int32: Sampling rate to decode to (Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param [in] channels int: Number of channels (1 or 2) to decode + * @retval #OPUS_OK Success or @ref opus_errorcodes + */ +OPUS_EXPORT int opus_decoder_init( + OpusDecoder *st, + opus_int32 Fs, + int channels +) OPUS_ARG_NONNULL(1); + +/** Decode an Opus packet. + * @param [in] st OpusDecoder*: Decoder state + * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss + * @param [in] len opus_int32: Number of bytes in payload* + * @param [out] pcm opus_int16*: Output signal (interleaved if 2 channels). length + * is frame_size*channels*sizeof(opus_int16) + * @param [in] frame_size Number of samples per channel of available space in \a pcm. + * If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will + * not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1), + * then frame_size needs to be exactly the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the next incoming packet. For the PLC and + * FEC cases, frame_size must be a multiple of 2.5 ms. + * @param [in] decode_fec int: Flag (0 or 1) to request that any in-band forward error correction data be + * decoded. If no such data is available, the frame is decoded as if it were lost. + * @returns Number of decoded samples or @ref opus_errorcodes + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode( + OpusDecoder *st, + const unsigned char *data, + opus_int32 len, + opus_int16 *pcm, + int frame_size, + int decode_fec +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Decode an Opus packet with floating point output. + * @param [in] st OpusDecoder*: Decoder state + * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss + * @param [in] len opus_int32: Number of bytes in payload + * @param [out] pcm float*: Output signal (interleaved if 2 channels). length + * is frame_size*channels*sizeof(float) + * @param [in] frame_size Number of samples per channel of available space in \a pcm. + * If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will + * not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1), + * then frame_size needs to be exactly the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the next incoming packet. For the PLC and + * FEC cases, frame_size must be a multiple of 2.5 ms. + * @param [in] decode_fec int: Flag (0 or 1) to request that any in-band forward error correction data be + * decoded. If no such data is available the frame is decoded as if it were lost. + * @returns Number of decoded samples or @ref opus_errorcodes + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode_float( + OpusDecoder *st, + const unsigned char *data, + opus_int32 len, + float *pcm, + int frame_size, + int decode_fec +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Perform a CTL function on an Opus decoder. + * + * Generally the request and subsequent arguments are generated + * by a convenience macro. + * @param st OpusDecoder*: Decoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls or + * @ref opus_decoderctls. + * @see opus_genericctls + * @see opus_decoderctls + */ +OPUS_EXPORT int opus_decoder_ctl(OpusDecoder *st, int request, ...) OPUS_ARG_NONNULL(1); + +/** Frees an OpusDecoder allocated by opus_decoder_create(). + * @param[in] st OpusDecoder*: State to be freed. + */ +OPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st); + +/** Parse an opus packet into one or more frames. + * Opus_decode will perform this operation internally so most applications do + * not need to use this function. + * This function does not copy the frames, the returned pointers are pointers into + * the input packet. + * @param [in] data char*: Opus packet to be parsed + * @param [in] len opus_int32: size of data + * @param [out] out_toc char*: TOC pointer + * @param [out] frames char*[48] encapsulated frames + * @param [out] size opus_int16[48] sizes of the encapsulated frames + * @param [out] payload_offset int*: returns the position of the payload within the packet (in bytes) + * @returns number of frames + */ +OPUS_EXPORT int opus_packet_parse( + const unsigned char *data, + opus_int32 len, + unsigned char *out_toc, + const unsigned char *frames[48], + opus_int16 size[48], + int *payload_offset +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(5); + +/** Gets the bandwidth of an Opus packet. + * @param [in] data char*: Opus packet + * @retval OPUS_BANDWIDTH_NARROWBAND Narrowband (4kHz bandpass) + * @retval OPUS_BANDWIDTH_MEDIUMBAND Mediumband (6kHz bandpass) + * @retval OPUS_BANDWIDTH_WIDEBAND Wideband (8kHz bandpass) + * @retval OPUS_BANDWIDTH_SUPERWIDEBAND Superwideband (12kHz bandpass) + * @retval OPUS_BANDWIDTH_FULLBAND Fullband (20kHz bandpass) + * @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_bandwidth(const unsigned char *data) OPUS_ARG_NONNULL(1); + +/** Gets the number of samples per frame from an Opus packet. + * @param [in] data char*: Opus packet. + * This must contain at least one byte of + * data. + * @param [in] Fs opus_int32: Sampling rate in Hz. + * This must be a multiple of 400, or + * inaccurate results will be returned. + * @returns Number of samples per frame. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_samples_per_frame(const unsigned char *data, opus_int32 Fs) OPUS_ARG_NONNULL(1); + +/** Gets the number of channels from an Opus packet. + * @param [in] data char*: Opus packet + * @returns Number of channels + * @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_channels(const unsigned char *data) OPUS_ARG_NONNULL(1); + +/** Gets the number of frames in an Opus packet. + * @param [in] packet char*: Opus packet + * @param [in] len opus_int32: Length of packet + * @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 + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1); + +/** Gets the number of samples of an Opus packet. + * @param [in] packet char*: Opus packet + * @param [in] len opus_int32: Length of packet + * @param [in] Fs opus_int32: Sampling rate in Hz. + * This must be a multiple of 400, or + * inaccurate results will be returned. + * @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 + */ +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); + +/** Gets the number of samples of an Opus packet. + * @param [in] dec OpusDecoder*: Decoder state + * @param [in] packet char*: Opus packet + * @param [in] len opus_int32: Length of packet + * @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 + */ +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 float*: Input PCM and modified PCM + * @param [in] frame_size int Number of samples per channel to process + * @param [in] channels int: Number of channels + * @param [in,out] softclip_mem float*: 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 + * @{ + * + * The repacketizer can be used to merge multiple Opus packets into a single + * packet or alternatively to split Opus packets that have previously been + * merged. Splitting valid Opus packets is always guaranteed to succeed, + * whereas merging valid packets only succeeds if all frames have the same + * mode, bandwidth, and frame size, and when the total duration of the merged + * packet is no more than 120 ms. The 120 ms limit comes from the + * specification and limits decoder memory requirements at a point where + * framing overhead becomes negligible. + * + * The repacketizer currently only operates on elementary Opus + * streams. It will not manipualte multistream packets successfully, except in + * the degenerate case where they consist of data from a single stream. + * + * The repacketizing process starts with creating a repacketizer state, either + * by calling opus_repacketizer_create() or by allocating the memory yourself, + * e.g., + * @code + * OpusRepacketizer *rp; + * rp = (OpusRepacketizer*)malloc(opus_repacketizer_get_size()); + * if (rp != NULL) + * opus_repacketizer_init(rp); + * @endcode + * + * Then the application should submit packets with opus_repacketizer_cat(), + * extract new packets with opus_repacketizer_out() or + * opus_repacketizer_out_range(), and then reset the state for the next set of + * input packets via opus_repacketizer_init(). + * + * For example, to split a sequence of packets into individual frames: + * @code + * unsigned char *data; + * int len; + * while (get_next_packet(&data, &len)) + * { + * unsigned char out[1276]; + * opus_int32 out_len; + * int nb_frames; + * int err; + * int i; + * err = opus_repacketizer_cat(rp, data, len); + * if (err != OPUS_OK) + * { + * release_packet(data); + * return err; + * } + * nb_frames = opus_repacketizer_get_nb_frames(rp); + * for (i = 0; i < nb_frames; i++) + * { + * out_len = opus_repacketizer_out_range(rp, i, i+1, out, sizeof(out)); + * if (out_len < 0) + * { + * release_packet(data); + * return (int)out_len; + * } + * output_next_packet(out, out_len); + * } + * opus_repacketizer_init(rp); + * release_packet(data); + * } + * @endcode + * + * Alternatively, to combine a sequence of frames into packets that each + * contain up to TARGET_DURATION_MS milliseconds of data: + * @code + * // The maximum number of packets with duration TARGET_DURATION_MS occurs + * // when the frame size is 2.5 ms, for a total of (TARGET_DURATION_MS*2/5) + * // packets. + * unsigned char *data[(TARGET_DURATION_MS*2/5)+1]; + * opus_int32 len[(TARGET_DURATION_MS*2/5)+1]; + * int nb_packets; + * unsigned char out[1277*(TARGET_DURATION_MS*2/2)]; + * opus_int32 out_len; + * int prev_toc; + * nb_packets = 0; + * while (get_next_packet(data+nb_packets, len+nb_packets)) + * { + * int nb_frames; + * int err; + * nb_frames = opus_packet_get_nb_frames(data[nb_packets], len[nb_packets]); + * if (nb_frames < 1) + * { + * release_packets(data, nb_packets+1); + * return nb_frames; + * } + * nb_frames += opus_repacketizer_get_nb_frames(rp); + * // If adding the next packet would exceed our target, or it has an + * // incompatible TOC sequence, output the packets we already have before + * // submitting it. + * // N.B., The nb_packets > 0 check ensures we've submitted at least one + * // packet since the last call to opus_repacketizer_init(). Otherwise a + * // single packet longer than TARGET_DURATION_MS would cause us to try to + * // output an (invalid) empty packet. It also ensures that prev_toc has + * // been set to a valid value. Additionally, len[nb_packets] > 0 is + * // guaranteed by the call to opus_packet_get_nb_frames() above, so the + * // reference to data[nb_packets][0] should be valid. + * if (nb_packets > 0 && ( + * ((prev_toc & 0xFC) != (data[nb_packets][0] & 0xFC)) || + * opus_packet_get_samples_per_frame(data[nb_packets], 48000)*nb_frames > + * TARGET_DURATION_MS*48)) + * { + * out_len = opus_repacketizer_out(rp, out, sizeof(out)); + * if (out_len < 0) + * { + * release_packets(data, nb_packets+1); + * return (int)out_len; + * } + * output_next_packet(out, out_len); + * opus_repacketizer_init(rp); + * release_packets(data, nb_packets); + * data[0] = data[nb_packets]; + * len[0] = len[nb_packets]; + * nb_packets = 0; + * } + * err = opus_repacketizer_cat(rp, data[nb_packets], len[nb_packets]); + * if (err != OPUS_OK) + * { + * release_packets(data, nb_packets+1); + * return err; + * } + * prev_toc = data[nb_packets][0]; + * nb_packets++; + * } + * // Output the final, partial packet. + * if (nb_packets > 0) + * { + * out_len = opus_repacketizer_out(rp, out, sizeof(out)); + * release_packets(data, nb_packets); + * if (out_len < 0) + * return (int)out_len; + * output_next_packet(out, out_len); + * } + * @endcode + * + * An alternate way of merging packets is to simply call opus_repacketizer_cat() + * unconditionally until it fails. At that point, the merged packet can be + * obtained with opus_repacketizer_out() and the input packet for which + * opus_repacketizer_cat() needs to be re-added to a newly reinitialized + * repacketizer state. + */ + +typedef struct OpusRepacketizer OpusRepacketizer; + +/** Gets the size of an OpusRepacketizer structure. + * @returns The size in bytes. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_size(void); + +/** (Re)initializes a previously allocated repacketizer state. + * The state must be at least the size returned by opus_repacketizer_get_size(). + * This can be used for applications which use their own allocator instead of + * malloc(). + * It must also be called to reset the queue of packets waiting to be + * repacketized, which is necessary if the maximum packet duration of 120 ms + * is reached or if you wish to submit packets with a different Opus + * configuration (coding mode, audio bandwidth, frame size, or channel count). + * Failure to do so will prevent a new packet from being added with + * opus_repacketizer_cat(). + * @see opus_repacketizer_create + * @see opus_repacketizer_get_size + * @see opus_repacketizer_cat + * @param rp OpusRepacketizer*: The repacketizer state to + * (re)initialize. + * @returns A pointer to the same repacketizer state that was passed in. + */ +OPUS_EXPORT OpusRepacketizer *opus_repacketizer_init(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1); + +/** Allocates memory and initializes the new repacketizer with + * opus_repacketizer_init(). + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusRepacketizer *opus_repacketizer_create(void); + +/** Frees an OpusRepacketizer allocated by + * opus_repacketizer_create(). + * @param[in] rp OpusRepacketizer*: State to be freed. + */ +OPUS_EXPORT void opus_repacketizer_destroy(OpusRepacketizer *rp); + +/** Add a packet to the current repacketizer state. + * This packet must match the configuration of any packets already submitted + * for repacketization since the last call to opus_repacketizer_init(). + * This means that it must have the same coding mode, audio bandwidth, frame + * size, and channel count. + * This can be checked in advance by examining the top 6 bits of the first + * byte of the packet, and ensuring they match the top 6 bits of the first + * byte of any previously submitted packet. + * The total duration of audio in the repacketizer state also must not exceed + * 120 ms, the maximum duration of a single packet, after adding this packet. + * + * The contents of the current repacketizer state can be extracted into new + * packets using opus_repacketizer_out() or opus_repacketizer_out_range(). + * + * In order to add a packet with a different configuration or to add more + * audio beyond 120 ms, you must clear the repacketizer state by calling + * opus_repacketizer_init(). + * If a packet is too large to add to the current repacketizer state, no part + * of it is added, even if it contains multiple frames, some of which might + * fit. + * If you wish to be able to add parts of such packets, you should first use + * another repacketizer to split the packet into pieces and add them + * individually. + * @see opus_repacketizer_out_range + * @see opus_repacketizer_out + * @see opus_repacketizer_init + * @param rp OpusRepacketizer*: The repacketizer state to which to + * add the packet. + * @param[in] data const unsigned char*: The packet data. + * The application must ensure + * this pointer remains valid + * until the next call to + * opus_repacketizer_init() or + * opus_repacketizer_destroy(). + * @param len opus_int32: The number of bytes in the packet data. + * @returns An error code indicating whether or not the operation succeeded. + * @retval #OPUS_OK The packet's contents have been added to the repacketizer + * state. + * @retval #OPUS_INVALID_PACKET The packet did not have a valid TOC sequence, + * the packet's TOC sequence was not compatible + * with previously submitted packets (because + * the coding mode, audio bandwidth, frame size, + * or channel count did not match), or adding + * this packet would increase the total amount of + * audio stored in the repacketizer state to more + * than 120 ms. + */ +OPUS_EXPORT int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); + + +/** Construct a new packet from data previously submitted to the repacketizer + * state via opus_repacketizer_cat(). + * @param rp OpusRepacketizer*: The repacketizer state from which to + * construct the new packet. + * @param begin int: The index of the first frame in the current + * repacketizer state to include in the output. + * @param end int: One past the index of the last frame in the + * current repacketizer state to include in the + * output. + * @param[out] data const unsigned char*: The buffer in which to + * store the output packet. + * @param maxlen opus_int32: The maximum number of bytes to store in + * the output buffer. In order to guarantee + * success, this should be at least + * 1276 for a single frame, + * or for multiple frames, + * 1277*(end-begin). + * However, 1*(end-begin) plus + * the size of all packet data submitted to + * the repacketizer since the last call to + * opus_repacketizer_init() or + * opus_repacketizer_create() is also + * sufficient, and possibly much smaller. + * @returns The total size of the output packet on success, or an error code + * on failure. + * @retval #OPUS_BAD_ARG [begin,end) was an invalid range of + * frames (begin < 0, begin >= end, or end > + * opus_repacketizer_get_nb_frames()). + * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the + * complete output packet. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Return the total number of frames contained in packet data submitted to + * the repacketizer state so far via opus_repacketizer_cat() since the last + * call to opus_repacketizer_init() or opus_repacketizer_create(). + * This defines the valid range of packets that can be extracted with + * opus_repacketizer_out_range() or opus_repacketizer_out(). + * @param rp OpusRepacketizer*: The repacketizer state containing the + * frames. + * @returns The total number of frames contained in the packet data submitted + * to the repacketizer state. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1); + +/** Construct a new packet from data previously submitted to the repacketizer + * state via opus_repacketizer_cat(). + * This is a convenience routine that returns all the data submitted so far + * in a single packet. + * It is equivalent to calling + * @code + * opus_repacketizer_out_range(rp, 0, opus_repacketizer_get_nb_frames(rp), + * data, maxlen) + * @endcode + * @param rp OpusRepacketizer*: The repacketizer state from which to + * construct the new packet. + * @param[out] data const unsigned char*: The buffer in which to + * store the output packet. + * @param maxlen opus_int32: The maximum number of bytes to store in + * the output buffer. In order to guarantee + * success, this should be at least + * 1277*opus_repacketizer_get_nb_frames(rp). + * However, + * 1*opus_repacketizer_get_nb_frames(rp) + * plus the size of all packet data + * submitted to the repacketizer since the + * last call to opus_repacketizer_init() or + * opus_repacketizer_create() is also + * sufficient, and possibly much smaller. + * @returns The total size of the output packet on success, or an error code + * on failure. + * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the + * complete output packet. + */ +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 const unsigned char*: The buffer containing the + * packet to pad. + * @param len opus_int32: The size of the packet. + * This must be at least 1. + * @param new_len opus_int32: 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 const unsigned char*: The buffer containing the + * packet to strip. + * @param len opus_int32: 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 const unsigned char*: The buffer containing the + * packet to pad. + * @param len opus_int32: The size of the packet. + * This must be at least 1. + * @param new_len opus_int32: The desired size of the packet after padding. + * This must be at least 1. + * @param nb_streams opus_int32: 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 const unsigned char*: The buffer containing the + * packet to strip. + * @param len opus_int32: The size of the packet. + * This must be at least 1. + * @param nb_streams opus_int32: 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 +} +#endif + +#endif /* OPUS_H */ diff --git a/engine/voice_codecs/opus/opus/opus_custom.h b/engine/voice_codecs/opus/opus/opus_custom.h new file mode 100644 index 00000000..41f36bf2 --- /dev/null +++ b/engine/voice_codecs/opus/opus/opus_custom.h @@ -0,0 +1,342 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Copyright (c) 2008-2012 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. +*/ + +/** + @file opus_custom.h + @brief Opus-Custom reference implementation API + */ + +#ifndef OPUS_CUSTOM_H +#define OPUS_CUSTOM_H + +#include "opus_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef CUSTOM_MODES +# define OPUS_CUSTOM_EXPORT OPUS_EXPORT +# define OPUS_CUSTOM_EXPORT_STATIC OPUS_EXPORT +#else +# define OPUS_CUSTOM_EXPORT +# ifdef OPUS_BUILD +# define OPUS_CUSTOM_EXPORT_STATIC static OPUS_INLINE +# else +# define OPUS_CUSTOM_EXPORT_STATIC +# endif +#endif + +/** @defgroup opus_custom Opus Custom + * @{ + * Opus Custom is an optional part of the Opus specification and + * reference implementation which uses a distinct API from the regular + * API and supports frame sizes that are not normally supported.\ Use + * of Opus Custom is discouraged for all but very special applications + * for which a frame size different from 2.5, 5, 10, or 20 ms is needed + * (for either complexity or latency reasons) and where interoperability + * is less important. + * + * In addition to the interoperability limitations the use of Opus custom + * disables a substantial chunk of the codec and generally lowers the + * quality available at a given bitrate. Normally when an application needs + * a different frame size from the codec it should buffer to match the + * sizes but this adds a small amount of delay which may be important + * in some very low latency applications. Some transports (especially + * constant rate RF transports) may also work best with frames of + * particular durations. + * + * Libopus only supports custom modes if they are enabled at compile time. + * + * The Opus Custom API is similar to the regular API but the + * @ref opus_encoder_create and @ref opus_decoder_create calls take + * an additional mode parameter which is a structure produced by + * a call to @ref opus_custom_mode_create. Both the encoder and decoder + * must create a mode using the same sample rate (fs) and frame size + * (frame size) so these parameters must either be signaled out of band + * or fixed in a particular implementation. + * + * Similar to regular Opus the custom modes support on the fly frame size + * switching, but the sizes available depend on the particular frame size in + * use. For some initial frame sizes on a single on the fly size is available. + */ + +/** Contains the state of an encoder. One encoder state is needed + for each stream. It is initialized once at the beginning of the + stream. Do *not* re-initialize the state for every frame. + @brief Encoder state + */ +typedef struct OpusCustomEncoder OpusCustomEncoder; + +/** State of the decoder. One decoder state is needed for each stream. + It is initialized once at the beginning of the stream. Do *not* + re-initialize the state for every frame. + @brief Decoder state + */ +typedef struct OpusCustomDecoder OpusCustomDecoder; + +/** The mode contains all the information necessary to create an + encoder. Both the encoder and decoder need to be initialized + with exactly the same mode, otherwise the output will be + corrupted. + @brief Mode configuration + */ +typedef struct OpusCustomMode OpusCustomMode; + +/** Creates a new mode struct. This will be passed to an encoder or + * decoder. The mode MUST NOT BE DESTROYED until the encoders and + * decoders that use it are destroyed as well. + * @param [in] Fs int: Sampling rate (8000 to 96000 Hz) + * @param [in] frame_size int: Number of samples (per channel) to encode in each + * packet (64 - 1024, prime factorization must contain zero or more 2s, 3s, or 5s and no other primes) + * @param [out] error int*: Returned error code (if NULL, no error will be returned) + * @return A newly created mode + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error); + +/** Destroys a mode struct. Only call this after all encoders and + * decoders using this mode are destroyed as well. + * @param [in] mode OpusCustomMode*: Mode to be freed. + */ +OPUS_CUSTOM_EXPORT void opus_custom_mode_destroy(OpusCustomMode *mode); + + +#if !defined(OPUS_BUILD) || defined(CELT_ENCODER_C) + +/* Encoder */ +/** Gets the size of an OpusCustomEncoder structure. + * @param [in] mode OpusCustomMode *: Mode configuration + * @param [in] channels int: Number of channels + * @returns size + */ +OPUS_CUSTOM_EXPORT_STATIC OPUS_WARN_UNUSED_RESULT int opus_custom_encoder_get_size( + const OpusCustomMode *mode, + int channels +) 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 OpusCustomEncoder*: Encoder state + * @param [in] mode OpusCustomMode *: Contains all the information about the characteristics of + * the stream (must be the same characteristics as used for the + * decoder) + * @param [in] channels int: 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 + * state (can't be shared across simultaneous streams). + * @param [in] mode OpusCustomMode*: Contains all the information about the characteristics of + * the stream (must be the same characteristics as used for the + * decoder) + * @param [in] channels int: Number of channels + * @param [out] error int*: Returns an error code + * @return Newly created encoder state. +*/ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomEncoder *opus_custom_encoder_create( + const OpusCustomMode *mode, + int channels, + int *error +) OPUS_ARG_NONNULL(1); + + +/** Destroys a an encoder state. + * @param[in] st OpusCustomEncoder*: State to be freed. + */ +OPUS_CUSTOM_EXPORT void opus_custom_encoder_destroy(OpusCustomEncoder *st); + +/** Encodes a frame of audio. + * @param [in] st OpusCustomEncoder*: Encoder state + * @param [in] pcm float*: PCM audio in float format, with a normal range of +/-1.0. + * Samples with a range beyond +/-1.0 are supported but will + * be clipped by decoders using the integer API and should + * only be used if it is known that the far end supports + * extended dynamic range. There must be exactly + * frame_size samples per channel. + * @param [in] frame_size int: Number of samples per frame of input signal + * @param [out] compressed char *: The compressed data is written here. This may not alias pcm and must be at least maxCompressedBytes long. + * @param [in] maxCompressedBytes int: Maximum number of bytes to use for compressing the frame + * (can change from one frame to another) + * @return Number of bytes written to "compressed". + * If negative, an error has occurred (see error codes). It is IMPORTANT that + * the length returned be somehow transmitted to the decoder. Otherwise, no + * decoding is possible. + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode_float( + OpusCustomEncoder *st, + const float *pcm, + int frame_size, + unsigned char *compressed, + int maxCompressedBytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Encodes a frame of audio. + * @param [in] st OpusCustomEncoder*: Encoder state + * @param [in] pcm opus_int16*: PCM audio in signed 16-bit format (native endian). + * There must be exactly frame_size samples per channel. + * @param [in] frame_size int: Number of samples per frame of input signal + * @param [out] compressed char *: The compressed data is written here. This may not alias pcm and must be at least maxCompressedBytes long. + * @param [in] maxCompressedBytes int: Maximum number of bytes to use for compressing the frame + * (can change from one frame to another) + * @return Number of bytes written to "compressed". + * If negative, an error has occurred (see error codes). It is IMPORTANT that + * the length returned be somehow transmitted to the decoder. Otherwise, no + * decoding is possible. + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode( + OpusCustomEncoder *st, + const opus_int16 *pcm, + int frame_size, + unsigned char *compressed, + int maxCompressedBytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Perform a CTL function on an Opus custom encoder. + * + * Generally the request and subsequent arguments are generated + * by a convenience macro. + * @see opus_encoderctls + */ +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 */ + +/** Gets the size of an OpusCustomDecoder structure. + * @param [in] mode OpusCustomMode *: Mode configuration + * @param [in] channels int: Number of channels + * @returns size + */ +OPUS_CUSTOM_EXPORT_STATIC OPUS_WARN_UNUSED_RESULT int opus_custom_decoder_get_size( + const OpusCustomMode *mode, + int channels +) OPUS_ARG_NONNULL(1); + +/** Initializes a previously allocated decoder state + * 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. + * @see opus_custom_decoder_create(),opus_custom_decoder_get_size() + * To reset a previously initialized state use the OPUS_RESET_STATE CTL. + * @param [in] st OpusCustomDecoder*: Decoder state + * @param [in] mode OpusCustomMode *: Contains all the information about the characteristics of + * the stream (must be the same characteristics as used for the + * encoder) + * @param [in] channels int: Number of channels + * @return OPUS_OK Success or @ref opus_errorcodes + */ +OPUS_CUSTOM_EXPORT_STATIC int opus_custom_decoder_init( + OpusCustomDecoder *st, + const OpusCustomMode *mode, + int channels +) 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 OpusCustomMode: Contains all the information about the characteristics of the + * stream (must be the same characteristics as used for the encoder) + * @param [in] channels int: Number of channels + * @param [out] error int*: 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. + * @param[in] st OpusCustomDecoder*: State to be freed. + */ +OPUS_CUSTOM_EXPORT void opus_custom_decoder_destroy(OpusCustomDecoder *st); + +/** Decode an opus custom frame with floating point output + * @param [in] st OpusCustomDecoder*: Decoder state + * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss + * @param [in] len int: Number of bytes in payload + * @param [out] pcm float*: Output signal (interleaved if 2 channels). length + * is frame_size*channels*sizeof(float) + * @param [in] frame_size Number of samples per channel of available space in *pcm. + * @returns Number of decoded samples or @ref opus_errorcodes + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_decode_float( + OpusCustomDecoder *st, + const unsigned char *data, + int len, + float *pcm, + int frame_size +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Decode an opus custom frame + * @param [in] st OpusCustomDecoder*: Decoder state + * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss + * @param [in] len int: Number of bytes in payload + * @param [out] pcm opus_int16*: Output signal (interleaved if 2 channels). length + * is frame_size*channels*sizeof(opus_int16) + * @param [in] frame_size Number of samples per channel of available space in *pcm. + * @returns Number of decoded samples or @ref opus_errorcodes + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_decode( + OpusCustomDecoder *st, + const unsigned char *data, + int len, + opus_int16 *pcm, + int frame_size +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Perform a CTL function on an Opus custom decoder. + * + * Generally the request and subsequent arguments are generated + * by a convenience macro. + * @see opus_genericctls + */ +OPUS_CUSTOM_EXPORT int opus_custom_decoder_ctl(OpusCustomDecoder * OPUS_RESTRICT st, int request, ...) OPUS_ARG_NONNULL(1); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* OPUS_CUSTOM_H */ diff --git a/engine/voice_codecs/opus/opus/opus_defines.h b/engine/voice_codecs/opus/opus/opus_defines.h new file mode 100644 index 00000000..d141418b --- /dev/null +++ b/engine/voice_codecs/opus/opus/opus_defines.h @@ -0,0 +1,799 @@ +/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited + Written by Jean-Marc Valin and Koen Vos */ +/* + 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. +*/ + +/** + * @file opus_defines.h + * @brief Opus reference implementation constants + */ + +#ifndef OPUS_DEFINES_H +#define OPUS_DEFINES_H + +#include "opus_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup opus_errorcodes Error codes + * @{ + */ +/** No error @hideinitializer*/ +#define OPUS_OK 0 +/** One or more invalid/out of range arguments @hideinitializer*/ +#define OPUS_BAD_ARG -1 +/** Not enough bytes allocated in the buffer @hideinitializer*/ +#define OPUS_BUFFER_TOO_SMALL -2 +/** An internal error was detected @hideinitializer*/ +#define OPUS_INTERNAL_ERROR -3 +/** The compressed data passed is corrupted @hideinitializer*/ +#define OPUS_INVALID_PACKET -4 +/** Invalid/unsupported request number @hideinitializer*/ +#define OPUS_UNIMPLEMENTED -5 +/** An encoder or decoder structure is invalid or already freed @hideinitializer*/ +#define OPUS_INVALID_STATE -6 +/** Memory allocation has failed @hideinitializer*/ +#define OPUS_ALLOC_FAIL -7 +/**@}*/ + +/** @cond OPUS_INTERNAL_DOC */ +/**Export control for opus functions */ + +#ifndef OPUS_EXPORT +# if defined(WIN32) +# if defined(OPUS_BUILD) && defined(DLL_EXPORT) +# define OPUS_EXPORT __declspec(dllexport) +# else +# define OPUS_EXPORT +# endif +# elif defined(__GNUC__) && defined(OPUS_BUILD) +# define OPUS_EXPORT __attribute__ ((visibility ("default"))) +# else +# define OPUS_EXPORT +# endif +#endif + +# if !defined(OPUS_GNUC_PREREQ) +# if defined(__GNUC__)&&defined(__GNUC_MINOR__) +# define OPUS_GNUC_PREREQ(_maj,_min) \ + ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min)) +# else +# define OPUS_GNUC_PREREQ(_maj,_min) 0 +# endif +# endif + +#if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) +# if OPUS_GNUC_PREREQ(3,0) +# define OPUS_RESTRICT __restrict__ +# elif (defined(_MSC_VER) && _MSC_VER >= 1400) +# define OPUS_RESTRICT __restrict +# else +# define OPUS_RESTRICT +# endif +#else +# define OPUS_RESTRICT restrict +#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 + * NONNULL is not used in OPUS_BUILD to avoid the compiler optimizing out + * some paranoid null checks. */ +#if defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4) +# define OPUS_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__)) +#else +# define OPUS_WARN_UNUSED_RESULT +#endif +#if !defined(OPUS_BUILD) && defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4) +# define OPUS_ARG_NONNULL(_x) __attribute__ ((__nonnull__(_x))) +#else +# define OPUS_ARG_NONNULL(_x) +#endif + +/** These are the actual Encoder CTL ID numbers. + * They should not be used directly by applications. + * In general, SETs should be even and GETs should be odd.*/ +#define OPUS_SET_APPLICATION_REQUEST 4000 +#define OPUS_GET_APPLICATION_REQUEST 4001 +#define OPUS_SET_BITRATE_REQUEST 4002 +#define OPUS_GET_BITRATE_REQUEST 4003 +#define OPUS_SET_MAX_BANDWIDTH_REQUEST 4004 +#define OPUS_GET_MAX_BANDWIDTH_REQUEST 4005 +#define OPUS_SET_VBR_REQUEST 4006 +#define OPUS_GET_VBR_REQUEST 4007 +#define OPUS_SET_BANDWIDTH_REQUEST 4008 +#define OPUS_GET_BANDWIDTH_REQUEST 4009 +#define OPUS_SET_COMPLEXITY_REQUEST 4010 +#define OPUS_GET_COMPLEXITY_REQUEST 4011 +#define OPUS_SET_INBAND_FEC_REQUEST 4012 +#define OPUS_GET_INBAND_FEC_REQUEST 4013 +#define OPUS_SET_PACKET_LOSS_PERC_REQUEST 4014 +#define OPUS_GET_PACKET_LOSS_PERC_REQUEST 4015 +#define OPUS_SET_DTX_REQUEST 4016 +#define OPUS_GET_DTX_REQUEST 4017 +#define OPUS_SET_VBR_CONSTRAINT_REQUEST 4020 +#define OPUS_GET_VBR_CONSTRAINT_REQUEST 4021 +#define OPUS_SET_FORCE_CHANNELS_REQUEST 4022 +#define OPUS_GET_FORCE_CHANNELS_REQUEST 4023 +#define OPUS_SET_SIGNAL_REQUEST 4024 +#define OPUS_GET_SIGNAL_REQUEST 4025 +#define OPUS_GET_LOOKAHEAD_REQUEST 4027 +/* #define OPUS_RESET_STATE 4028 */ +#define OPUS_GET_SAMPLE_RATE_REQUEST 4029 +#define OPUS_GET_FINAL_RANGE_REQUEST 4031 +#define OPUS_GET_PITCH_REQUEST 4033 +#define OPUS_SET_GAIN_REQUEST 4034 +#define OPUS_GET_GAIN_REQUEST 4045 /* Should have been 4035 */ +#define OPUS_SET_LSB_DEPTH_REQUEST 4036 +#define OPUS_GET_LSB_DEPTH_REQUEST 4037 +#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 */ +#define OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST 4046 +#define OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST 4047 +#define OPUS_GET_IN_DTX_REQUEST 4049 + +/** Defines for the presence of extended APIs. */ +#define OPUS_HAVE_OPUS_PROJECTION_H + +/* Macros to trigger compilation errors when the wrong types are provided to a CTL */ +#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_uint_ptr(ptr) ((ptr) + ((ptr) - (opus_uint32*)(ptr))) +#define __opus_check_val16_ptr(ptr) ((ptr) + ((ptr) - (opus_val16*)(ptr))) +/** @endcond */ + +/** @defgroup opus_ctlvalues Pre-defined values for CTL interface + * @see opus_genericctls, opus_encoderctls + * @{ + */ +/* Values for the various encoder CTLs */ +#define OPUS_AUTO -1000 /**opus_int32: Allowed values: 0-10, inclusive. + * + * @hideinitializer */ +#define OPUS_SET_COMPLEXITY(x) OPUS_SET_COMPLEXITY_REQUEST, __opus_check_int(x) +/** Gets the encoder's complexity configuration. + * @see OPUS_SET_COMPLEXITY + * @param[out] x opus_int32 *: Returns a value in the range 0-10, + * inclusive. + * @hideinitializer */ +#define OPUS_GET_COMPLEXITY(x) OPUS_GET_COMPLEXITY_REQUEST, __opus_check_int_ptr(x) + +/** Configures the bitrate in the encoder. + * Rates from 500 to 512000 bits per second are meaningful, as well as the + * special values #OPUS_AUTO and #OPUS_BITRATE_MAX. + * The value #OPUS_BITRATE_MAX can be used to cause the codec to use as much + * rate as it can, which is useful for controlling the rate by adjusting the + * output buffer size. + * @see OPUS_GET_BITRATE + * @param[in] x opus_int32: Bitrate in bits per second. The default + * is determined based on the number of + * channels and the input sampling rate. + * @hideinitializer */ +#define OPUS_SET_BITRATE(x) OPUS_SET_BITRATE_REQUEST, __opus_check_int(x) +/** Gets the encoder's bitrate configuration. + * @see OPUS_SET_BITRATE + * @param[out] x opus_int32 *: Returns the bitrate in bits per second. + * The default is determined based on the + * number of channels and the input + * sampling rate. + * @hideinitializer */ +#define OPUS_GET_BITRATE(x) OPUS_GET_BITRATE_REQUEST, __opus_check_int_ptr(x) + +/** Enables or disables variable bitrate (VBR) in the encoder. + * The configured bitrate may not be met exactly because frames must + * be an integer number of bytes in length. + * @see OPUS_GET_VBR + * @see OPUS_SET_VBR_CONSTRAINT + * @param[in] x opus_int32: Allowed values: + *
+ *
0
Hard CBR. For LPC/hybrid modes at very low bit-rate, this can + * cause noticeable quality degradation.
+ *
1
VBR (default). The exact type of VBR is controlled by + * #OPUS_SET_VBR_CONSTRAINT.
+ *
+ * @hideinitializer */ +#define OPUS_SET_VBR(x) OPUS_SET_VBR_REQUEST, __opus_check_int(x) +/** Determine if variable bitrate (VBR) is enabled in the encoder. + * @see OPUS_SET_VBR + * @see OPUS_GET_VBR_CONSTRAINT + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
0
Hard CBR.
+ *
1
VBR (default). The exact type of VBR may be retrieved via + * #OPUS_GET_VBR_CONSTRAINT.
+ *
+ * @hideinitializer */ +#define OPUS_GET_VBR(x) OPUS_GET_VBR_REQUEST, __opus_check_int_ptr(x) + +/** Enables or disables constrained VBR in the encoder. + * This setting is ignored when the encoder is in CBR mode. + * @warning Only the MDCT mode of Opus currently heeds the constraint. + * Speech mode ignores it completely, hybrid mode may fail to obey it + * if the LPC layer uses more bitrate than the constraint would have + * permitted. + * @see OPUS_GET_VBR_CONSTRAINT + * @see OPUS_SET_VBR + * @param[in] x opus_int32: Allowed values: + *
+ *
0
Unconstrained VBR.
+ *
1
Constrained VBR (default). This creates a maximum of one + * frame of buffering delay assuming a transport with a + * serialization speed of the nominal bitrate.
+ *
+ * @hideinitializer */ +#define OPUS_SET_VBR_CONSTRAINT(x) OPUS_SET_VBR_CONSTRAINT_REQUEST, __opus_check_int(x) +/** Determine if constrained VBR is enabled in the encoder. + * @see OPUS_SET_VBR_CONSTRAINT + * @see OPUS_GET_VBR + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
0
Unconstrained VBR.
+ *
1
Constrained VBR (default).
+ *
+ * @hideinitializer */ +#define OPUS_GET_VBR_CONSTRAINT(x) OPUS_GET_VBR_CONSTRAINT_REQUEST, __opus_check_int_ptr(x) + +/** Configures mono/stereo forcing in the encoder. + * This can force the encoder to produce packets encoded as either mono or + * stereo, regardless of the format of the input audio. This is useful when + * the caller knows that the input signal is currently a mono source embedded + * in a stereo stream. + * @see OPUS_GET_FORCE_CHANNELS + * @param[in] x opus_int32: Allowed values: + *
+ *
#OPUS_AUTO
Not forced (default)
+ *
1
Forced mono
+ *
2
Forced stereo
+ *
+ * @hideinitializer */ +#define OPUS_SET_FORCE_CHANNELS(x) OPUS_SET_FORCE_CHANNELS_REQUEST, __opus_check_int(x) +/** Gets the encoder's forced channel configuration. + * @see OPUS_SET_FORCE_CHANNELS + * @param[out] x opus_int32 *: + *
+ *
#OPUS_AUTO
Not forced (default)
+ *
1
Forced mono
+ *
2
Forced stereo
+ *
+ * @hideinitializer */ +#define OPUS_GET_FORCE_CHANNELS(x) OPUS_GET_FORCE_CHANNELS_REQUEST, __opus_check_int_ptr(x) + +/** Configures the maximum bandpass that the encoder will select automatically. + * Applications should normally use this instead of #OPUS_SET_BANDWIDTH + * (leaving that set to the default, #OPUS_AUTO). This allows the + * application to set an upper bound based on the type of input it is + * providing, but still gives the encoder the freedom to reduce the bandpass + * when the bitrate becomes too low, for better overall quality. + * @see OPUS_GET_MAX_BANDWIDTH + * @param[in] x opus_int32: Allowed values: + *
+ *
OPUS_BANDWIDTH_NARROWBAND
4 kHz passband
+ *
OPUS_BANDWIDTH_MEDIUMBAND
6 kHz passband
+ *
OPUS_BANDWIDTH_WIDEBAND
8 kHz passband
+ *
OPUS_BANDWIDTH_SUPERWIDEBAND
12 kHz passband
+ *
OPUS_BANDWIDTH_FULLBAND
20 kHz passband (default)
+ *
+ * @hideinitializer */ +#define OPUS_SET_MAX_BANDWIDTH(x) OPUS_SET_MAX_BANDWIDTH_REQUEST, __opus_check_int(x) + +/** Gets the encoder's configured maximum allowed bandpass. + * @see OPUS_SET_MAX_BANDWIDTH + * @param[out] x opus_int32 *: Allowed values: + *
+ *
#OPUS_BANDWIDTH_NARROWBAND
4 kHz passband
+ *
#OPUS_BANDWIDTH_MEDIUMBAND
6 kHz passband
+ *
#OPUS_BANDWIDTH_WIDEBAND
8 kHz passband
+ *
#OPUS_BANDWIDTH_SUPERWIDEBAND
12 kHz passband
+ *
#OPUS_BANDWIDTH_FULLBAND
20 kHz passband (default)
+ *
+ * @hideinitializer */ +#define OPUS_GET_MAX_BANDWIDTH(x) OPUS_GET_MAX_BANDWIDTH_REQUEST, __opus_check_int_ptr(x) + +/** Sets the encoder's bandpass to a specific value. + * This prevents the encoder from automatically selecting the bandpass based + * on the available bitrate. If an application knows the bandpass of the input + * audio it is providing, it should normally use #OPUS_SET_MAX_BANDWIDTH + * instead, which still gives the encoder the freedom to reduce the bandpass + * when the bitrate becomes too low, for better overall quality. + * @see OPUS_GET_BANDWIDTH + * @param[in] x opus_int32: Allowed values: + *
+ *
#OPUS_AUTO
(default)
+ *
#OPUS_BANDWIDTH_NARROWBAND
4 kHz passband
+ *
#OPUS_BANDWIDTH_MEDIUMBAND
6 kHz passband
+ *
#OPUS_BANDWIDTH_WIDEBAND
8 kHz passband
+ *
#OPUS_BANDWIDTH_SUPERWIDEBAND
12 kHz passband
+ *
#OPUS_BANDWIDTH_FULLBAND
20 kHz passband
+ *
+ * @hideinitializer */ +#define OPUS_SET_BANDWIDTH(x) OPUS_SET_BANDWIDTH_REQUEST, __opus_check_int(x) + +/** Configures the type of signal being encoded. + * This is a hint which helps the encoder's mode selection. + * @see OPUS_GET_SIGNAL + * @param[in] x opus_int32: Allowed values: + *
+ *
#OPUS_AUTO
(default)
+ *
#OPUS_SIGNAL_VOICE
Bias thresholds towards choosing LPC or Hybrid modes.
+ *
#OPUS_SIGNAL_MUSIC
Bias thresholds towards choosing MDCT modes.
+ *
+ * @hideinitializer */ +#define OPUS_SET_SIGNAL(x) OPUS_SET_SIGNAL_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured signal type. + * @see OPUS_SET_SIGNAL + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
#OPUS_AUTO
(default)
+ *
#OPUS_SIGNAL_VOICE
Bias thresholds towards choosing LPC or Hybrid modes.
+ *
#OPUS_SIGNAL_MUSIC
Bias thresholds towards choosing MDCT modes.
+ *
+ * @hideinitializer */ +#define OPUS_GET_SIGNAL(x) OPUS_GET_SIGNAL_REQUEST, __opus_check_int_ptr(x) + + +/** Configures the encoder's intended application. + * The initial value is a mandatory argument to the encoder_create function. + * @see OPUS_GET_APPLICATION + * @param[in] x opus_int32: Returns one of the following values: + *
+ *
#OPUS_APPLICATION_VOIP
+ *
Process signal for improved speech intelligibility.
+ *
#OPUS_APPLICATION_AUDIO
+ *
Favor faithfulness to the original input.
+ *
#OPUS_APPLICATION_RESTRICTED_LOWDELAY
+ *
Configure the minimum possible coding delay by disabling certain modes + * of operation.
+ *
+ * @hideinitializer */ +#define OPUS_SET_APPLICATION(x) OPUS_SET_APPLICATION_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured application. + * @see OPUS_SET_APPLICATION + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
#OPUS_APPLICATION_VOIP
+ *
Process signal for improved speech intelligibility.
+ *
#OPUS_APPLICATION_AUDIO
+ *
Favor faithfulness to the original input.
+ *
#OPUS_APPLICATION_RESTRICTED_LOWDELAY
+ *
Configure the minimum possible coding delay by disabling certain modes + * of operation.
+ *
+ * @hideinitializer */ +#define OPUS_GET_APPLICATION(x) OPUS_GET_APPLICATION_REQUEST, __opus_check_int_ptr(x) + +/** Gets the total samples of delay added by the entire codec. + * This can be queried by the encoder and then the provided number of samples can be + * skipped on from the start of the decoder's output to provide time aligned input + * and output. From the perspective of a decoding application the real data begins this many + * samples late. + * + * The decoder contribution to this delay is identical for all decoders, but the + * encoder portion of the delay may vary from implementation to implementation, + * version to version, or even depend on the encoder's initial configuration. + * Applications needing delay compensation should call this CTL rather than + * hard-coding a value. + * @param[out] x opus_int32 *: Number of lookahead samples + * @hideinitializer */ +#define OPUS_GET_LOOKAHEAD(x) OPUS_GET_LOOKAHEAD_REQUEST, __opus_check_int_ptr(x) + +/** Configures the encoder's use of inband forward error correction (FEC). + * @note This is only applicable to the LPC layer + * @see OPUS_GET_INBAND_FEC + * @param[in] x opus_int32: Allowed values: + *
+ *
0
Disable inband FEC (default).
+ *
1
Enable inband FEC.
+ *
+ * @hideinitializer */ +#define OPUS_SET_INBAND_FEC(x) OPUS_SET_INBAND_FEC_REQUEST, __opus_check_int(x) +/** Gets encoder's configured use of inband forward error correction. + * @see OPUS_SET_INBAND_FEC + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
0
Inband FEC disabled (default).
+ *
1
Inband FEC enabled.
+ *
+ * @hideinitializer */ +#define OPUS_GET_INBAND_FEC(x) OPUS_GET_INBAND_FEC_REQUEST, __opus_check_int_ptr(x) + +/** Configures the encoder's expected packet loss percentage. + * Higher values trigger progressively more loss resistant behavior in the encoder + * at the expense of quality at a given bitrate in the absence of packet loss, but + * greater quality under loss. + * @see OPUS_GET_PACKET_LOSS_PERC + * @param[in] x opus_int32: Loss percentage in the range 0-100, inclusive (default: 0). + * @hideinitializer */ +#define OPUS_SET_PACKET_LOSS_PERC(x) OPUS_SET_PACKET_LOSS_PERC_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured packet loss percentage. + * @see OPUS_SET_PACKET_LOSS_PERC + * @param[out] x opus_int32 *: Returns the configured loss percentage + * in the range 0-100, inclusive (default: 0). + * @hideinitializer */ +#define OPUS_GET_PACKET_LOSS_PERC(x) OPUS_GET_PACKET_LOSS_PERC_REQUEST, __opus_check_int_ptr(x) + +/** Configures the encoder's use of discontinuous transmission (DTX). + * @note This is only applicable to the LPC layer + * @see OPUS_GET_DTX + * @param[in] x opus_int32: Allowed values: + *
+ *
0
Disable DTX (default).
+ *
1
Enabled DTX.
+ *
+ * @hideinitializer */ +#define OPUS_SET_DTX(x) OPUS_SET_DTX_REQUEST, __opus_check_int(x) +/** Gets encoder's configured use of discontinuous transmission. + * @see OPUS_SET_DTX + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
0
DTX disabled (default).
+ *
1
DTX enabled.
+ *
+ * @hideinitializer */ +#define OPUS_GET_DTX(x) OPUS_GET_DTX_REQUEST, __opus_check_int_ptr(x) +/** Configures the depth of signal being encoded. + * + * This is a hint which helps the encoder identify silence and near-silence. + * It represents the number of significant bits of linear intensity below + * which the signal contains ignorable quantization or other noise. + * + * For example, OPUS_SET_LSB_DEPTH(14) would be an appropriate setting + * for G.711 u-law input. OPUS_SET_LSB_DEPTH(16) would be appropriate + * for 16-bit linear pcm input with opus_encode_float(). + * + * When using opus_encode() instead of opus_encode_float(), or when libopus + * is compiled for fixed-point, the encoder uses the minimum of the value + * set here and the value 16. + * + * @see OPUS_GET_LSB_DEPTH + * @param[in] x opus_int32: Input precision in bits, between 8 and 24 + * (default: 24). + * @hideinitializer */ +#define OPUS_SET_LSB_DEPTH(x) OPUS_SET_LSB_DEPTH_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured signal depth. + * @see OPUS_SET_LSB_DEPTH + * @param[out] x opus_int32 *: Input precision in bits, between 8 and + * 24 (default: 24). + * @hideinitializer */ +#define OPUS_GET_LSB_DEPTH(x) OPUS_GET_LSB_DEPTH_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 really + * know what you are doing. + * @see OPUS_GET_EXPERT_FRAME_DURATION + * @param[in] x opus_int32: Allowed values: + *
+ *
OPUS_FRAMESIZE_ARG
Select frame size from the argument (default).
+ *
OPUS_FRAMESIZE_2_5_MS
Use 2.5 ms frames.
+ *
OPUS_FRAMESIZE_5_MS
Use 5 ms frames.
+ *
OPUS_FRAMESIZE_10_MS
Use 10 ms frames.
+ *
OPUS_FRAMESIZE_20_MS
Use 20 ms frames.
+ *
OPUS_FRAMESIZE_40_MS
Use 40 ms frames.
+ *
OPUS_FRAMESIZE_60_MS
Use 60 ms frames.
+ *
OPUS_FRAMESIZE_80_MS
Use 80 ms frames.
+ *
OPUS_FRAMESIZE_100_MS
Use 100 ms frames.
+ *
OPUS_FRAMESIZE_120_MS
Use 120 ms frames.
+ *
+ * @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_FRAME_DURATION + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
OPUS_FRAMESIZE_ARG
Select frame size from the argument (default).
+ *
OPUS_FRAMESIZE_2_5_MS
Use 2.5 ms frames.
+ *
OPUS_FRAMESIZE_5_MS
Use 5 ms frames.
+ *
OPUS_FRAMESIZE_10_MS
Use 10 ms frames.
+ *
OPUS_FRAMESIZE_20_MS
Use 20 ms frames.
+ *
OPUS_FRAMESIZE_40_MS
Use 40 ms frames.
+ *
OPUS_FRAMESIZE_60_MS
Use 60 ms frames.
+ *
OPUS_FRAMESIZE_80_MS
Use 80 ms frames.
+ *
OPUS_FRAMESIZE_100_MS
Use 100 ms frames.
+ *
OPUS_FRAMESIZE_120_MS
Use 120 ms frames.
+ *
+ * @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. + * @see OPUS_GET_PREDICTION_DISABLED + * @param[in] x opus_int32: Allowed values: + *
+ *
0
Enable prediction (default).
+ *
1
Disable prediction.
+ *
+ * @hideinitializer */ +#define OPUS_SET_PREDICTION_DISABLED(x) OPUS_SET_PREDICTION_DISABLED_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured prediction status. + * @see OPUS_SET_PREDICTION_DISABLED + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
0
Prediction enabled (default).
+ *
1
Prediction disabled.
+ *
+ * @hideinitializer */ +#define OPUS_GET_PREDICTION_DISABLED(x) OPUS_GET_PREDICTION_DISABLED_REQUEST, __opus_check_int_ptr(x) + +/**@}*/ + +/** @defgroup opus_genericctls Generic CTLs + * + * These macros are used with the \c opus_decoder_ctl and + * \c opus_encoder_ctl calls to generate a particular + * request. + * + * When called on an \c OpusDecoder they apply to that + * particular decoder instance. When called on an + * \c OpusEncoder they apply to the corresponding setting + * on that encoder instance, if present. + * + * Some usage examples: + * + * @code + * int ret; + * opus_int32 pitch; + * ret = opus_decoder_ctl(dec_ctx, OPUS_GET_PITCH(&pitch)); + * if (ret == OPUS_OK) return ret; + * + * opus_encoder_ctl(enc_ctx, OPUS_RESET_STATE); + * opus_decoder_ctl(dec_ctx, OPUS_RESET_STATE); + * + * opus_int32 enc_bw, dec_bw; + * opus_encoder_ctl(enc_ctx, OPUS_GET_BANDWIDTH(&enc_bw)); + * opus_decoder_ctl(dec_ctx, OPUS_GET_BANDWIDTH(&dec_bw)); + * if (enc_bw != dec_bw) { + * printf("packet bandwidth mismatch!\n"); + * } + * @endcode + * + * @see opus_encoder, opus_decoder_ctl, opus_encoder_ctl, opus_decoderctls, opus_encoderctls + * @{ + */ + +/** Resets the codec state to be equivalent to a freshly initialized state. + * This should be called when switching streams in order to prevent + * the back to back decoding from giving different results from + * one at a time decoding. + * @hideinitializer */ +#define OPUS_RESET_STATE 4028 + +/** Gets the final state of the codec's entropy coder. + * This is used for testing purposes, + * The encoder and decoder state should be identical after coding a payload + * (assuming no data corruption or software bugs) + * + * @param[out] x opus_uint32 *: Entropy coder state + * + * @hideinitializer */ +#define OPUS_GET_FINAL_RANGE(x) OPUS_GET_FINAL_RANGE_REQUEST, __opus_check_uint_ptr(x) + +/** Gets the encoder's configured bandpass or the decoder's last bandpass. + * @see OPUS_SET_BANDWIDTH + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
#OPUS_AUTO
(default)
+ *
#OPUS_BANDWIDTH_NARROWBAND
4 kHz passband
+ *
#OPUS_BANDWIDTH_MEDIUMBAND
6 kHz passband
+ *
#OPUS_BANDWIDTH_WIDEBAND
8 kHz passband
+ *
#OPUS_BANDWIDTH_SUPERWIDEBAND
12 kHz passband
+ *
#OPUS_BANDWIDTH_FULLBAND
20 kHz passband
+ *
+ * @hideinitializer */ +#define OPUS_GET_BANDWIDTH(x) OPUS_GET_BANDWIDTH_REQUEST, __opus_check_int_ptr(x) + +/** Gets the sampling rate the encoder or decoder was initialized with. + * This simply returns the Fs value passed to opus_encoder_init() + * or opus_decoder_init(). + * @param[out] x opus_int32 *: Sampling rate of encoder or decoder. + * @hideinitializer + */ +#define OPUS_GET_SAMPLE_RATE(x) OPUS_GET_SAMPLE_RATE_REQUEST, __opus_check_int_ptr(x) + +/** If set to 1, disables the use of phase inversion for intensity stereo, + * improving the quality of mono downmixes, but slightly reducing normal + * stereo quality. Disabling phase inversion in the decoder does not comply + * with RFC 6716, although it does not cause any interoperability issue and + * is expected to become part of the Opus standard once RFC 6716 is updated + * by draft-ietf-codec-opus-update. + * @see OPUS_GET_PHASE_INVERSION_DISABLED + * @param[in] x opus_int32: Allowed values: + *
+ *
0
Enable phase inversion (default).
+ *
1
Disable phase inversion.
+ *
+ * @hideinitializer */ +#define OPUS_SET_PHASE_INVERSION_DISABLED(x) OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured phase inversion status. + * @see OPUS_SET_PHASE_INVERSION_DISABLED + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
0
Stereo phase inversion enabled (default).
+ *
1
Stereo phase inversion disabled.
+ *
+ * @hideinitializer */ +#define OPUS_GET_PHASE_INVERSION_DISABLED(x) OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, __opus_check_int_ptr(x) +/** Gets the DTX state of the encoder. + * Returns whether the last encoded frame was either a comfort noise update + * during DTX or not encoded because of DTX. + * @param[out] x opus_int32 *: Returns one of the following values: + *
+ *
0
The encoder is not in DTX.
+ *
1
The encoder is in DTX.
+ *
+ * @hideinitializer */ +#define OPUS_GET_IN_DTX(x) OPUS_GET_IN_DTX_REQUEST, __opus_check_int_ptr(x) + +/**@}*/ + +/** @defgroup opus_decoderctls Decoder related CTLs + * @see opus_genericctls, opus_encoderctls, opus_decoder + * @{ + */ + +/** Configures decoder gain adjustment. + * Scales the decoded output by a factor specified in Q8 dB units. + * This has a maximum range of -32768 to 32767 inclusive, and returns + * OPUS_BAD_ARG otherwise. The default is zero indicating no adjustment. + * This setting survives decoder reset. + * + * gain = pow(10, x/(20.0*256)) + * + * @param[in] x opus_int32: Amount to scale PCM signal by in Q8 dB units. + * @hideinitializer */ +#define OPUS_SET_GAIN(x) OPUS_SET_GAIN_REQUEST, __opus_check_int(x) +/** Gets the decoder's configured gain adjustment. @see OPUS_SET_GAIN + * + * @param[out] x opus_int32 *: Amount to scale PCM signal by in Q8 dB units. + * @hideinitializer */ +#define OPUS_GET_GAIN(x) OPUS_GET_GAIN_REQUEST, __opus_check_int_ptr(x) + +/** Gets the duration (in samples) of the last packet successfully decoded or concealed. + * @param[out] x opus_int32 *: Number of samples (at current sampling rate). + * @hideinitializer */ +#define OPUS_GET_LAST_PACKET_DURATION(x) OPUS_GET_LAST_PACKET_DURATION_REQUEST, __opus_check_int_ptr(x) + +/** Gets the pitch of the last decoded frame, if available. + * This can be used for any post-processing algorithm requiring the use of pitch, + * e.g. time stretching/shortening. If the last frame was not voiced, or if the + * pitch was not coded in the frame, then zero is returned. + * + * This CTL is only implemented for decoder instances. + * + * @param[out] x opus_int32 *: pitch period at 48 kHz (or 0 if not available) + * + * @hideinitializer */ +#define OPUS_GET_PITCH(x) OPUS_GET_PITCH_REQUEST, __opus_check_int_ptr(x) + +/**@}*/ + +/** @defgroup opus_libinfo Opus library information functions + * @{ + */ + +/** Converts an opus error code into a human readable string. + * + * @param[in] error int: Error number + * @returns Error string + */ +OPUS_EXPORT const char *opus_strerror(int error); + +/** Gets the libopus version string. + * + * Applications may look for the substring "-fixed" in the version string to + * determine whether they have a fixed-point or floating-point build at + * runtime. + * + * @returns Version string + */ +OPUS_EXPORT const char *opus_get_version_string(void); +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* OPUS_DEFINES_H */ diff --git a/engine/voice_codecs/opus/opus/opus_multistream.h b/engine/voice_codecs/opus/opus/opus_multistream.h new file mode 100644 index 00000000..babcee69 --- /dev/null +++ b/engine/voice_codecs/opus/opus/opus_multistream.h @@ -0,0 +1,660 @@ +/* Copyright (c) 2011 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. +*/ + +/** + * @file opus_multistream.h + * @brief Opus reference implementation multistream API + */ + +#ifndef OPUS_MULTISTREAM_H +#define OPUS_MULTISTREAM_H + +#include "opus.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond OPUS_INTERNAL_DOC */ + +/** Macros to trigger compilation errors when the wrong types are provided to a + * CTL. */ +/**@{*/ +#define __opus_check_encstate_ptr(ptr) ((ptr) + ((ptr) - (OpusEncoder**)(ptr))) +#define __opus_check_decstate_ptr(ptr) ((ptr) + ((ptr) - (OpusDecoder**)(ptr))) +/**@}*/ + +/** These are the actual encoder and decoder CTL ID numbers. + * They should not be used directly by applications. + * In general, SETs should be even and GETs should be odd.*/ +/**@{*/ +#define OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST 5120 +#define OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST 5122 +/**@}*/ + +/** @endcond */ + +/** @defgroup opus_multistream_ctls Multistream specific encoder and decoder CTLs + * + * These are convenience macros that are specific to the + * opus_multistream_encoder_ctl() and opus_multistream_decoder_ctl() + * interface. + * The CTLs from @ref opus_genericctls, @ref opus_encoderctls, and + * @ref opus_decoderctls may be applied to a multistream encoder or decoder as + * well. + * In addition, you may retrieve the encoder or decoder state for an specific + * stream via #OPUS_MULTISTREAM_GET_ENCODER_STATE or + * #OPUS_MULTISTREAM_GET_DECODER_STATE and apply CTLs to it individually. + */ +/**@{*/ + +/** Gets the encoder state for an individual stream of a multistream encoder. + * @param[in] x opus_int32: The index of the stream whose encoder you + * wish to retrieve. + * This must be non-negative and less than + * the streams parameter used + * to initialize the encoder. + * @param[out] y OpusEncoder**: Returns a pointer to the given + * encoder state. + * @retval OPUS_BAD_ARG The index of the requested stream was out of range. + * @hideinitializer + */ +#define OPUS_MULTISTREAM_GET_ENCODER_STATE(x,y) OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST, __opus_check_int(x), __opus_check_encstate_ptr(y) + +/** Gets the decoder state for an individual stream of a multistream decoder. + * @param[in] x opus_int32: The index of the stream whose decoder you + * wish to retrieve. + * This must be non-negative and less than + * the streams parameter used + * to initialize the decoder. + * @param[out] y OpusDecoder**: Returns a pointer to the given + * decoder state. + * @retval OPUS_BAD_ARG The index of the requested stream was out of range. + * @hideinitializer + */ +#define OPUS_MULTISTREAM_GET_DECODER_STATE(x,y) OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST, __opus_check_int(x), __opus_check_decstate_ptr(y) + +/**@}*/ + +/** @defgroup opus_multistream Opus Multistream API + * @{ + * + * The multistream API allows individual Opus streams to be combined into a + * single packet, enabling support for up to 255 channels. Unlike an + * elementary Opus stream, the encoder and decoder must negotiate the channel + * configuration before the decoder can successfully interpret the data in the + * packets produced by the encoder. Some basic information, such as packet + * duration, can be computed without any special negotiation. + * + * The format for multistream Opus packets is defined in + * RFC 7845 + * and is based on the self-delimited Opus framing described in Appendix B of + * RFC 6716. + * Normal Opus packets are just a degenerate case of multistream Opus packets, + * and can be encoded or decoded with the multistream API by setting + * streams to 1 when initializing the encoder or + * decoder. + * + * Multistream Opus streams can contain up to 255 elementary Opus streams. + * These may be either "uncoupled" or "coupled", indicating that the decoder + * is configured to decode them to either 1 or 2 channels, respectively. + * The streams are ordered so that all coupled streams appear at the + * beginning. + * + * A mapping table defines which decoded channel i + * should be used for each input/output (I/O) channel j. This table is + * typically provided as an unsigned char array. + * Let i = mapping[j] be the index for I/O channel j. + * If i < 2*coupled_streams, then I/O channel j is + * encoded as the left channel of stream (i/2) if i + * is even, or as the right channel of stream (i/2) if + * i is odd. Otherwise, I/O channel j is encoded as + * mono in stream (i - coupled_streams), unless it has the special + * value 255, in which case it is omitted from the encoding entirely (the + * decoder will reproduce it as silence). Each value i must either + * be the special value 255 or be less than streams + coupled_streams. + * + * The output channels specified by the encoder + * should use the + * Vorbis + * channel ordering. A decoder may wish to apply an additional permutation + * to the mapping the encoder used to achieve a different output channel + * order (e.g. for outputing in WAV order). + * + * Each multistream packet contains an Opus packet for each stream, and all of + * the Opus packets in a single multistream packet must have the same + * duration. Therefore the duration of a multistream packet can be extracted + * from the TOC sequence of the first stream, which is located at the + * beginning of the packet, just like an elementary Opus stream: + * + * @code + * int nb_samples; + * int nb_frames; + * nb_frames = opus_packet_get_nb_frames(data, len); + * if (nb_frames < 1) + * return nb_frames; + * nb_samples = opus_packet_get_samples_per_frame(data, 48000) * nb_frames; + * @endcode + * + * The general encoding and decoding process proceeds exactly the same as in + * the normal @ref opus_encoder and @ref opus_decoder APIs. + * See their documentation for an overview of how to use the corresponding + * multistream functions. + */ + +/** Opus multistream encoder state. + * This contains the complete state of a multistream Opus encoder. + * It is position independent and can be freely copied. + * @see opus_multistream_encoder_create + * @see opus_multistream_encoder_init + */ +typedef struct OpusMSEncoder OpusMSEncoder; + +/** Opus multistream decoder state. + * This contains the complete state of a multistream Opus decoder. + * It is position independent and can be freely copied. + * @see opus_multistream_decoder_create + * @see opus_multistream_decoder_init + */ +typedef struct OpusMSDecoder OpusMSDecoder; + +/**\name Multistream encoder functions */ +/**@{*/ + +/** Gets the size of an OpusMSEncoder structure. + * @param streams int: The total number of streams to encode from the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number of coupled (2 channel) streams + * to encode. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * encoded channels (streams + + * coupled_streams) must be no + * more than 255. + * @returns The size in bytes on success, or a negative error code + * (see @ref opus_errorcodes) on error. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_encoder_get_size( + int 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. + * Call opus_multistream_encoder_destroy() to release + * this object when finished. + * @param Fs opus_int32: Sampling rate of the input signal (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels in the input signal. + * This must be at most 255. + * It may be greater than the number of + * coded channels (streams + + * coupled_streams). + * @param streams int: The total number of streams to encode from the + * input. + * This must be no more than the number of channels. + * @param coupled_streams int: Number of coupled (2 channel) streams + * to encode. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * encoded channels (streams + + * coupled_streams) must be no + * more than the number of input channels. + * @param[in] mapping const unsigned char[channels]: Mapping from + * encoded channels to input channels, as described in + * @ref opus_multistream. As an extra constraint, the + * multistream encoder does not allow encoding coupled + * streams for which one channel is unused since this + * is never a good idea. + * @param application int: The target encoder application. + * This must be one of the following: + *
+ *
#OPUS_APPLICATION_VOIP
+ *
Process signal for improved speech intelligibility.
+ *
#OPUS_APPLICATION_AUDIO
+ *
Favor faithfulness to the original input.
+ *
#OPUS_APPLICATION_RESTRICTED_LOWDELAY
+ *
Configure the minimum possible coding delay by disabling certain modes + * of operation.
+ *
+ * @param[out] error int *: Returns #OPUS_OK on success, or an error + * code (see @ref opus_errorcodes) on + * failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_encoder_create( + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping, + int application, + int *error +) 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(4) OPUS_ARG_NONNULL(5) OPUS_ARG_NONNULL(6); + +/** Initialize a previously allocated multistream encoder state. + * The memory pointed to by \a st must be at least the size returned by + * opus_multistream_encoder_get_size(). + * This is intended for applications which use their own allocator instead of + * malloc. + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. + * @see opus_multistream_encoder_create + * @see opus_multistream_encoder_get_size + * @param st OpusMSEncoder*: Multistream encoder state to initialize. + * @param Fs opus_int32: Sampling rate of the input signal (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels in the input signal. + * This must be at most 255. + * It may be greater than the number of + * coded channels (streams + + * coupled_streams). + * @param streams int: The total number of streams to encode from the + * input. + * This must be no more than the number of channels. + * @param coupled_streams int: Number of coupled (2 channel) streams + * to encode. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * encoded channels (streams + + * coupled_streams) must be no + * more than the number of input channels. + * @param[in] mapping const unsigned char[channels]: Mapping from + * encoded channels to input channels, as described in + * @ref opus_multistream. As an extra constraint, the + * multistream encoder does not allow encoding coupled + * streams for which one channel is unused since this + * is never a good idea. + * @param application int: The target encoder application. + * This must be one of the following: + *
+ *
#OPUS_APPLICATION_VOIP
+ *
Process signal for improved speech intelligibility.
+ *
#OPUS_APPLICATION_AUDIO
+ *
Favor faithfulness to the original input.
+ *
#OPUS_APPLICATION_RESTRICTED_LOWDELAY
+ *
Configure the minimum possible coding delay by disabling certain modes + * of operation.
+ *
+ * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes) + * on failure. + */ +OPUS_EXPORT int opus_multistream_encoder_init( + OpusMSEncoder *st, + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping, + int application +) 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(5) OPUS_ARG_NONNULL(6) OPUS_ARG_NONNULL(7); + +/** Encodes a multistream Opus frame. + * @param st OpusMSEncoder*: Multistream encoder state. + * @param[in] pcm const opus_int16*: The input signal as interleaved + * samples. + * This must contain + * frame_size*channels + * samples. + * @param frame_size int: Number of samples per channel in the input + * signal. + * This must be an Opus frame size for the + * encoder's sampling rate. + * For example, at 48 kHz the permitted values + * are 120, 240, 480, 960, 1920, and 2880. + * Passing in a duration of less than 10 ms + * (480 samples at 48 kHz) will prevent the + * encoder from using the LPC or hybrid modes. + * @param[out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode( + OpusMSEncoder *st, + const opus_int16 *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Encodes a multistream Opus frame from floating point input. + * @param st OpusMSEncoder*: Multistream encoder state. + * @param[in] pcm const float*: The input signal as interleaved + * samples with a normal range of + * +/-1.0. + * Samples with a range beyond +/-1.0 + * are supported but will be clipped by + * decoders using the integer API and + * should only be used if it is known + * that the far end supports extended + * dynamic range. + * This must contain + * frame_size*channels + * samples. + * @param frame_size int: Number of samples per channel in the input + * signal. + * This must be an Opus frame size for the + * encoder's sampling rate. + * For example, at 48 kHz the permitted values + * are 120, 240, 480, 960, 1920, and 2880. + * Passing in a duration of less than 10 ms + * (480 samples at 48 kHz) will prevent the + * encoder from using the LPC or hybrid modes. + * @param[out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode_float( + OpusMSEncoder *st, + const float *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Frees an OpusMSEncoder allocated by + * opus_multistream_encoder_create(). + * @param st OpusMSEncoder*: Multistream encoder state to be freed. + */ +OPUS_EXPORT void opus_multistream_encoder_destroy(OpusMSEncoder *st); + +/** Perform a CTL function on a multistream Opus encoder. + * + * Generally the request and subsequent arguments are generated by a + * convenience macro. + * @param st OpusMSEncoder*: Multistream encoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls, + * @ref opus_encoderctls, or @ref opus_multistream_ctls. + * @see opus_genericctls + * @see opus_encoderctls + * @see opus_multistream_ctls + */ +OPUS_EXPORT int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...) OPUS_ARG_NONNULL(1); + +/**@}*/ + +/**\name Multistream decoder functions */ +/**@{*/ + +/** Gets the size of an OpusMSDecoder structure. + * @param streams int: The total number of streams coded in the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number streams to decode as coupled + * (2 channel) streams. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * coded channels (streams + + * coupled_streams) must be no + * more than 255. + * @returns The size in bytes on success, or a negative error code + * (see @ref opus_errorcodes) on error. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_decoder_get_size( + int streams, + int coupled_streams +); + +/** Allocates and initializes a multistream decoder state. + * Call opus_multistream_decoder_destroy() to release + * this object when finished. + * @param Fs opus_int32: Sampling rate to decode at (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels to output. + * This must be at most 255. + * It may be different from the number of coded + * channels (streams + + * coupled_streams). + * @param streams int: The total number of streams coded in the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number of streams to decode as coupled + * (2 channel) streams. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * coded channels (streams + + * coupled_streams) must be no + * more than 255. + * @param[in] mapping const unsigned char[channels]: Mapping from + * coded channels to output channels, as described in + * @ref opus_multistream. + * @param[out] error int *: Returns #OPUS_OK on success, or an error + * code (see @ref opus_errorcodes) on + * failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSDecoder *opus_multistream_decoder_create( + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping, + int *error +) OPUS_ARG_NONNULL(5); + +/** Intialize a previously allocated decoder state object. + * The memory pointed to by \a st must be at least the size returned by + * opus_multistream_encoder_get_size(). + * This is intended for applications which use their own allocator instead of + * malloc. + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. + * @see opus_multistream_decoder_create + * @see opus_multistream_deocder_get_size + * @param st OpusMSEncoder*: Multistream encoder state to initialize. + * @param Fs opus_int32: Sampling rate to decode at (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels to output. + * This must be at most 255. + * It may be different from the number of coded + * channels (streams + + * coupled_streams). + * @param streams int: The total number of streams coded in the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number of streams to decode as coupled + * (2 channel) streams. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * coded channels (streams + + * coupled_streams) must be no + * more than 255. + * @param[in] mapping const unsigned char[channels]: Mapping from + * coded channels to output channels, as described in + * @ref opus_multistream. + * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes) + * on failure. + */ +OPUS_EXPORT int opus_multistream_decoder_init( + OpusMSDecoder *st, + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6); + +/** Decode a multistream Opus packet. + * @param st OpusMSDecoder*: Multistream decoder state. + * @param[in] data const unsigned char*: Input payload. + * Use a NULL + * pointer to indicate packet + * loss. + * @param len opus_int32: Number of bytes in payload. + * @param[out] pcm opus_int16*: Output signal, with interleaved + * samples. + * This must contain room for + * frame_size*channels + * samples. + * @param frame_size int: The number of samples per channel of + * available space in \a pcm. + * If this is less than the maximum packet duration + * (120 ms; 5760 for 48kHz), this function will not be capable + * of decoding some packets. In the case of PLC (data==NULL) + * or FEC (decode_fec=1), then frame_size needs to be exactly + * the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the + * next incoming packet. For the PLC and FEC cases, frame_size + * must be a multiple of 2.5 ms. + * @param decode_fec int: Flag (0 or 1) to request that any in-band + * forward error correction data be decoded. + * If no such data is available, the frame is + * decoded as if it were lost. + * @returns Number of samples decoded on success or a negative error code + * (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode( + OpusMSDecoder *st, + const unsigned char *data, + opus_int32 len, + opus_int16 *pcm, + int frame_size, + int decode_fec +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Decode a multistream Opus packet with floating point output. + * @param st OpusMSDecoder*: Multistream decoder state. + * @param[in] data const unsigned char*: Input payload. + * Use a NULL + * pointer to indicate packet + * loss. + * @param len opus_int32: Number of bytes in payload. + * @param[out] pcm opus_int16*: Output signal, with interleaved + * samples. + * This must contain room for + * frame_size*channels + * samples. + * @param frame_size int: The number of samples per channel of + * available space in \a pcm. + * If this is less than the maximum packet duration + * (120 ms; 5760 for 48kHz), this function will not be capable + * of decoding some packets. In the case of PLC (data==NULL) + * or FEC (decode_fec=1), then frame_size needs to be exactly + * the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the + * next incoming packet. For the PLC and FEC cases, frame_size + * must be a multiple of 2.5 ms. + * @param decode_fec int: Flag (0 or 1) to request that any in-band + * forward error correction data be decoded. + * If no such data is available, the frame is + * decoded as if it were lost. + * @returns Number of samples decoded on success or a negative error code + * (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode_float( + OpusMSDecoder *st, + const unsigned char *data, + opus_int32 len, + float *pcm, + int frame_size, + int decode_fec +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Perform a CTL function on a multistream Opus decoder. + * + * Generally the request and subsequent arguments are generated by a + * convenience macro. + * @param st OpusMSDecoder*: Multistream decoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls, + * @ref opus_decoderctls, or @ref opus_multistream_ctls. + * @see opus_genericctls + * @see opus_decoderctls + * @see opus_multistream_ctls + */ +OPUS_EXPORT int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) OPUS_ARG_NONNULL(1); + +/** Frees an OpusMSDecoder allocated by + * opus_multistream_decoder_create(). + * @param st OpusMSDecoder: Multistream decoder state to be freed. + */ +OPUS_EXPORT void opus_multistream_decoder_destroy(OpusMSDecoder *st); + +/**@}*/ + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* OPUS_MULTISTREAM_H */ diff --git a/engine/voice_codecs/opus/opus/opus_projection.h b/engine/voice_codecs/opus/opus/opus_projection.h new file mode 100644 index 00000000..9dabf4e8 --- /dev/null +++ b/engine/voice_codecs/opus/opus/opus_projection.h @@ -0,0 +1,568 @@ +/* Copyright (c) 2017 Google Inc. + Written by Andrew Allen */ +/* + 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. +*/ + +/** + * @file opus_projection.h + * @brief Opus projection reference API + */ + +#ifndef OPUS_PROJECTION_H +#define OPUS_PROJECTION_H + +#include "opus_multistream.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond OPUS_INTERNAL_DOC */ + +/** These are the actual encoder and decoder CTL ID numbers. + * They should not be used directly by applications.c + * In general, SETs should be even and GETs should be odd.*/ +/**@{*/ +#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN_REQUEST 6001 +#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST 6003 +#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST 6005 +/**@}*/ + + +/** @endcond */ + +/** @defgroup opus_projection_ctls Projection specific encoder and decoder CTLs + * + * These are convenience macros that are specific to the + * opus_projection_encoder_ctl() and opus_projection_decoder_ctl() + * interface. + * The CTLs from @ref opus_genericctls, @ref opus_encoderctls, + * @ref opus_decoderctls, and @ref opus_multistream_ctls may be applied to a + * projection encoder or decoder as well. + */ +/**@{*/ + +/** Gets the gain (in dB. S7.8-format) of the demixing matrix from the encoder. + * @param[out] x opus_int32 *: Returns the gain (in dB. S7.8-format) + * of the demixing matrix. + * @hideinitializer + */ +#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN(x) OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN_REQUEST, __opus_check_int_ptr(x) + + +/** Gets the size in bytes of the demixing matrix from the encoder. + * @param[out] x opus_int32 *: Returns the size in bytes of the + * demixing matrix. + * @hideinitializer + */ +#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE(x) OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST, __opus_check_int_ptr(x) + + +/** Copies the demixing matrix to the supplied pointer location. + * @param[out] x unsigned char *: Returns the demixing matrix to the + * supplied pointer location. + * @param y opus_int32: The size in bytes of the reserved memory at the + * pointer location. + * @hideinitializer + */ +#define OPUS_PROJECTION_GET_DEMIXING_MATRIX(x,y) OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST, x, __opus_check_int(y) + + +/**@}*/ + +/** Opus projection encoder state. + * This contains the complete state of a projection Opus encoder. + * It is position independent and can be freely copied. + * @see opus_projection_ambisonics_encoder_create + */ +typedef struct OpusProjectionEncoder OpusProjectionEncoder; + + +/** Opus projection decoder state. + * This contains the complete state of a projection Opus decoder. + * It is position independent and can be freely copied. + * @see opus_projection_decoder_create + * @see opus_projection_decoder_init + */ +typedef struct OpusProjectionDecoder OpusProjectionDecoder; + + +/**\name Projection encoder functions */ +/**@{*/ + +/** Gets the size of an OpusProjectionEncoder structure. + * @param channels int: The total number of input channels to encode. + * This must be no more than 255. + * @param mapping_family int: The mapping family to use for selecting + * the appropriate projection. + * @returns The size in bytes on success, or a negative error code + * (see @ref opus_errorcodes) on error. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_projection_ambisonics_encoder_get_size( + int channels, + int mapping_family +); + + +/** Allocates and initializes a projection encoder state. + * Call opus_projection_encoder_destroy() to release + * this object when finished. + * @param Fs opus_int32: Sampling rate of the input signal (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels in the input signal. + * This must be at most 255. + * It may be greater than the number of + * coded channels (streams + + * coupled_streams). + * @param mapping_family int: The mapping family to use for selecting + * the appropriate projection. + * @param[out] streams int *: The total number of streams that will + * be encoded from the input. + * @param[out] coupled_streams int *: Number of coupled (2 channel) + * streams that will be encoded from the input. + * @param application int: The target encoder application. + * This must be one of the following: + *
+ *
#OPUS_APPLICATION_VOIP
+ *
Process signal for improved speech intelligibility.
+ *
#OPUS_APPLICATION_AUDIO
+ *
Favor faithfulness to the original input.
+ *
#OPUS_APPLICATION_RESTRICTED_LOWDELAY
+ *
Configure the minimum possible coding delay by disabling certain modes + * of operation.
+ *
+ * @param[out] error int *: Returns #OPUS_OK on success, or an error + * code (see @ref opus_errorcodes) on + * failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusProjectionEncoder *opus_projection_ambisonics_encoder_create( + opus_int32 Fs, + int channels, + int mapping_family, + int *streams, + int *coupled_streams, + int application, + int *error +) OPUS_ARG_NONNULL(4) OPUS_ARG_NONNULL(5); + + +/** Initialize a previously allocated projection encoder state. + * The memory pointed to by \a st must be at least the size returned by + * opus_projection_ambisonics_encoder_get_size(). + * This is intended for applications which use their own allocator instead of + * malloc. + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. + * @see opus_projection_ambisonics_encoder_create + * @see opus_projection_ambisonics_encoder_get_size + * @param st OpusProjectionEncoder*: Projection encoder state to initialize. + * @param Fs opus_int32: Sampling rate of the input signal (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels in the input signal. + * This must be at most 255. + * It may be greater than the number of + * coded channels (streams + + * coupled_streams). + * @param streams int: The total number of streams to encode from the + * input. + * This must be no more than the number of channels. + * @param coupled_streams int: Number of coupled (2 channel) streams + * to encode. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * encoded channels (streams + + * coupled_streams) must be no + * more than the number of input channels. + * @param application int: The target encoder application. + * This must be one of the following: + *
+ *
#OPUS_APPLICATION_VOIP
+ *
Process signal for improved speech intelligibility.
+ *
#OPUS_APPLICATION_AUDIO
+ *
Favor faithfulness to the original input.
+ *
#OPUS_APPLICATION_RESTRICTED_LOWDELAY
+ *
Configure the minimum possible coding delay by disabling certain modes + * of operation.
+ *
+ * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes) + * on failure. + */ +OPUS_EXPORT int opus_projection_ambisonics_encoder_init( + OpusProjectionEncoder *st, + opus_int32 Fs, + int channels, + int mapping_family, + int *streams, + int *coupled_streams, + int application +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(5) OPUS_ARG_NONNULL(6); + + +/** Encodes a projection Opus frame. + * @param st OpusProjectionEncoder*: Projection encoder state. + * @param[in] pcm const opus_int16*: The input signal as interleaved + * samples. + * This must contain + * frame_size*channels + * samples. + * @param frame_size int: Number of samples per channel in the input + * signal. + * This must be an Opus frame size for the + * encoder's sampling rate. + * For example, at 48 kHz the permitted values + * are 120, 240, 480, 960, 1920, and 2880. + * Passing in a duration of less than 10 ms + * (480 samples at 48 kHz) will prevent the + * encoder from using the LPC or hybrid modes. + * @param[out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_encode( + OpusProjectionEncoder *st, + const opus_int16 *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + + +/** Encodes a projection Opus frame from floating point input. + * @param st OpusProjectionEncoder*: Projection encoder state. + * @param[in] pcm const float*: The input signal as interleaved + * samples with a normal range of + * +/-1.0. + * Samples with a range beyond +/-1.0 + * are supported but will be clipped by + * decoders using the integer API and + * should only be used if it is known + * that the far end supports extended + * dynamic range. + * This must contain + * frame_size*channels + * samples. + * @param frame_size int: Number of samples per channel in the input + * signal. + * This must be an Opus frame size for the + * encoder's sampling rate. + * For example, at 48 kHz the permitted values + * are 120, 240, 480, 960, 1920, and 2880. + * Passing in a duration of less than 10 ms + * (480 samples at 48 kHz) will prevent the + * encoder from using the LPC or hybrid modes. + * @param[out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_encode_float( + OpusProjectionEncoder *st, + const float *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + + +/** Frees an OpusProjectionEncoder allocated by + * opus_projection_ambisonics_encoder_create(). + * @param st OpusProjectionEncoder*: Projection encoder state to be freed. + */ +OPUS_EXPORT void opus_projection_encoder_destroy(OpusProjectionEncoder *st); + + +/** Perform a CTL function on a projection Opus encoder. + * + * Generally the request and subsequent arguments are generated by a + * convenience macro. + * @param st OpusProjectionEncoder*: Projection encoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls, + * @ref opus_encoderctls, @ref opus_multistream_ctls, or + * @ref opus_projection_ctls + * @see opus_genericctls + * @see opus_encoderctls + * @see opus_multistream_ctls + * @see opus_projection_ctls + */ +OPUS_EXPORT int opus_projection_encoder_ctl(OpusProjectionEncoder *st, int request, ...) OPUS_ARG_NONNULL(1); + + +/**@}*/ + +/**\name Projection decoder functions */ +/**@{*/ + +/** Gets the size of an OpusProjectionDecoder structure. + * @param channels int: The total number of output channels. + * This must be no more than 255. + * @param streams int: The total number of streams coded in the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number streams to decode as coupled + * (2 channel) streams. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * coded channels (streams + + * coupled_streams) must be no + * more than 255. + * @returns The size in bytes on success, or a negative error code + * (see @ref opus_errorcodes) on error. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_projection_decoder_get_size( + int channels, + int streams, + int coupled_streams +); + + +/** Allocates and initializes a projection decoder state. + * Call opus_projection_decoder_destroy() to release + * this object when finished. + * @param Fs opus_int32: Sampling rate to decode at (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels to output. + * This must be at most 255. + * It may be different from the number of coded + * channels (streams + + * coupled_streams). + * @param streams int: The total number of streams coded in the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number of streams to decode as coupled + * (2 channel) streams. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * coded channels (streams + + * coupled_streams) must be no + * more than 255. + * @param[in] demixing_matrix const unsigned char[demixing_matrix_size]: Demixing matrix + * that mapping from coded channels to output channels, + * as described in @ref opus_projection and + * @ref opus_projection_ctls. + * @param demixing_matrix_size opus_int32: The size in bytes of the + * demixing matrix, as + * described in @ref + * opus_projection_ctls. + * @param[out] error int *: Returns #OPUS_OK on success, or an error + * code (see @ref opus_errorcodes) on + * failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusProjectionDecoder *opus_projection_decoder_create( + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + unsigned char *demixing_matrix, + opus_int32 demixing_matrix_size, + int *error +) OPUS_ARG_NONNULL(5); + + +/** Intialize a previously allocated projection decoder state object. + * The memory pointed to by \a st must be at least the size returned by + * opus_projection_decoder_get_size(). + * This is intended for applications which use their own allocator instead of + * malloc. + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. + * @see opus_projection_decoder_create + * @see opus_projection_deocder_get_size + * @param st OpusProjectionDecoder*: Projection encoder state to initialize. + * @param Fs opus_int32: Sampling rate to decode at (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels to output. + * This must be at most 255. + * It may be different from the number of coded + * channels (streams + + * coupled_streams). + * @param streams int: The total number of streams coded in the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number of streams to decode as coupled + * (2 channel) streams. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * coded channels (streams + + * coupled_streams) must be no + * more than 255. + * @param[in] demixing_matrix const unsigned char[demixing_matrix_size]: Demixing matrix + * that mapping from coded channels to output channels, + * as described in @ref opus_projection and + * @ref opus_projection_ctls. + * @param demixing_matrix_size opus_int32: The size in bytes of the + * demixing matrix, as + * described in @ref + * opus_projection_ctls. + * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes) + * on failure. + */ +OPUS_EXPORT int opus_projection_decoder_init( + OpusProjectionDecoder *st, + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + unsigned char *demixing_matrix, + opus_int32 demixing_matrix_size +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6); + + +/** Decode a projection Opus packet. + * @param st OpusProjectionDecoder*: Projection decoder state. + * @param[in] data const unsigned char*: Input payload. + * Use a NULL + * pointer to indicate packet + * loss. + * @param len opus_int32: Number of bytes in payload. + * @param[out] pcm opus_int16*: Output signal, with interleaved + * samples. + * This must contain room for + * frame_size*channels + * samples. + * @param frame_size int: The number of samples per channel of + * available space in \a pcm. + * If this is less than the maximum packet duration + * (120 ms; 5760 for 48kHz), this function will not be capable + * of decoding some packets. In the case of PLC (data==NULL) + * or FEC (decode_fec=1), then frame_size needs to be exactly + * the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the + * next incoming packet. For the PLC and FEC cases, frame_size + * must be a multiple of 2.5 ms. + * @param decode_fec int: Flag (0 or 1) to request that any in-band + * forward error correction data be decoded. + * If no such data is available, the frame is + * decoded as if it were lost. + * @returns Number of samples decoded on success or a negative error code + * (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_decode( + OpusProjectionDecoder *st, + const unsigned char *data, + opus_int32 len, + opus_int16 *pcm, + int frame_size, + int decode_fec +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + + +/** Decode a projection Opus packet with floating point output. + * @param st OpusProjectionDecoder*: Projection decoder state. + * @param[in] data const unsigned char*: Input payload. + * Use a NULL + * pointer to indicate packet + * loss. + * @param len opus_int32: Number of bytes in payload. + * @param[out] pcm opus_int16*: Output signal, with interleaved + * samples. + * This must contain room for + * frame_size*channels + * samples. + * @param frame_size int: The number of samples per channel of + * available space in \a pcm. + * If this is less than the maximum packet duration + * (120 ms; 5760 for 48kHz), this function will not be capable + * of decoding some packets. In the case of PLC (data==NULL) + * or FEC (decode_fec=1), then frame_size needs to be exactly + * the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the + * next incoming packet. For the PLC and FEC cases, frame_size + * must be a multiple of 2.5 ms. + * @param decode_fec int: Flag (0 or 1) to request that any in-band + * forward error correction data be decoded. + * If no such data is available, the frame is + * decoded as if it were lost. + * @returns Number of samples decoded on success or a negative error code + * (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_decode_float( + OpusProjectionDecoder *st, + const unsigned char *data, + opus_int32 len, + float *pcm, + int frame_size, + int decode_fec +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + + +/** Perform a CTL function on a projection Opus decoder. + * + * Generally the request and subsequent arguments are generated by a + * convenience macro. + * @param st OpusProjectionDecoder*: Projection decoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls, + * @ref opus_decoderctls, @ref opus_multistream_ctls, or + * @ref opus_projection_ctls. + * @see opus_genericctls + * @see opus_decoderctls + * @see opus_multistream_ctls + * @see opus_projection_ctls + */ +OPUS_EXPORT int opus_projection_decoder_ctl(OpusProjectionDecoder *st, int request, ...) OPUS_ARG_NONNULL(1); + + +/** Frees an OpusProjectionDecoder allocated by + * opus_projection_decoder_create(). + * @param st OpusProjectionDecoder: Projection decoder state to be freed. + */ +OPUS_EXPORT void opus_projection_decoder_destroy(OpusProjectionDecoder *st); + + +/**@}*/ + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* OPUS_PROJECTION_H */ diff --git a/engine/voice_codecs/opus/opus/opus_types.h b/engine/voice_codecs/opus/opus/opus_types.h new file mode 100644 index 00000000..7cf67558 --- /dev/null +++ b/engine/voice_codecs/opus/opus/opus_types.h @@ -0,0 +1,166 @@ +/* (C) COPYRIGHT 1994-2002 Xiph.Org Foundation */ +/* Modified 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. +*/ +/* opus_types.h based on ogg_types.h from libogg */ + +/** + @file opus_types.h + @brief Opus reference implementation types +*/ +#ifndef OPUS_TYPES_H +#define OPUS_TYPES_H + +#define opus_int int /* used for counters etc; at least 16 bits */ +#define opus_int64 long long +#define opus_int8 signed char + +#define opus_uint unsigned int /* used for counters etc; at least 16 bits */ +#define opus_uint64 unsigned long long +#define opus_uint8 unsigned char + +/* Use the real stdint.h if it's there (taken from Paul Hsieh's pstdint.h) */ +#if (defined(__STDC__) && __STDC__ && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) || defined (HAVE_STDINT_H)) +#include +# undef opus_int64 +# undef opus_int8 +# undef opus_uint64 +# undef opus_uint8 + typedef int8_t opus_int8; + typedef uint8_t opus_uint8; + typedef int16_t opus_int16; + typedef uint16_t opus_uint16; + typedef int32_t opus_int32; + typedef uint32_t opus_uint32; + typedef int64_t opus_int64; + typedef uint64_t opus_uint64; +#elif defined(_WIN32) + +# if defined(__CYGWIN__) +# include <_G_config.h> + typedef _G_int32_t opus_int32; + typedef _G_uint32_t opus_uint32; + typedef _G_int16 opus_int16; + typedef _G_uint16 opus_uint16; +# elif defined(__MINGW32__) + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; +# elif defined(__MWERKS__) + typedef int opus_int32; + typedef unsigned int opus_uint32; + typedef short opus_int16; + typedef unsigned short opus_uint16; +# else + /* MSVC/Borland */ + typedef __int32 opus_int32; + typedef unsigned __int32 opus_uint32; + typedef __int16 opus_int16; + typedef unsigned __int16 opus_uint16; +# endif + +#elif defined(__MACOS__) + +# include + typedef SInt16 opus_int16; + typedef UInt16 opus_uint16; + typedef SInt32 opus_int32; + typedef UInt32 opus_uint32; + +#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ + +# include + typedef int16_t opus_int16; + typedef u_int16_t opus_uint16; + typedef int32_t opus_int32; + typedef u_int32_t opus_uint32; + +#elif defined(__BEOS__) + + /* Be */ +# include + typedef int16 opus_int16; + typedef u_int16 opus_uint16; + typedef int32_t opus_int32; + typedef u_int32_t opus_uint32; + +#elif defined (__EMX__) + + /* OS/2 GCC */ + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; + +#elif defined (DJGPP) + + /* DJGPP */ + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; + +#elif defined(R5900) + + /* PS2 EE */ + typedef int opus_int32; + typedef unsigned opus_uint32; + typedef short opus_int16; + typedef unsigned short opus_uint16; + +#elif defined(__SYMBIAN32__) + + /* Symbian GCC */ + typedef signed short opus_int16; + typedef unsigned short opus_uint16; + typedef signed int opus_int32; + typedef unsigned int opus_uint32; + +#elif defined(CONFIG_TI_C54X) || defined (CONFIG_TI_C55X) + + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef long opus_int32; + typedef unsigned long opus_uint32; + +#elif defined(CONFIG_TI_C6X) + + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; + +#else + + /* Give up, take a reasonable guess */ + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; + +#endif + +#endif /* OPUS_TYPES_H */ diff --git a/engine/voice_codecs/opus/opus/opusfile.h b/engine/voice_codecs/opus/opus/opusfile.h new file mode 100644 index 00000000..7c1c89e0 --- /dev/null +++ b/engine/voice_codecs/opus/opus/opusfile.h @@ -0,0 +1,2164 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE libopusfile SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE libopusfile SOURCE CODE IS (C) COPYRIGHT 1994-2012 * + * by the Xiph.Org Foundation and contributors https://xiph.org/ * + * * + ******************************************************************** + + function: stdio-based convenience library for opening/seeking/decoding + last mod: $Id: vorbisfile.h 17182 2010-04-29 03:48:32Z xiphmont $ + + ********************************************************************/ +#if !defined(_opusfile_h) +# define _opusfile_h (1) + +/**\mainpage + \section Introduction + + This is the documentation for the libopusfile C API. + + The libopusfile package provides a convenient high-level API for + decoding and basic manipulation of all Ogg Opus audio streams. + libopusfile is implemented as a layer on top of Xiph.Org's + reference + libogg + and + libopus + libraries. + + libopusfile provides several sets of built-in routines for + file/stream access, and may also use custom stream I/O routines provided by + the embedded environment. + There are built-in I/O routines provided for ANSI-compliant + stdio (FILE *), memory buffers, and URLs + (including URLs, plus optionally and URLs). + + \section Organization + + The main API is divided into several sections: + - \ref stream_open_close + - \ref stream_info + - \ref stream_decoding + - \ref stream_seeking + + Several additional sections are not tied to the main API. + - \ref stream_callbacks + - \ref header_info + - \ref error_codes + + \section Overview + + The libopusfile API always decodes files to 48 kHz. + The original sample rate is not preserved by the lossy compression, though + it is stored in the header to allow you to resample to it after decoding + (the libopusfile API does not currently provide a resampler, + but the + the + Speex resampler is a good choice if you need one). + In general, if you are playing back the audio, you should leave it at + 48 kHz, provided your audio hardware supports it. + When decoding to a file, it may be worth resampling back to the original + sample rate, so as not to surprise users who might not expect the sample + rate to change after encoding to Opus and decoding. + + Opus files can contain anywhere from 1 to 255 channels of audio. + The channel mappings for up to 8 channels are the same as the + Vorbis + mappings. + A special stereo API can convert everything to 2 channels, making it simple + to support multichannel files in an application which only has stereo + output. + Although the libopusfile ABI provides support for the theoretical + maximum number of channels, the current implementation does not support + files with more than 8 channels, as they do not have well-defined channel + mappings. + + Like all Ogg files, Opus files may be "chained". + That is, multiple Opus files may be combined into a single, longer file just + by concatenating the original files. + This is commonly done in internet radio streaming, as it allows the title + and artist to be updated each time the song changes, since each link in the + chain includes its own set of metadata. + + libopusfile fully supports chained files. + It will decode the first Opus stream found in each link of a chained file + (ignoring any other streams that might be concurrently multiplexed with it, + such as a video stream). + + The channel count can also change between links. + If your application is not prepared to deal with this, it can use the stereo + API to ensure the audio from all links will always get decoded into a + common format. + Since libopusfile always decodes to 48 kHz, you do not have to + worry about the sample rate changing between links (as was possible with + Vorbis). + This makes application support for chained files with libopusfile + very easy.*/ + +# if defined(__cplusplus) +extern "C" { +# endif + +# include +# include +# include +# include + +/**@cond PRIVATE*/ + +/*Enable special features for gcc and gcc-compatible compilers.*/ +# if !defined(OP_GNUC_PREREQ) +# if defined(__GNUC__)&&defined(__GNUC_MINOR__) +# define OP_GNUC_PREREQ(_maj,_min) \ + ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min)) +# else +# define OP_GNUC_PREREQ(_maj,_min) 0 +# endif +# endif + +# if OP_GNUC_PREREQ(4,0) +# pragma GCC visibility push(default) +# endif + +typedef struct OpusHead OpusHead; +typedef struct OpusTags OpusTags; +typedef struct OpusPictureTag OpusPictureTag; +typedef struct OpusServerInfo OpusServerInfo; +typedef struct OpusFileCallbacks OpusFileCallbacks; +typedef struct OggOpusFile OggOpusFile; + +/*Warning attributes for libopusfile functions.*/ +# if OP_GNUC_PREREQ(3,4) +# define OP_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) +# else +# define OP_WARN_UNUSED_RESULT +# endif +# if OP_GNUC_PREREQ(3,4) +# define OP_ARG_NONNULL(_x) __attribute__((__nonnull__(_x))) +# else +# define OP_ARG_NONNULL(_x) +# endif + +/**@endcond*/ + +/**\defgroup error_codes Error Codes*/ +/*@{*/ +/**\name List of possible error codes + Many of the functions in this library return a negative error code when a + function fails. + This list provides a brief explanation of the common errors. + See each individual function for more details on what a specific error code + means in that context.*/ +/*@{*/ + +/**A request did not succeed.*/ +#define OP_FALSE (-1) +/*Currently not used externally.*/ +#define OP_EOF (-2) +/**There was a hole in the page sequence numbers (e.g., a page was corrupt or + missing).*/ +#define OP_HOLE (-3) +/**An underlying read, seek, or tell operation failed when it should have + succeeded.*/ +#define OP_EREAD (-128) +/**A NULL pointer was passed where one was unexpected, or an + internal memory allocation failed, or an internal library error was + encountered.*/ +#define OP_EFAULT (-129) +/**The stream used a feature that is not implemented, such as an unsupported + channel family.*/ +#define OP_EIMPL (-130) +/**One or more parameters to a function were invalid.*/ +#define OP_EINVAL (-131) +/**A purported Ogg Opus stream did not begin with an Ogg page, a purported + header packet did not start with one of the required strings, "OpusHead" or + "OpusTags", or a link in a chained file was encountered that did not + contain any logical Opus streams.*/ +#define OP_ENOTFORMAT (-132) +/**A required header packet was not properly formatted, contained illegal + values, or was missing altogether.*/ +#define OP_EBADHEADER (-133) +/**The ID header contained an unrecognized version number.*/ +#define OP_EVERSION (-134) +/*Currently not used at all.*/ +#define OP_ENOTAUDIO (-135) +/**An audio packet failed to decode properly. + This is usually caused by a multistream Ogg packet where the durations of + the individual Opus packets contained in it are not all the same.*/ +#define OP_EBADPACKET (-136) +/**We failed to find data we had seen before, or the bitstream structure was + sufficiently malformed that seeking to the target destination was + impossible.*/ +#define OP_EBADLINK (-137) +/**An operation that requires seeking was requested on an unseekable stream.*/ +#define OP_ENOSEEK (-138) +/**The first or last granule position of a link failed basic validity checks.*/ +#define OP_EBADTIMESTAMP (-139) + +/*@}*/ +/*@}*/ + +/**\defgroup header_info Header Information*/ +/*@{*/ + +/**The maximum number of channels in an Ogg Opus stream.*/ +#define OPUS_CHANNEL_COUNT_MAX (255) + +/**Ogg Opus bitstream information. + This contains the basic playback parameters for a stream, and corresponds to + the initial ID header packet of an Ogg Opus stream.*/ +struct OpusHead{ + /**The Ogg Opus format version, in the range 0...255. + The top 4 bits represent a "major" version, and the bottom four bits + represent backwards-compatible "minor" revisions. + The current specification describes version 1. + This library will recognize versions up through 15 as backwards compatible + with the current specification. + An earlier draft of the specification described a version 0, but the only + difference between version 1 and version 0 is that version 0 did + not specify the semantics for handling the version field.*/ + int version; + /**The number of channels, in the range 1...255.*/ + int channel_count; + /**The number of samples that should be discarded from the beginning of the + stream.*/ + unsigned pre_skip; + /**The sampling rate of the original input. + All Opus audio is coded at 48 kHz, and should also be decoded at 48 kHz + for playback (unless the target hardware does not support this sampling + rate). + However, this field may be used to resample the audio back to the original + sampling rate, for example, when saving the output to a file.*/ + opus_uint32 input_sample_rate; + /**The gain to apply to the decoded output, in dB, as a Q8 value in the range + -32768...32767. + The libopusfile API will automatically apply this gain to the + decoded output before returning it, scaling it by + pow(10,output_gain/(20.0*256)). + You can adjust this behavior with op_set_gain_offset().*/ + int output_gain; + /**The channel mapping family, in the range 0...255. + Channel mapping family 0 covers mono or stereo in a single stream. + Channel mapping family 1 covers 1 to 8 channels in one or more streams, + using the Vorbis speaker assignments. + Channel mapping family 255 covers 1 to 255 channels in one or more + streams, but without any defined speaker assignment.*/ + int mapping_family; + /**The number of Opus streams in each Ogg packet, in the range 1...255.*/ + int stream_count; + /**The number of coupled Opus streams in each Ogg packet, in the range + 0...127. + This must satisfy 0 <= coupled_count <= stream_count and + coupled_count + stream_count <= 255. + The coupled streams appear first, before all uncoupled streams, in an Ogg + Opus packet.*/ + int coupled_count; + /**The mapping from coded stream channels to output channels. + Let index=mapping[k] be the value for channel k. + If index<2*coupled_count, then it refers to the left channel + from stream (index/2) if even, and the right channel from + stream (index/2) if odd. + Otherwise, it refers to the output of the uncoupled stream + (index-coupled_count).*/ + unsigned char mapping[OPUS_CHANNEL_COUNT_MAX]; +}; + +/**The metadata from an Ogg Opus stream. + + This structure holds the in-stream metadata corresponding to the 'comment' + header packet of an Ogg Opus stream. + The comment header is meant to be used much like someone jotting a quick + note on the label of a CD. + It should be a short, to the point text note that can be more than a couple + words, but not more than a short paragraph. + + The metadata is stored as a series of (tag, value) pairs, in length-encoded + string vectors, using the same format as Vorbis (without the final "framing + bit"), Theora, and Speex, except for the packet header. + The first occurrence of the '=' character delimits the tag and value. + A particular tag may occur more than once, and order is significant. + The character set encoding for the strings is always UTF-8, but the tag + names are limited to ASCII, and treated as case-insensitive. + See the Vorbis + comment header specification for details. + + In filling in this structure, libopusfile will null-terminate the + #user_comments strings for safety. + However, the bitstream format itself treats them as 8-bit clean vectors, + possibly containing NUL characters, so the #comment_lengths array should be + treated as their authoritative length. + + This structure is binary and source-compatible with a + vorbis_comment, and pointers to it may be freely cast to + vorbis_comment pointers, and vice versa. + It is provided as a separate type to avoid introducing a compile-time + dependency on the libvorbis headers.*/ +struct OpusTags{ + /**The array of comment string vectors.*/ + char **user_comments; + /**An array of the corresponding length of each vector, in bytes.*/ + int *comment_lengths; + /**The total number of comment streams.*/ + int comments; + /**The null-terminated vendor string. + This identifies the software used to encode the stream.*/ + char *vendor; +}; + +/**\name Picture tag image formats*/ +/*@{*/ + +/**The MIME type was not recognized, or the image data did not match the + declared MIME type.*/ +#define OP_PIC_FORMAT_UNKNOWN (-1) +/**The MIME type indicates the image data is really a URL.*/ +#define OP_PIC_FORMAT_URL (0) +/**The image is a JPEG.*/ +#define OP_PIC_FORMAT_JPEG (1) +/**The image is a PNG.*/ +#define OP_PIC_FORMAT_PNG (2) +/**The image is a GIF.*/ +#define OP_PIC_FORMAT_GIF (3) + +/*@}*/ + +/**The contents of a METADATA_BLOCK_PICTURE tag.*/ +struct OpusPictureTag{ + /**The picture type according to the ID3v2 APIC frame: +
    +
  1. Other
  2. +
  3. 32x32 pixels 'file icon' (PNG only)
  4. +
  5. Other file icon
  6. +
  7. Cover (front)
  8. +
  9. Cover (back)
  10. +
  11. Leaflet page
  12. +
  13. Media (e.g. label side of CD)
  14. +
  15. Lead artist/lead performer/soloist
  16. +
  17. Artist/performer
  18. +
  19. Conductor
  20. +
  21. Band/Orchestra
  22. +
  23. Composer
  24. +
  25. Lyricist/text writer
  26. +
  27. Recording Location
  28. +
  29. During recording
  30. +
  31. During performance
  32. +
  33. Movie/video screen capture
  34. +
  35. A bright colored fish
  36. +
  37. Illustration
  38. +
  39. Band/artist logotype
  40. +
  41. Publisher/Studio logotype
  42. +
+ Others are reserved and should not be used. + There may only be one each of picture type 1 and 2 in a file.*/ + opus_int32 type; + /**The MIME type of the picture, in printable ASCII characters 0x20-0x7E. + The MIME type may also be "-->" to signify that the data part + is a URL pointing to the picture instead of the picture data itself. + In this case, a terminating NUL is appended to the URL string in #data, + but #data_length is set to the length of the string excluding that + terminating NUL.*/ + char *mime_type; + /**The description of the picture, in UTF-8.*/ + char *description; + /**The width of the picture in pixels.*/ + opus_uint32 width; + /**The height of the picture in pixels.*/ + opus_uint32 height; + /**The color depth of the picture in bits-per-pixel (not + bits-per-channel).*/ + opus_uint32 depth; + /**For indexed-color pictures (e.g., GIF), the number of colors used, or 0 + for non-indexed pictures.*/ + opus_uint32 colors; + /**The length of the picture data in bytes.*/ + opus_uint32 data_length; + /**The binary picture data.*/ + unsigned char *data; + /**The format of the picture data, if known. + One of +
    +
  • #OP_PIC_FORMAT_UNKNOWN,
  • +
  • #OP_PIC_FORMAT_URL,
  • +
  • #OP_PIC_FORMAT_JPEG,
  • +
  • #OP_PIC_FORMAT_PNG, or
  • +
  • #OP_PIC_FORMAT_GIF.
  • +
*/ + int format; +}; + +/**\name Functions for manipulating header data + + These functions manipulate the #OpusHead and #OpusTags structures, + which describe the audio parameters and tag-value metadata, respectively. + These can be used to query the headers returned by libopusfile, or + to parse Opus headers from sources other than an Ogg Opus stream, provided + they use the same format.*/ +/*@{*/ + +/**Parses the contents of the ID header packet of an Ogg Opus stream. + \param[out] _head Returns the contents of the parsed packet. + The contents of this structure are untouched on error. + This may be NULL to merely test the header + for validity. + \param[in] _data The contents of the ID header packet. + \param _len The number of bytes of data in the ID header packet. + \return 0 on success or a negative value on error. + \retval #OP_ENOTFORMAT If the data does not start with the "OpusHead" + string. + \retval #OP_EVERSION If the version field signaled a version this library + does not know how to parse. + \retval #OP_EIMPL If the channel mapping family was 255, which general + purpose players should not attempt to play. + \retval #OP_EBADHEADER If the contents of the packet otherwise violate the + Ogg Opus specification: +
    +
  • Insufficient data,
  • +
  • Too much data for the known minor versions,
  • +
  • An unrecognized channel mapping family,
  • +
  • Zero channels or too many channels,
  • +
  • Zero coded streams,
  • +
  • Too many coupled streams, or
  • +
  • An invalid channel mapping index.
  • +
*/ +OP_WARN_UNUSED_RESULT int opus_head_parse(OpusHead *_head, + const unsigned char *_data,size_t _len) OP_ARG_NONNULL(2); + +/**Converts a granule position to a sample offset for a given Ogg Opus stream. + The sample offset is simply _gp-_head->pre_skip. + Granule position values smaller than OpusHead#pre_skip correspond to audio + that should never be played, and thus have no associated sample offset. + This function returns -1 for such values. + This function also correctly handles extremely large granule positions, + which may have wrapped around to a negative number when stored in a signed + ogg_int64_t value. + \param _head The #OpusHead information from the ID header of the stream. + \param _gp The granule position to convert. + \return The sample offset associated with the given granule position + (counting at a 48 kHz sampling rate), or the special value -1 on + error (i.e., the granule position was smaller than the pre-skip + amount).*/ +ogg_int64_t opus_granule_sample(const OpusHead *_head,ogg_int64_t _gp) + OP_ARG_NONNULL(1); + +/**Parses the contents of the 'comment' header packet of an Ogg Opus stream. + \param[out] _tags An uninitialized #OpusTags structure. + This returns the contents of the parsed packet. + The contents of this structure are untouched on error. + This may be NULL to merely test the header + for validity. + \param[in] _data The contents of the 'comment' header packet. + \param _len The number of bytes of data in the 'info' header packet. + \retval 0 Success. + \retval #OP_ENOTFORMAT If the data does not start with the "OpusTags" + string. + \retval #OP_EBADHEADER If the contents of the packet otherwise violate the + Ogg Opus specification. + \retval #OP_EFAULT If there wasn't enough memory to store the tags.*/ +OP_WARN_UNUSED_RESULT int opus_tags_parse(OpusTags *_tags, + const unsigned char *_data,size_t _len) OP_ARG_NONNULL(2); + +/**Performs a deep copy of an #OpusTags structure. + \param _dst The #OpusTags structure to copy into. + If this function fails, the contents of this structure remain + untouched. + \param _src The #OpusTags structure to copy from. + \retval 0 Success. + \retval #OP_EFAULT If there wasn't enough memory to copy the tags.*/ +int opus_tags_copy(OpusTags *_dst,const OpusTags *_src) OP_ARG_NONNULL(1); + +/**Initializes an #OpusTags structure. + This should be called on a freshly allocated #OpusTags structure before + attempting to use it. + \param _tags The #OpusTags structure to initialize.*/ +void opus_tags_init(OpusTags *_tags) OP_ARG_NONNULL(1); + +/**Add a (tag, value) pair to an initialized #OpusTags structure. + \note Neither opus_tags_add() nor opus_tags_add_comment() support values + containing embedded NULs, although the bitstream format does support them. + To add such tags, you will need to manipulate the #OpusTags structure + directly. + \param _tags The #OpusTags structure to add the (tag, value) pair to. + \param _tag A NUL-terminated, case-insensitive, ASCII string containing + the tag to add (without an '=' character). + \param _value A NUL-terminated UTF-8 containing the corresponding value. + \return 0 on success, or a negative value on failure. + \retval #OP_EFAULT An internal memory allocation failed.*/ +int opus_tags_add(OpusTags *_tags,const char *_tag,const char *_value) + OP_ARG_NONNULL(1) OP_ARG_NONNULL(2) OP_ARG_NONNULL(3); + +/**Add a comment to an initialized #OpusTags structure. + \note Neither opus_tags_add_comment() nor opus_tags_add() support comments + containing embedded NULs, although the bitstream format does support them. + To add such tags, you will need to manipulate the #OpusTags structure + directly. + \param _tags The #OpusTags structure to add the comment to. + \param _comment A NUL-terminated UTF-8 string containing the comment in + "TAG=value" form. + \return 0 on success, or a negative value on failure. + \retval #OP_EFAULT An internal memory allocation failed.*/ +int opus_tags_add_comment(OpusTags *_tags,const char *_comment) + OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); + +/**Replace the binary suffix data at the end of the packet (if any). + \param _tags An initialized #OpusTags structure. + \param _data A buffer of binary data to append after the encoded user + comments. + The least significant bit of the first byte of this data must + be set (to ensure the data is preserved by other editors). + \param _len The number of bytes of binary data to append. + This may be zero to remove any existing binary suffix data. + \return 0 on success, or a negative value on error. + \retval #OP_EINVAL \a _len was negative, or \a _len was positive but + \a _data was NULL or the least significant + bit of the first byte was not set. + \retval #OP_EFAULT An internal memory allocation failed.*/ +int opus_tags_set_binary_suffix(OpusTags *_tags, + const unsigned char *_data,int _len) OP_ARG_NONNULL(1); + +/**Look up a comment value by its tag. + \param _tags An initialized #OpusTags structure. + \param _tag The tag to look up. + \param _count The instance of the tag. + The same tag can appear multiple times, each with a distinct + value, so an index is required to retrieve them all. + The order in which these values appear is significant and + should be preserved. + Use opus_tags_query_count() to get the legal range for the + \a _count parameter. + \return A pointer to the queried tag's value. + This points directly to data in the #OpusTags structure. + It should not be modified or freed by the application, and + modifications to the structure may invalidate the pointer. + \retval NULL If no matching tag is found.*/ +const char *opus_tags_query(const OpusTags *_tags,const char *_tag,int _count) + OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); + +/**Look up the number of instances of a tag. + Call this first when querying for a specific tag and then iterate over the + number of instances with separate calls to opus_tags_query() to retrieve + all the values for that tag in order. + \param _tags An initialized #OpusTags structure. + \param _tag The tag to look up. + \return The number of instances of this particular tag.*/ +int opus_tags_query_count(const OpusTags *_tags,const char *_tag) + OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); + +/**Retrieve the binary suffix data at the end of the packet (if any). + \param _tags An initialized #OpusTags structure. + \param[out] _len Returns the number of bytes of binary suffix data returned. + \return A pointer to the binary suffix data, or NULL if none + was present.*/ +const unsigned char *opus_tags_get_binary_suffix(const OpusTags *_tags, + int *_len) OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); + +/**Get the album gain from an R128_ALBUM_GAIN tag, if one was specified. + This searches for the first R128_ALBUM_GAIN tag with a valid signed, + 16-bit decimal integer value and returns the value. + This routine is exposed merely for convenience for applications which wish + to do something special with the album gain (i.e., display it). + If you simply wish to apply the album gain instead of the header gain, you + can use op_set_gain_offset() with an #OP_ALBUM_GAIN type and no offset. + \param _tags An initialized #OpusTags structure. + \param[out] _gain_q8 The album gain, in 1/256ths of a dB. + This will lie in the range [-32768,32767], and should + be applied in addition to the header gain. + On error, no value is returned, and the previous + contents remain unchanged. + \return 0 on success, or a negative value on error. + \retval #OP_FALSE There was no album gain available in the given tags.*/ +int opus_tags_get_album_gain(const OpusTags *_tags,int *_gain_q8) + OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); + +/**Get the track gain from an R128_TRACK_GAIN tag, if one was specified. + This searches for the first R128_TRACK_GAIN tag with a valid signed, + 16-bit decimal integer value and returns the value. + This routine is exposed merely for convenience for applications which wish + to do something special with the track gain (i.e., display it). + If you simply wish to apply the track gain instead of the header gain, you + can use op_set_gain_offset() with an #OP_TRACK_GAIN type and no offset. + \param _tags An initialized #OpusTags structure. + \param[out] _gain_q8 The track gain, in 1/256ths of a dB. + This will lie in the range [-32768,32767], and should + be applied in addition to the header gain. + On error, no value is returned, and the previous + contents remain unchanged. + \return 0 on success, or a negative value on error. + \retval #OP_FALSE There was no track gain available in the given tags.*/ +int opus_tags_get_track_gain(const OpusTags *_tags,int *_gain_q8) + OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); + +/**Clears the #OpusTags structure. + This should be called on an #OpusTags structure after it is no longer + needed. + It will free all memory used by the structure members. + \param _tags The #OpusTags structure to clear.*/ +void opus_tags_clear(OpusTags *_tags) OP_ARG_NONNULL(1); + +/**Check if \a _comment is an instance of a \a _tag_name tag. + \see opus_tagncompare + \param _tag_name A NUL-terminated, case-insensitive, ASCII string containing + the name of the tag to check for (without the terminating + '=' character). + \param _comment The comment string to check. + \return An integer less than, equal to, or greater than zero if \a _comment + is found respectively, to be less than, to match, or be greater + than a "tag=value" string whose tag matches \a _tag_name.*/ +int opus_tagcompare(const char *_tag_name,const char *_comment); + +/**Check if \a _comment is an instance of a \a _tag_name tag. + This version is slightly more efficient than opus_tagcompare() if the length + of the tag name is already known (e.g., because it is a constant). + \see opus_tagcompare + \param _tag_name A case-insensitive ASCII string containing the name of the + tag to check for (without the terminating '=' character). + \param _tag_len The number of characters in the tag name. + This must be non-negative. + \param _comment The comment string to check. + \return An integer less than, equal to, or greater than zero if \a _comment + is found respectively, to be less than, to match, or be greater + than a "tag=value" string whose tag matches the first \a _tag_len + characters of \a _tag_name.*/ +int opus_tagncompare(const char *_tag_name,int _tag_len,const char *_comment); + +/**Parse a single METADATA_BLOCK_PICTURE tag. + This decodes the BASE64-encoded content of the tag and returns a structure + with the MIME type, description, image parameters (if known), and the + compressed image data. + If the MIME type indicates the presence of an image format we recognize + (JPEG, PNG, or GIF) and the actual image data contains the magic signature + associated with that format, then the OpusPictureTag::format field will be + set to the corresponding format. + This is provided as a convenience to avoid requiring applications to parse + the MIME type and/or do their own format detection for the commonly used + formats. + In this case, we also attempt to extract the image parameters directly from + the image data (overriding any that were present in the tag, which the + specification says applications are not meant to rely on). + The application must still provide its own support for actually decoding the + image data and, if applicable, retrieving that data from URLs. + \param[out] _pic Returns the parsed picture data. + No sanitation is done on the type, MIME type, or + description fields, so these might return invalid values. + The contents of this structure are left unmodified on + failure. + \param _tag The METADATA_BLOCK_PICTURE tag contents. + The leading "METADATA_BLOCK_PICTURE=" portion is optional, + to allow the function to be used on either directly on the + values in OpusTags::user_comments or on the return value + of opus_tags_query(). + \return 0 on success or a negative value on error. + \retval #OP_ENOTFORMAT The METADATA_BLOCK_PICTURE contents were not valid. + \retval #OP_EFAULT There was not enough memory to store the picture tag + contents.*/ +OP_WARN_UNUSED_RESULT int opus_picture_tag_parse(OpusPictureTag *_pic, + const char *_tag) OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); + +/**Initializes an #OpusPictureTag structure. + This should be called on a freshly allocated #OpusPictureTag structure + before attempting to use it. + \param _pic The #OpusPictureTag structure to initialize.*/ +void opus_picture_tag_init(OpusPictureTag *_pic) OP_ARG_NONNULL(1); + +/**Clears the #OpusPictureTag structure. + This should be called on an #OpusPictureTag structure after it is no longer + needed. + It will free all memory used by the structure members. + \param _pic The #OpusPictureTag structure to clear.*/ +void opus_picture_tag_clear(OpusPictureTag *_pic) OP_ARG_NONNULL(1); + +/*@}*/ + +/*@}*/ + +/**\defgroup url_options URL Reading Options*/ +/*@{*/ +/**\name URL reading options + Options for op_url_stream_create() and associated functions. + These allow you to provide proxy configuration parameters, skip SSL + certificate checks, etc. + Options are processed in order, and if the same option is passed multiple + times, only the value specified by the last occurrence has an effect + (unless otherwise specified). + They may be expanded in the future.*/ +/*@{*/ + +/**@cond PRIVATE*/ + +/*These are the raw numbers used to define the request codes. + They should not be used directly.*/ +#define OP_SSL_SKIP_CERTIFICATE_CHECK_REQUEST (6464) +#define OP_HTTP_PROXY_HOST_REQUEST (6528) +#define OP_HTTP_PROXY_PORT_REQUEST (6592) +#define OP_HTTP_PROXY_USER_REQUEST (6656) +#define OP_HTTP_PROXY_PASS_REQUEST (6720) +#define OP_GET_SERVER_INFO_REQUEST (6784) + +#define OP_URL_OPT(_request) ((char *)(_request)) + +/*These macros trigger compilation errors or warnings if the wrong types are + provided to one of the URL options.*/ +#define OP_CHECK_INT(_x) ((void)((_x)==(opus_int32)0),(opus_int32)(_x)) +#define OP_CHECK_CONST_CHAR_PTR(_x) ((_x)+((_x)-(const char *)(_x))) +#define OP_CHECK_SERVER_INFO_PTR(_x) ((_x)+((_x)-(OpusServerInfo *)(_x))) + +/**@endcond*/ + +/**HTTP/Shoutcast/Icecast server information associated with a URL.*/ +struct OpusServerInfo{ + /**The name of the server (icy-name/ice-name). + This is NULL if there was no icy-name or + ice-name header.*/ + char *name; + /**A short description of the server (icy-description/ice-description). + This is NULL if there was no icy-description or + ice-description header.*/ + char *description; + /**The genre the server falls under (icy-genre/ice-genre). + This is NULL if there was no icy-genre or + ice-genre header.*/ + char *genre; + /**The homepage for the server (icy-url/ice-url). + This is NULL if there was no icy-url or + ice-url header.*/ + char *url; + /**The software used by the origin server (Server). + This is NULL if there was no Server header.*/ + char *server; + /**The media type of the entity sent to the recepient (Content-Type). + This is NULL if there was no Content-Type + header.*/ + char *content_type; + /**The nominal stream bitrate in kbps (icy-br/ice-bitrate). + This is -1 if there was no icy-br or + ice-bitrate header.*/ + opus_int32 bitrate_kbps; + /**Flag indicating whether the server is public (1) or not + (0) (icy-pub/ice-public). + This is -1 if there was no icy-pub or + ice-public header.*/ + int is_public; + /**Flag indicating whether the server is using HTTPS instead of HTTP. + This is 0 unless HTTPS is being used. + This may not match the protocol used in the original URL if there were + redirections.*/ + int is_ssl; +}; + +/**Initializes an #OpusServerInfo structure. + All fields are set as if the corresponding header was not available. + \param _info The #OpusServerInfo structure to initialize. + \note If you use this function, you must link against libopusurl.*/ +void opus_server_info_init(OpusServerInfo *_info) OP_ARG_NONNULL(1); + +/**Clears the #OpusServerInfo structure. + This should be called on an #OpusServerInfo structure after it is no longer + needed. + It will free all memory used by the structure members. + \param _info The #OpusServerInfo structure to clear. + \note If you use this function, you must link against libopusurl.*/ +void opus_server_info_clear(OpusServerInfo *_info) OP_ARG_NONNULL(1); + +/**Skip the certificate check when connecting via TLS/SSL (https). + \param _b opus_int32: Whether or not to skip the certificate + check. + The check will be skipped if \a _b is non-zero, and will not be + skipped if \a _b is zero. + \hideinitializer*/ +#define OP_SSL_SKIP_CERTIFICATE_CHECK(_b) \ + OP_URL_OPT(OP_SSL_SKIP_CERTIFICATE_CHECK_REQUEST),OP_CHECK_INT(_b) + +/**Proxy connections through the given host. + If no port is specified via #OP_HTTP_PROXY_PORT, the port number defaults + to 8080 (http-alt). + All proxy parameters are ignored for non-http and non-https URLs. + \param _host const char *: The proxy server hostname. + This may be NULL to disable the use of a proxy + server. + \hideinitializer*/ +#define OP_HTTP_PROXY_HOST(_host) \ + OP_URL_OPT(OP_HTTP_PROXY_HOST_REQUEST),OP_CHECK_CONST_CHAR_PTR(_host) + +/**Use the given port when proxying connections. + This option only has an effect if #OP_HTTP_PROXY_HOST is specified with a + non-NULL \a _host. + If this option is not provided, the proxy port number defaults to 8080 + (http-alt). + All proxy parameters are ignored for non-http and non-https URLs. + \param _port opus_int32: The proxy server port. + This must be in the range 0...65535 (inclusive), or the + URL function this is passed to will fail. + \hideinitializer*/ +#define OP_HTTP_PROXY_PORT(_port) \ + OP_URL_OPT(OP_HTTP_PROXY_PORT_REQUEST),OP_CHECK_INT(_port) + +/**Use the given user name for authentication when proxying connections. + All proxy parameters are ignored for non-http and non-https URLs. + \param _user const char *: The proxy server user name. + This may be NULL to disable proxy + authentication. + A non-NULL value only has an effect + if #OP_HTTP_PROXY_HOST and #OP_HTTP_PROXY_PASS + are also specified with non-NULL + arguments. + \hideinitializer*/ +#define OP_HTTP_PROXY_USER(_user) \ + OP_URL_OPT(OP_HTTP_PROXY_USER_REQUEST),OP_CHECK_CONST_CHAR_PTR(_user) + +/**Use the given password for authentication when proxying connections. + All proxy parameters are ignored for non-http and non-https URLs. + \param _pass const char *: The proxy server password. + This may be NULL to disable proxy + authentication. + A non-NULL value only has an effect + if #OP_HTTP_PROXY_HOST and #OP_HTTP_PROXY_USER + are also specified with non-NULL + arguments. + \hideinitializer*/ +#define OP_HTTP_PROXY_PASS(_pass) \ + OP_URL_OPT(OP_HTTP_PROXY_PASS_REQUEST),OP_CHECK_CONST_CHAR_PTR(_pass) + +/**Parse information about the streaming server (if any) and return it. + Very little validation is done. + In particular, OpusServerInfo::url may not be a valid URL, + OpusServerInfo::bitrate_kbps may not really be in kbps, and + OpusServerInfo::content_type may not be a valid MIME type. + The character set of the string fields is not specified anywhere, and should + not be assumed to be valid UTF-8. + \param _info OpusServerInfo *: Returns information about the server. + If there is any error opening the stream, the + contents of this structure remain + unmodified. + On success, fills in the structure with the + server information that was available, if + any. + After a successful return, the contents of + this structure should be freed by calling + opus_server_info_clear(). + \hideinitializer*/ +#define OP_GET_SERVER_INFO(_info) \ + OP_URL_OPT(OP_GET_SERVER_INFO_REQUEST),OP_CHECK_SERVER_INFO_PTR(_info) + +/*@}*/ +/*@}*/ + +/**\defgroup stream_callbacks Abstract Stream Reading Interface*/ +/*@{*/ +/**\name Functions for reading from streams + These functions define the interface used to read from and seek in a stream + of data. + A stream does not need to implement seeking, but the decoder will not be + able to seek if it does not do so. + These functions also include some convenience routines for working with + standard FILE pointers, complete streams stored in a single + block of memory, or URLs.*/ +/*@{*/ + +/**Reads up to \a _nbytes bytes of data from \a _stream. + \param _stream The stream to read from. + \param[out] _ptr The buffer to store the data in. + \param _nbytes The maximum number of bytes to read. + This function may return fewer, though it will not + return zero unless it reaches end-of-file. + \return The number of bytes successfully read, or a negative value on + error.*/ +typedef int (*op_read_func)(void *_stream,unsigned char *_ptr,int _nbytes); + +/**Sets the position indicator for \a _stream. + The new position, measured in bytes, is obtained by adding \a _offset + bytes to the position specified by \a _whence. + If \a _whence is set to SEEK_SET, SEEK_CUR, or + SEEK_END, the offset is relative to the start of the stream, + the current position indicator, or end-of-file, respectively. + \retval 0 Success. + \retval -1 Seeking is not supported or an error occurred. + errno need not be set.*/ +typedef int (*op_seek_func)(void *_stream,opus_int64 _offset,int _whence); + +/**Obtains the current value of the position indicator for \a _stream. + \return The current position indicator.*/ +typedef opus_int64 (*op_tell_func)(void *_stream); + +/**Closes the underlying stream. + \retval 0 Success. + \retval EOF An error occurred. + errno need not be set.*/ +typedef int (*op_close_func)(void *_stream); + +/**The callbacks used to access non-FILE stream resources. + The function prototypes are basically the same as for the stdio functions + fread(), fseek(), ftell(), and + fclose(). + The differences are that the FILE * arguments have been + replaced with a void *, which is to be used as a pointer to + whatever internal data these functions might need, that #seek and #tell + take and return 64-bit offsets, and that #seek must return -1 if + the stream is unseekable.*/ +struct OpusFileCallbacks{ + /**Used to read data from the stream. + This must not be NULL.*/ + op_read_func read; + /**Used to seek in the stream. + This may be NULL if seeking is not implemented.*/ + op_seek_func seek; + /**Used to return the current read position in the stream. + This may be NULL if seeking is not implemented.*/ + op_tell_func tell; + /**Used to close the stream when the decoder is freed. + This may be NULL to leave the stream open.*/ + op_close_func close; +}; + +/**Opens a stream with fopen() and fills in a set of callbacks + that can be used to access it. + This is useful to avoid writing your own portable 64-bit seeking wrappers, + and also avoids cross-module linking issues on Windows, where a + FILE * must be accessed by routines defined in the same module + that opened it. + \param[out] _cb The callbacks to use for this file. + If there is an error opening the file, nothing will be + filled in here. + \param _path The path to the file to open. + On Windows, this string must be UTF-8 (to allow access to + files whose names cannot be represented in the current + MBCS code page). + All other systems use the native character encoding. + \param _mode The mode to open the file in. + \return A stream handle to use with the callbacks, or NULL on + error.*/ +OP_WARN_UNUSED_RESULT void *op_fopen(OpusFileCallbacks *_cb, + const char *_path,const char *_mode) OP_ARG_NONNULL(1) OP_ARG_NONNULL(2) + OP_ARG_NONNULL(3); + +/**Opens a stream with fdopen() and fills in a set of callbacks + that can be used to access it. + This is useful to avoid writing your own portable 64-bit seeking wrappers, + and also avoids cross-module linking issues on Windows, where a + FILE * must be accessed by routines defined in the same module + that opened it. + \param[out] _cb The callbacks to use for this file. + If there is an error opening the file, nothing will be + filled in here. + \param _fd The file descriptor to open. + \param _mode The mode to open the file in. + \return A stream handle to use with the callbacks, or NULL on + error.*/ +OP_WARN_UNUSED_RESULT void *op_fdopen(OpusFileCallbacks *_cb, + int _fd,const char *_mode) OP_ARG_NONNULL(1) OP_ARG_NONNULL(3); + +/**Opens a stream with freopen() and fills in a set of callbacks + that can be used to access it. + This is useful to avoid writing your own portable 64-bit seeking wrappers, + and also avoids cross-module linking issues on Windows, where a + FILE * must be accessed by routines defined in the same module + that opened it. + \param[out] _cb The callbacks to use for this file. + If there is an error opening the file, nothing will be + filled in here. + \param _path The path to the file to open. + On Windows, this string must be UTF-8 (to allow access + to files whose names cannot be represented in the + current MBCS code page). + All other systems use the native character encoding. + \param _mode The mode to open the file in. + \param _stream A stream previously returned by op_fopen(), op_fdopen(), + or op_freopen(). + \return A stream handle to use with the callbacks, or NULL on + error.*/ +OP_WARN_UNUSED_RESULT void *op_freopen(OpusFileCallbacks *_cb, + const char *_path,const char *_mode,void *_stream) OP_ARG_NONNULL(1) + OP_ARG_NONNULL(2) OP_ARG_NONNULL(3) OP_ARG_NONNULL(4); + +/**Creates a stream that reads from the given block of memory. + This block of memory must contain the complete stream to decode. + This is useful for caching small streams (e.g., sound effects) in RAM. + \param[out] _cb The callbacks to use for this stream. + If there is an error creating the stream, nothing will be + filled in here. + \param _data The block of memory to read from. + \param _size The size of the block of memory. + \return A stream handle to use with the callbacks, or NULL on + error.*/ +OP_WARN_UNUSED_RESULT void *op_mem_stream_create(OpusFileCallbacks *_cb, + const unsigned char *_data,size_t _size) OP_ARG_NONNULL(1); + +/**Creates a stream that reads from the given URL. + This function behaves identically to op_url_stream_create(), except that it + takes a va_list instead of a variable number of arguments. + It does not call the va_end macro, and because it invokes the + va_arg macro, the value of \a _ap is undefined after the call. + \note If you use this function, you must link against libopusurl. + \param[out] _cb The callbacks to use for this stream. + If there is an error creating the stream, nothing will + be filled in here. + \param _url The URL to read from. + Currently only the , , and + schemes are supported. + Both and may be disabled at compile + time, in which case opening such URLs will always fail. + Currently this only supports URIs. + IRIs should be converted to UTF-8 and URL-escaped, with + internationalized domain names encoded in punycode, + before passing them to this function. + \param[in,out] _ap A list of the \ref url_options "optional flags" to use. + This is a variable-length list of options terminated + with NULL. + \return A stream handle to use with the callbacks, or NULL on + error.*/ +OP_WARN_UNUSED_RESULT void *op_url_stream_vcreate(OpusFileCallbacks *_cb, + const char *_url,va_list _ap) OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); + +/**Creates a stream that reads from the given URL. + \note If you use this function, you must link against libopusurl. + \param[out] _cb The callbacks to use for this stream. + If there is an error creating the stream, nothing will be + filled in here. + \param _url The URL to read from. + Currently only the , , and schemes + are supported. + Both and may be disabled at compile time, + in which case opening such URLs will always fail. + Currently this only supports URIs. + IRIs should be converted to UTF-8 and URL-escaped, with + internationalized domain names encoded in punycode, before + passing them to this function. + \param ... The \ref url_options "optional flags" to use. + This is a variable-length list of options terminated with + NULL. + \return A stream handle to use with the callbacks, or NULL on + error.*/ +OP_WARN_UNUSED_RESULT void *op_url_stream_create(OpusFileCallbacks *_cb, + const char *_url,...) OP_ARG_NONNULL(1) OP_ARG_NONNULL(2); + +/*@}*/ +/*@}*/ + +/**\defgroup stream_open_close Opening and Closing*/ +/*@{*/ +/**\name Functions for opening and closing streams + + These functions allow you to test a stream to see if it is Opus, open it, + and close it. + Several flavors are provided for each of the built-in stream types, plus a + more general version which takes a set of application-provided callbacks.*/ +/*@{*/ + +/**Test to see if this is an Opus stream. + For good results, you will need at least 57 bytes (for a pure Opus-only + stream). + Something like 512 bytes will give more reliable results for multiplexed + streams. + This function is meant to be a quick-rejection filter. + Its purpose is not to guarantee that a stream is a valid Opus stream, but to + ensure that it looks enough like Opus that it isn't going to be recognized + as some other format (except possibly an Opus stream that is also + multiplexed with other codecs, such as video). + \param[out] _head The parsed ID header contents. + You may pass NULL if you do not need + this information. + If the function fails, the contents of this structure + remain untouched. + \param _initial_data An initial buffer of data from the start of the + stream. + \param _initial_bytes The number of bytes in \a _initial_data. + \return 0 if the data appears to be Opus, or a negative value on error. + \retval #OP_FALSE There was not enough data to tell if this was an Opus + stream or not. + \retval #OP_EFAULT An internal memory allocation failed. + \retval #OP_EIMPL The stream used a feature that is not implemented, + such as an unsupported channel family. + \retval #OP_ENOTFORMAT If the data did not contain a recognizable ID + header for an Opus stream. + \retval #OP_EVERSION If the version field signaled a version this library + does not know how to parse. + \retval #OP_EBADHEADER The ID header was not properly formatted or contained + illegal values.*/ +int op_test(OpusHead *_head, + const unsigned char *_initial_data,size_t _initial_bytes); + +/**Open a stream from the given file path. + \param _path The path to the file to open. + \param[out] _error Returns 0 on success, or a failure code on error. + You may pass in NULL if you don't want the + failure code. + The failure code will be #OP_EFAULT if the file could not + be opened, or one of the other failure codes from + op_open_callbacks() otherwise. + \return A freshly opened \c OggOpusFile, or NULL on error.*/ +OP_WARN_UNUSED_RESULT OggOpusFile *op_open_file(const char *_path,int *_error) + OP_ARG_NONNULL(1); + +/**Open a stream from a memory buffer. + \param _data The memory buffer to open. + \param _size The number of bytes in the buffer. + \param[out] _error Returns 0 on success, or a failure code on error. + You may pass in NULL if you don't want the + failure code. + See op_open_callbacks() for a full list of failure codes. + \return A freshly opened \c OggOpusFile, or NULL on error.*/ +OP_WARN_UNUSED_RESULT OggOpusFile *op_open_memory(const unsigned char *_data, + size_t _size,int *_error); + +/**Open a stream from a URL. + This function behaves identically to op_open_url(), except that it + takes a va_list instead of a variable number of arguments. + It does not call the va_end macro, and because it invokes the + va_arg macro, the value of \a _ap is undefined after the call. + \note If you use this function, you must link against libopusurl. + \param _url The URL to open. + Currently only the , , and + schemes are supported. + Both and may be disabled at compile + time, in which case opening such URLs will always + fail. + Currently this only supports URIs. + IRIs should be converted to UTF-8 and URL-escaped, + with internationalized domain names encoded in + punycode, before passing them to this function. + \param[out] _error Returns 0 on success, or a failure code on error. + You may pass in NULL if you don't want + the failure code. + See op_open_callbacks() for a full list of failure + codes. + \param[in,out] _ap A list of the \ref url_options "optional flags" to + use. + This is a variable-length list of options terminated + with NULL. + \return A freshly opened \c OggOpusFile, or NULL on error.*/ +OP_WARN_UNUSED_RESULT OggOpusFile *op_vopen_url(const char *_url, + int *_error,va_list _ap) OP_ARG_NONNULL(1); + +/**Open a stream from a URL. + \note If you use this function, you must link against libopusurl. + \param _url The URL to open. + Currently only the , , and schemes + are supported. + Both and may be disabled at compile + time, in which case opening such URLs will always fail. + Currently this only supports URIs. + IRIs should be converted to UTF-8 and URL-escaped, with + internationalized domain names encoded in punycode, + before passing them to this function. + \param[out] _error Returns 0 on success, or a failure code on error. + You may pass in NULL if you don't want the + failure code. + See op_open_callbacks() for a full list of failure codes. + \param ... The \ref url_options "optional flags" to use. + This is a variable-length list of options terminated with + NULL. + \return A freshly opened \c OggOpusFile, or NULL on error.*/ +OP_WARN_UNUSED_RESULT OggOpusFile *op_open_url(const char *_url, + int *_error,...) OP_ARG_NONNULL(1); + +/**Open a stream using the given set of callbacks to access it. + \param _stream The stream to read from (e.g., a FILE *). + This value will be passed verbatim as the first + argument to all of the callbacks. + \param _cb The callbacks with which to access the stream. + read() must + be implemented. + seek() and + tell() may + be NULL, or may always return -1 to + indicate a stream is unseekable, but if + seek() is + implemented and succeeds on a particular stream, then + tell() must + also. + close() may + be NULL, but if it is not, it will be + called when the \c OggOpusFile is destroyed by + op_free(). + It will not be called if op_open_callbacks() fails + with an error. + \param _initial_data An initial buffer of data from the start of the + stream. + Applications can read some number of bytes from the + start of the stream to help identify this as an Opus + stream, and then provide them here to allow the + stream to be opened, even if it is unseekable. + \param _initial_bytes The number of bytes in \a _initial_data. + If the stream is seekable, its current position (as + reported by + tell() + at the start of this function) must be equal to + \a _initial_bytes. + Otherwise, seeking to absolute positions will + generate inconsistent results. + \param[out] _error Returns 0 on success, or a failure code on error. + You may pass in NULL if you don't want + the failure code. + The failure code will be one of +
+
#OP_EREAD
+
An underlying read, seek, or tell operation + failed when it should have succeeded, or we failed + to find data in the stream we had seen before.
+
#OP_EFAULT
+
There was a memory allocation failure, or an + internal library error.
+
#OP_EIMPL
+
The stream used a feature that is not + implemented, such as an unsupported channel + family.
+
#OP_EINVAL
+
seek() + was implemented and succeeded on this source, but + tell() + did not, or the starting position indicator was + not equal to \a _initial_bytes.
+
#OP_ENOTFORMAT
+
The stream contained a link that did not have + any logical Opus streams in it.
+
#OP_EBADHEADER
+
A required header packet was not properly + formatted, contained illegal values, or was missing + altogether.
+
#OP_EVERSION
+
An ID header contained an unrecognized version + number.
+
#OP_EBADLINK
+
We failed to find data we had seen before after + seeking.
+
#OP_EBADTIMESTAMP
+
The first or last timestamp in a link failed + basic validity checks.
+
+ \return A freshly opened \c OggOpusFile, or NULL on error. + libopusfile does not take ownership of the stream + if the call fails. + The calling application is responsible for closing the stream if + this call returns an error.*/ +OP_WARN_UNUSED_RESULT OggOpusFile *op_open_callbacks(void *_stream, + const OpusFileCallbacks *_cb,const unsigned char *_initial_data, + size_t _initial_bytes,int *_error) OP_ARG_NONNULL(2); + +/**Partially open a stream from the given file path. + \see op_test_callbacks + \param _path The path to the file to open. + \param[out] _error Returns 0 on success, or a failure code on error. + You may pass in NULL if you don't want the + failure code. + The failure code will be #OP_EFAULT if the file could not + be opened, or one of the other failure codes from + op_open_callbacks() otherwise. + \return A partially opened \c OggOpusFile, or NULL on error.*/ +OP_WARN_UNUSED_RESULT OggOpusFile *op_test_file(const char *_path,int *_error) + OP_ARG_NONNULL(1); + +/**Partially open a stream from a memory buffer. + \see op_test_callbacks + \param _data The memory buffer to open. + \param _size The number of bytes in the buffer. + \param[out] _error Returns 0 on success, or a failure code on error. + You may pass in NULL if you don't want the + failure code. + See op_open_callbacks() for a full list of failure codes. + \return A partially opened \c OggOpusFile, or NULL on error.*/ +OP_WARN_UNUSED_RESULT OggOpusFile *op_test_memory(const unsigned char *_data, + size_t _size,int *_error); + +/**Partially open a stream from a URL. + This function behaves identically to op_test_url(), except that it + takes a va_list instead of a variable number of arguments. + It does not call the va_end macro, and because it invokes the + va_arg macro, the value of \a _ap is undefined after the call. + \note If you use this function, you must link against libopusurl. + \see op_test_url + \see op_test_callbacks + \param _url The URL to open. + Currently only the , , and + schemes are supported. + Both and may be disabled at compile + time, in which case opening such URLs will always + fail. + Currently this only supports URIs. + IRIs should be converted to UTF-8 and URL-escaped, + with internationalized domain names encoded in + punycode, before passing them to this function. + \param[out] _error Returns 0 on success, or a failure code on error. + You may pass in NULL if you don't want + the failure code. + See op_open_callbacks() for a full list of failure + codes. + \param[in,out] _ap A list of the \ref url_options "optional flags" to + use. + This is a variable-length list of options terminated + with NULL. + \return A partially opened \c OggOpusFile, or NULL on error.*/ +OP_WARN_UNUSED_RESULT OggOpusFile *op_vtest_url(const char *_url, + int *_error,va_list _ap) OP_ARG_NONNULL(1); + +/**Partially open a stream from a URL. + \note If you use this function, you must link against libopusurl. + \see op_test_callbacks + \param _url The URL to open. + Currently only the , , and + schemes are supported. + Both and may be disabled at compile + time, in which case opening such URLs will always fail. + Currently this only supports URIs. + IRIs should be converted to UTF-8 and URL-escaped, with + internationalized domain names encoded in punycode, + before passing them to this function. + \param[out] _error Returns 0 on success, or a failure code on error. + You may pass in NULL if you don't want the + failure code. + See op_open_callbacks() for a full list of failure + codes. + \param ... The \ref url_options "optional flags" to use. + This is a variable-length list of options terminated + with NULL. + \return A partially opened \c OggOpusFile, or NULL on error.*/ +OP_WARN_UNUSED_RESULT OggOpusFile *op_test_url(const char *_url, + int *_error,...) OP_ARG_NONNULL(1); + +/**Partially open a stream using the given set of callbacks to access it. + This tests for Opusness and loads the headers for the first link. + It does not seek (although it tests for seekability). + You can query a partially open stream for the few pieces of basic + information returned by op_serialno(), op_channel_count(), op_head(), and + op_tags() (but only for the first link). + You may also determine if it is seekable via a call to op_seekable(). + You cannot read audio from the stream, seek, get the size or duration, + get information from links other than the first one, or even get the total + number of links until you finish opening the stream with op_test_open(). + If you do not need to do any of these things, you can dispose of it with + op_free() instead. + + This function is provided mostly to simplify porting existing code that used + libvorbisfile. + For new code, you are likely better off using op_test() instead, which + is less resource-intensive, requires less data to succeed, and imposes a + hard limit on the amount of data it examines (important for unseekable + streams, where all such data must be buffered until you are sure of the + stream type). + \param _stream The stream to read from (e.g., a FILE *). + This value will be passed verbatim as the first + argument to all of the callbacks. + \param _cb The callbacks with which to access the stream. + read() must + be implemented. + seek() and + tell() may + be NULL, or may always return -1 to + indicate a stream is unseekable, but if + seek() is + implemented and succeeds on a particular stream, then + tell() must + also. + close() may + be NULL, but if it is not, it will be + called when the \c OggOpusFile is destroyed by + op_free(). + It will not be called if op_open_callbacks() fails + with an error. + \param _initial_data An initial buffer of data from the start of the + stream. + Applications can read some number of bytes from the + start of the stream to help identify this as an Opus + stream, and then provide them here to allow the + stream to be tested more thoroughly, even if it is + unseekable. + \param _initial_bytes The number of bytes in \a _initial_data. + If the stream is seekable, its current position (as + reported by + tell() + at the start of this function) must be equal to + \a _initial_bytes. + Otherwise, seeking to absolute positions will + generate inconsistent results. + \param[out] _error Returns 0 on success, or a failure code on error. + You may pass in NULL if you don't want + the failure code. + See op_open_callbacks() for a full list of failure + codes. + \return A partially opened \c OggOpusFile, or NULL on error. + libopusfile does not take ownership of the stream + if the call fails. + The calling application is responsible for closing the stream if + this call returns an error.*/ +OP_WARN_UNUSED_RESULT OggOpusFile *op_test_callbacks(void *_stream, + const OpusFileCallbacks *_cb,const unsigned char *_initial_data, + size_t _initial_bytes,int *_error) OP_ARG_NONNULL(2); + +/**Finish opening a stream partially opened with op_test_callbacks() or one of + the associated convenience functions. + If this function fails, you are still responsible for freeing the + \c OggOpusFile with op_free(). + \param _of The \c OggOpusFile to finish opening. + \return 0 on success, or a negative value on error. + \retval #OP_EREAD An underlying read, seek, or tell operation failed + when it should have succeeded. + \retval #OP_EFAULT There was a memory allocation failure, or an + internal library error. + \retval #OP_EIMPL The stream used a feature that is not implemented, + such as an unsupported channel family. + \retval #OP_EINVAL The stream was not partially opened with + op_test_callbacks() or one of the associated + convenience functions. + \retval #OP_ENOTFORMAT The stream contained a link that did not have any + logical Opus streams in it. + \retval #OP_EBADHEADER A required header packet was not properly + formatted, contained illegal values, or was + missing altogether. + \retval #OP_EVERSION An ID header contained an unrecognized version + number. + \retval #OP_EBADLINK We failed to find data we had seen before after + seeking. + \retval #OP_EBADTIMESTAMP The first or last timestamp in a link failed basic + validity checks.*/ +int op_test_open(OggOpusFile *_of) OP_ARG_NONNULL(1); + +/**Release all memory used by an \c OggOpusFile. + \param _of The \c OggOpusFile to free.*/ +void op_free(OggOpusFile *_of); + +/*@}*/ +/*@}*/ + +/**\defgroup stream_info Stream Information*/ +/*@{*/ +/**\name Functions for obtaining information about streams + + These functions allow you to get basic information about a stream, including + seekability, the number of links (for chained streams), plus the size, + duration, bitrate, header parameters, and meta information for each link + (or, where available, the stream as a whole). + Some of these (size, duration) are only available for seekable streams. + You can also query the current stream position, link, and playback time, + and instantaneous bitrate during playback. + + Some of these functions may be used successfully on the partially open + streams returned by op_test_callbacks() or one of the associated + convenience functions. + Their documention will indicate so explicitly.*/ +/*@{*/ + +/**Returns whether or not the stream being read is seekable. + This is true if +
    +
  1. The seek() and + tell() callbacks are both + non-NULL,
  2. +
  3. The seek() callback was + successfully executed at least once, and
  4. +
  5. The tell() callback was + successfully able to report the position indicator afterwards.
  6. +
+ This function may be called on partially-opened streams. + \param _of The \c OggOpusFile whose seekable status is to be returned. + \return A non-zero value if seekable, and 0 if unseekable.*/ +int op_seekable(const OggOpusFile *_of) OP_ARG_NONNULL(1); + +/**Returns the number of links in this chained stream. + This function may be called on partially-opened streams, but it will always + return 1. + The actual number of links is not known until the stream is fully opened. + \param _of The \c OggOpusFile from which to retrieve the link count. + \return For fully-open seekable streams, this returns the total number of + links in the whole stream, which will be at least 1. + For partially-open or unseekable streams, this always returns 1.*/ +int op_link_count(const OggOpusFile *_of) OP_ARG_NONNULL(1); + +/**Get the serial number of the given link in a (possibly-chained) Ogg Opus + stream. + This function may be called on partially-opened streams, but it will always + return the serial number of the Opus stream in the first link. + \param _of The \c OggOpusFile from which to retrieve the serial number. + \param _li The index of the link whose serial number should be retrieved. + Use a negative number to get the serial number of the current + link. + \return The serial number of the given link. + If \a _li is greater than the total number of links, this returns + the serial number of the last link. + If the stream is not seekable, this always returns the serial number + of the current link.*/ +opus_uint32 op_serialno(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1); + +/**Get the channel count of the given link in a (possibly-chained) Ogg Opus + stream. + This is equivalent to op_head(_of,_li)->channel_count, but + is provided for convenience. + This function may be called on partially-opened streams, but it will always + return the channel count of the Opus stream in the first link. + \param _of The \c OggOpusFile from which to retrieve the channel count. + \param _li The index of the link whose channel count should be retrieved. + Use a negative number to get the channel count of the current + link. + \return The channel count of the given link. + If \a _li is greater than the total number of links, this returns + the channel count of the last link. + If the stream is not seekable, this always returns the channel count + of the current link.*/ +int op_channel_count(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1); + +/**Get the total (compressed) size of the stream, or of an individual link in + a (possibly-chained) Ogg Opus stream, including all headers and Ogg muxing + overhead. + \warning If the Opus stream (or link) is concurrently multiplexed with other + logical streams (e.g., video), this returns the size of the entire stream + (or link), not just the number of bytes in the first logical Opus stream. + Returning the latter would require scanning the entire file. + \param _of The \c OggOpusFile from which to retrieve the compressed size. + \param _li The index of the link whose compressed size should be computed. + Use a negative number to get the compressed size of the entire + stream. + \return The compressed size of the entire stream if \a _li is negative, the + compressed size of link \a _li if it is non-negative, or a negative + value on error. + The compressed size of the entire stream may be smaller than that + of the underlying stream if trailing garbage was detected in the + file. + \retval #OP_EINVAL The stream is not seekable (so we can't know the length), + \a _li wasn't less than the total number of links in + the stream, or the stream was only partially open.*/ +opus_int64 op_raw_total(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1); + +/**Get the total PCM length (number of samples at 48 kHz) of the stream, or of + an individual link in a (possibly-chained) Ogg Opus stream. + Users looking for op_time_total() should use op_pcm_total() + instead. + Because timestamps in Opus are fixed at 48 kHz, there is no need for a + separate function to convert this to seconds (and leaving it out avoids + introducing floating point to the API, for those that wish to avoid it). + \param _of The \c OggOpusFile from which to retrieve the PCM offset. + \param _li The index of the link whose PCM length should be computed. + Use a negative number to get the PCM length of the entire stream. + \return The PCM length of the entire stream if \a _li is negative, the PCM + length of link \a _li if it is non-negative, or a negative value on + error. + \retval #OP_EINVAL The stream is not seekable (so we can't know the length), + \a _li wasn't less than the total number of links in + the stream, or the stream was only partially open.*/ +ogg_int64_t op_pcm_total(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1); + +/**Get the ID header information for the given link in a (possibly chained) Ogg + Opus stream. + This function may be called on partially-opened streams, but it will always + return the ID header information of the Opus stream in the first link. + \param _of The \c OggOpusFile from which to retrieve the ID header + information. + \param _li The index of the link whose ID header information should be + retrieved. + Use a negative number to get the ID header information of the + current link. + For an unseekable stream, \a _li is ignored, and the ID header + information for the current link is always returned, if + available. + \return The contents of the ID header for the given link.*/ +const OpusHead *op_head(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1); + +/**Get the comment header information for the given link in a (possibly + chained) Ogg Opus stream. + This function may be called on partially-opened streams, but it will always + return the tags from the Opus stream in the first link. + \param _of The \c OggOpusFile from which to retrieve the comment header + information. + \param _li The index of the link whose comment header information should be + retrieved. + Use a negative number to get the comment header information of + the current link. + For an unseekable stream, \a _li is ignored, and the comment + header information for the current link is always returned, if + available. + \return The contents of the comment header for the given link, or + NULL if this is an unseekable stream that encountered + an invalid link.*/ +const OpusTags *op_tags(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1); + +/**Retrieve the index of the current link. + This is the link that produced the data most recently read by + op_read_float() or its associated functions, or, after a seek, the link + that the seek target landed in. + Reading more data may advance the link index (even on the first read after a + seek). + \param _of The \c OggOpusFile from which to retrieve the current link index. + \return The index of the current link on success, or a negative value on + failure. + For seekable streams, this is a number between 0 (inclusive) and the + value returned by op_link_count() (exclusive). + For unseekable streams, this value starts at 0 and increments by one + each time a new link is encountered (even though op_link_count() + always returns 1). + \retval #OP_EINVAL The stream was only partially open.*/ +int op_current_link(const OggOpusFile *_of) OP_ARG_NONNULL(1); + +/**Computes the bitrate of the stream, or of an individual link in a + (possibly-chained) Ogg Opus stream. + The stream must be seekable to compute the bitrate. + For unseekable streams, use op_bitrate_instant() to get periodic estimates. + \warning If the Opus stream (or link) is concurrently multiplexed with other + logical streams (e.g., video), this uses the size of the entire stream (or + link) to compute the bitrate, not just the number of bytes in the first + logical Opus stream. + Returning the latter requires scanning the entire file, but this may be done + by decoding the whole file and calling op_bitrate_instant() once at the + end. + Install a trivial decoding callback with op_set_decode_callback() if you + wish to skip actual decoding during this process. + \param _of The \c OggOpusFile from which to retrieve the bitrate. + \param _li The index of the link whose bitrate should be computed. + Use a negative number to get the bitrate of the whole stream. + \return The bitrate on success, or a negative value on error. + \retval #OP_EINVAL The stream was only partially open, the stream was not + seekable, or \a _li was larger than the number of + links.*/ +opus_int32 op_bitrate(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1); + +/**Compute the instantaneous bitrate, measured as the ratio of bits to playable + samples decoded since a) the last call to op_bitrate_instant(), b) the last + seek, or c) the start of playback, whichever was most recent. + This will spike somewhat after a seek or at the start/end of a chain + boundary, as pre-skip, pre-roll, and end-trimming causes samples to be + decoded but not played. + \param _of The \c OggOpusFile from which to retrieve the bitrate. + \return The bitrate, in bits per second, or a negative value on error. + \retval #OP_FALSE No data has been decoded since any of the events + described above. + \retval #OP_EINVAL The stream was only partially open.*/ +opus_int32 op_bitrate_instant(OggOpusFile *_of) OP_ARG_NONNULL(1); + +/**Obtain the current value of the position indicator for \a _of. + \param _of The \c OggOpusFile from which to retrieve the position indicator. + \return The byte position that is currently being read from. + \retval #OP_EINVAL The stream was only partially open.*/ +opus_int64 op_raw_tell(const OggOpusFile *_of) OP_ARG_NONNULL(1); + +/**Obtain the PCM offset of the next sample to be read. + If the stream is not properly timestamped, this might not increment by the + proper amount between reads, or even return monotonically increasing + values. + \param _of The \c OggOpusFile from which to retrieve the PCM offset. + \return The PCM offset of the next sample to be read. + \retval #OP_EINVAL The stream was only partially open.*/ +ogg_int64_t op_pcm_tell(const OggOpusFile *_of) OP_ARG_NONNULL(1); + +/*@}*/ +/*@}*/ + +/**\defgroup stream_seeking Seeking*/ +/*@{*/ +/**\name Functions for seeking in Opus streams + + These functions let you seek in Opus streams, if the underlying stream + support it. + Seeking is implemented for all built-in stream I/O routines, though some + individual streams may not be seekable (pipes, live HTTP streams, or HTTP + streams from a server that does not support Range requests). + + op_raw_seek() is the fastest: it is guaranteed to perform at most one + physical seek, but, since the target is a byte position, makes no guarantee + how close to a given time it will come. + op_pcm_seek() provides sample-accurate seeking. + The number of physical seeks it requires is still quite small (often 1 or + 2, even in highly variable bitrate streams). + + Seeking in Opus requires decoding some pre-roll amount before playback to + allow the internal state to converge (as if recovering from packet loss). + This is handled internally by libopusfile, but means there is + little extra overhead for decoding up to the exact position requested + (since it must decode some amount of audio anyway). + It also means that decoding after seeking may not return exactly the same + values as would be obtained by decoding the stream straight through. + However, such differences are expected to be smaller than the loss + introduced by Opus's lossy compression.*/ +/*@{*/ + +/**Seek to a byte offset relative to the compressed data. + This also scans packets to update the PCM cursor. + It will cross a logical bitstream boundary, but only if it can't get any + packets out of the tail of the link to which it seeks. + \param _of The \c OggOpusFile in which to seek. + \param _byte_offset The byte position to seek to. + This must be between 0 and #op_raw_total(\a _of,\c -1) + (inclusive). + \return 0 on success, or a negative error code on failure. + \retval #OP_EREAD The underlying seek operation failed. + \retval #OP_EINVAL The stream was only partially open, or the target was + outside the valid range for the stream. + \retval #OP_ENOSEEK This stream is not seekable. + \retval #OP_EBADLINK Failed to initialize a decoder for a stream for an + unknown reason.*/ +int op_raw_seek(OggOpusFile *_of,opus_int64 _byte_offset) OP_ARG_NONNULL(1); + +/**Seek to the specified PCM offset, such that decoding will begin at exactly + the requested position. + \param _of The \c OggOpusFile in which to seek. + \param _pcm_offset The PCM offset to seek to. + This is in samples at 48 kHz relative to the start of the + stream. + \return 0 on success, or a negative value on error. + \retval #OP_EREAD An underlying read or seek operation failed. + \retval #OP_EINVAL The stream was only partially open, or the target was + outside the valid range for the stream. + \retval #OP_ENOSEEK This stream is not seekable. + \retval #OP_EBADLINK We failed to find data we had seen before, or the + bitstream structure was sufficiently malformed that + seeking to the target destination was impossible.*/ +int op_pcm_seek(OggOpusFile *_of,ogg_int64_t _pcm_offset) OP_ARG_NONNULL(1); + +/*@}*/ +/*@}*/ + +/**\defgroup stream_decoding Decoding*/ +/*@{*/ +/**\name Functions for decoding audio data + + These functions retrieve actual decoded audio data from the stream. + The general functions, op_read() and op_read_float() return 16-bit or + floating-point output, both using native endian ordering. + The number of channels returned can change from link to link in a chained + stream. + There are special functions, op_read_stereo() and op_read_float_stereo(), + which always output two channels, to simplify applications which do not + wish to handle multichannel audio. + These downmix multichannel files to two channels, so they can always return + samples in the same format for every link in a chained file. + + If the rest of your audio processing chain can handle floating point, the + floating-point routines should be preferred, as they prevent clipping and + other issues which might be avoided entirely if, e.g., you scale down the + volume at some other stage. + However, if you intend to consume 16-bit samples directly, the conversion in + libopusfile provides noise-shaping dithering and, if compiled + against libopus 1.1 or later, soft-clipping prevention. + + libopusfile can also be configured at compile time to use the + fixed-point libopus API. + If so, libopusfile's floating-point API may also be disabled. + In that configuration, nothing in libopusfile will use any + floating-point operations, to simplify support on devices without an + adequate FPU. + + \warning HTTPS streams may be be vulnerable to truncation attacks if you do + not check the error return code from op_read_float() or its associated + functions. + If the remote peer does not close the connection gracefully (with a TLS + "close notify" message), these functions will return #OP_EREAD instead of 0 + when they reach the end of the file. + If you are reading from an URL (particularly if seeking is not + supported), you should make sure to check for this error and warn the user + appropriately.*/ +/*@{*/ + +/**Indicates that the decoding callback should produce signed 16-bit + native-endian output samples.*/ +#define OP_DEC_FORMAT_SHORT (7008) +/**Indicates that the decoding callback should produce 32-bit native-endian + float samples.*/ +#define OP_DEC_FORMAT_FLOAT (7040) + +/**Indicates that the decoding callback did not decode anything, and that + libopusfile should decode normally instead.*/ +#define OP_DEC_USE_DEFAULT (6720) + +/**Called to decode an Opus packet. + This should invoke the functional equivalent of opus_multistream_decode() or + opus_multistream_decode_float(), except that it returns 0 on success + instead of the number of decoded samples (which is known a priori). + \param _ctx The application-provided callback context. + \param _decoder The decoder to use to decode the packet. + \param[out] _pcm The buffer to decode into. + This will always have enough room for \a _nchannels of + \a _nsamples samples, which should be placed into this + buffer interleaved. + \param _op The packet to decode. + This will always have its granule position set to a valid + value. + \param _nsamples The number of samples expected from the packet. + \param _nchannels The number of channels expected from the packet. + \param _format The desired sample output format. + This is either #OP_DEC_FORMAT_SHORT or + #OP_DEC_FORMAT_FLOAT. + \param _li The index of the link from which this packet was decoded. + \return A non-negative value on success, or a negative value on error. + Any error codes should be the same as those returned by + opus_multistream_decode() or opus_multistream_decode_float(). + Success codes are as follows: + \retval 0 Decoding was successful. + The application has filled the buffer with + exactly \a _nsamples*\a + _nchannels samples in the requested + format. + \retval #OP_DEC_USE_DEFAULT No decoding was done. + libopusfile should do the decoding + by itself instead.*/ +typedef int (*op_decode_cb_func)(void *_ctx,OpusMSDecoder *_decoder,void *_pcm, + const ogg_packet *_op,int _nsamples,int _nchannels,int _format,int _li); + +/**Sets the packet decode callback function. + If set, this is called once for each packet that needs to be decoded. + This can be used by advanced applications to do additional processing on the + compressed or uncompressed data. + For example, an application might save the final entropy coder state for + debugging and testing purposes, or it might apply additional filters + before the downmixing, dithering, or soft-clipping performed by + libopusfile, so long as these filters do not introduce any + latency. + + A call to this function is no guarantee that the audio will eventually be + delivered to the application. + libopusfile may discard some or all of the decoded audio data + (i.e., at the beginning or end of a link, or after a seek), however the + callback is still required to provide all of it. + \param _of The \c OggOpusFile on which to set the decode callback. + \param _decode_cb The callback function to call. + This may be NULL to disable calling the + callback. + \param _ctx The application-provided context pointer to pass to the + callback on each call.*/ +void op_set_decode_callback(OggOpusFile *_of, + op_decode_cb_func _decode_cb,void *_ctx) OP_ARG_NONNULL(1); + +/**Gain offset type that indicates that the provided offset is relative to the + header gain. + This is the default.*/ +#define OP_HEADER_GAIN (0) + +/**Gain offset type that indicates that the provided offset is relative to the + R128_ALBUM_GAIN value (if any), in addition to the header gain.*/ +#define OP_ALBUM_GAIN (3007) + +/**Gain offset type that indicates that the provided offset is relative to the + R128_TRACK_GAIN value (if any), in addition to the header gain.*/ +#define OP_TRACK_GAIN (3008) + +/**Gain offset type that indicates that the provided offset should be used as + the gain directly, without applying any the header or track gains.*/ +#define OP_ABSOLUTE_GAIN (3009) + +/**Sets the gain to be used for decoded output. + By default, the gain in the header is applied with no additional offset. + The total gain (including header gain and/or track gain, if applicable, and + this offset), will be clamped to [-32768,32767]/256 dB. + This is more than enough to saturate or underflow 16-bit PCM. + \note The new gain will not be applied to any already buffered, decoded + output. + This means you cannot change it sample-by-sample, as at best it will be + updated packet-by-packet. + It is meant for setting a target volume level, rather than applying smooth + fades, etc. + \param _of The \c OggOpusFile on which to set the gain offset. + \param _gain_type One of #OP_HEADER_GAIN, #OP_ALBUM_GAIN, + #OP_TRACK_GAIN, or #OP_ABSOLUTE_GAIN. + \param _gain_offset_q8 The gain offset to apply, in 1/256ths of a dB. + \return 0 on success or a negative value on error. + \retval #OP_EINVAL The \a _gain_type was unrecognized.*/ +int op_set_gain_offset(OggOpusFile *_of, + int _gain_type,opus_int32 _gain_offset_q8) OP_ARG_NONNULL(1); + +/**Sets whether or not dithering is enabled for 16-bit decoding. + By default, when libopusfile is compiled to use floating-point + internally, calling op_read() or op_read_stereo() will first decode to + float, and then convert to fixed-point using noise-shaping dithering. + This flag can be used to disable that dithering. + When the application uses op_read_float() or op_read_float_stereo(), or when + the library has been compiled to decode directly to fixed point, this flag + has no effect. + \param _of The \c OggOpusFile on which to enable or disable dithering. + \param _enabled A non-zero value to enable dithering, or 0 to disable it.*/ +void op_set_dither_enabled(OggOpusFile *_of,int _enabled) OP_ARG_NONNULL(1); + +/**Reads more samples from the stream. + \note Although \a _buf_size must indicate the total number of values that + can be stored in \a _pcm, the return value is the number of samples + per channel. + This is done because +
    +
  1. The channel count cannot be known a priori (reading more samples might + advance us into the next link, with a different channel count), so + \a _buf_size cannot also be in units of samples per channel,
  2. +
  3. Returning the samples per channel matches the libopus API + as closely as we're able,
  4. +
  5. Returning the total number of values instead of samples per channel + would mean the caller would need a division to compute the samples per + channel, and might worry about the possibility of getting back samples + for some channels and not others, and
  6. +
  7. This approach is relatively fool-proof: if an application passes too + small a value to \a _buf_size, they will simply get fewer samples back, + and if they assume the return value is the total number of values, then + they will simply read too few (rather than reading too many and going + off the end of the buffer).
  8. +
+ \param _of The \c OggOpusFile from which to read. + \param[out] _pcm A buffer in which to store the output PCM samples, as + signed native-endian 16-bit values at 48 kHz + with a nominal range of [-32768,32767). + Multiple channels are interleaved using the + Vorbis + channel ordering. + This must have room for at least \a _buf_size values. + \param _buf_size The number of values that can be stored in \a _pcm. + It is recommended that this be large enough for at + least 120 ms of data at 48 kHz per channel (5760 + values per channel). + Smaller buffers will simply return less data, possibly + consuming more memory to buffer the data internally. + libopusfile may return less data than + requested. + If so, there is no guarantee that the remaining data + in \a _pcm will be unmodified. + \param[out] _li The index of the link this data was decoded from. + You may pass NULL if you do not need this + information. + If this function fails (returning a negative value), + this parameter is left unset. + \return The number of samples read per channel on success, or a negative + value on failure. + The channel count can be retrieved on success by calling + op_head(_of,*_li). + The number of samples returned may be 0 if the buffer was too small + to store even a single sample for all channels, or if end-of-file + was reached. + The list of possible failure codes follows. + Most of them can only be returned by unseekable, chained streams + that encounter a new link. + \retval #OP_HOLE There was a hole in the data, and some samples + may have been skipped. + Call this function again to continue decoding + past the hole. + \retval #OP_EREAD An underlying read operation failed. + This may signal a truncation attack from an + source. + \retval #OP_EFAULT An internal memory allocation failed. + \retval #OP_EIMPL An unseekable stream encountered a new link that + used a feature that is not implemented, such as + an unsupported channel family. + \retval #OP_EINVAL The stream was only partially open. + \retval #OP_ENOTFORMAT An unseekable stream encountered a new link that + did not have any logical Opus streams in it. + \retval #OP_EBADHEADER An unseekable stream encountered a new link with a + required header packet that was not properly + formatted, contained illegal values, or was + missing altogether. + \retval #OP_EVERSION An unseekable stream encountered a new link with + an ID header that contained an unrecognized + version number. + \retval #OP_EBADPACKET Failed to properly decode the next packet. + \retval #OP_EBADLINK We failed to find data we had seen before. + \retval #OP_EBADTIMESTAMP An unseekable stream encountered a new link with + a starting timestamp that failed basic validity + checks.*/ +OP_WARN_UNUSED_RESULT int op_read(OggOpusFile *_of, + opus_int16 *_pcm,int _buf_size,int *_li) OP_ARG_NONNULL(1); + +/**Reads more samples from the stream. + \note Although \a _buf_size must indicate the total number of values that + can be stored in \a _pcm, the return value is the number of samples + per channel. +
    +
  1. The channel count cannot be known a priori (reading more samples might + advance us into the next link, with a different channel count), so + \a _buf_size cannot also be in units of samples per channel,
  2. +
  3. Returning the samples per channel matches the libopus API + as closely as we're able,
  4. +
  5. Returning the total number of values instead of samples per channel + would mean the caller would need a division to compute the samples per + channel, and might worry about the possibility of getting back samples + for some channels and not others, and
  6. +
  7. This approach is relatively fool-proof: if an application passes too + small a value to \a _buf_size, they will simply get fewer samples back, + and if they assume the return value is the total number of values, then + they will simply read too few (rather than reading too many and going + off the end of the buffer).
  8. +
+ \param _of The \c OggOpusFile from which to read. + \param[out] _pcm A buffer in which to store the output PCM samples as + signed floats at 48 kHz with a nominal range of + [-1.0,1.0]. + Multiple channels are interleaved using the + Vorbis + channel ordering. + This must have room for at least \a _buf_size floats. + \param _buf_size The number of floats that can be stored in \a _pcm. + It is recommended that this be large enough for at + least 120 ms of data at 48 kHz per channel (5760 + samples per channel). + Smaller buffers will simply return less data, possibly + consuming more memory to buffer the data internally. + If less than \a _buf_size values are returned, + libopusfile makes no guarantee that the + remaining data in \a _pcm will be unmodified. + \param[out] _li The index of the link this data was decoded from. + You may pass NULL if you do not need this + information. + If this function fails (returning a negative value), + this parameter is left unset. + \return The number of samples read per channel on success, or a negative + value on failure. + The channel count can be retrieved on success by calling + op_head(_of,*_li). + The number of samples returned may be 0 if the buffer was too small + to store even a single sample for all channels, or if end-of-file + was reached. + The list of possible failure codes follows. + Most of them can only be returned by unseekable, chained streams + that encounter a new link. + \retval #OP_HOLE There was a hole in the data, and some samples + may have been skipped. + Call this function again to continue decoding + past the hole. + \retval #OP_EREAD An underlying read operation failed. + This may signal a truncation attack from an + source. + \retval #OP_EFAULT An internal memory allocation failed. + \retval #OP_EIMPL An unseekable stream encountered a new link that + used a feature that is not implemented, such as + an unsupported channel family. + \retval #OP_EINVAL The stream was only partially open. + \retval #OP_ENOTFORMAT An unseekable stream encountered a new link that + did not have any logical Opus streams in it. + \retval #OP_EBADHEADER An unseekable stream encountered a new link with a + required header packet that was not properly + formatted, contained illegal values, or was + missing altogether. + \retval #OP_EVERSION An unseekable stream encountered a new link with + an ID header that contained an unrecognized + version number. + \retval #OP_EBADPACKET Failed to properly decode the next packet. + \retval #OP_EBADLINK We failed to find data we had seen before. + \retval #OP_EBADTIMESTAMP An unseekable stream encountered a new link with + a starting timestamp that failed basic validity + checks.*/ +OP_WARN_UNUSED_RESULT int op_read_float(OggOpusFile *_of, + float *_pcm,int _buf_size,int *_li) OP_ARG_NONNULL(1); + +/**Reads more samples from the stream and downmixes to stereo, if necessary. + This function is intended for simple players that want a uniform output + format, even if the channel count changes between links in a chained + stream. + \note \a _buf_size indicates the total number of values that can be stored + in \a _pcm, while the return value is the number of samples per + channel, even though the channel count is known, for consistency with + op_read(). + \param _of The \c OggOpusFile from which to read. + \param[out] _pcm A buffer in which to store the output PCM samples, as + signed native-endian 16-bit values at 48 kHz + with a nominal range of [-32768,32767). + The left and right channels are interleaved in the + buffer. + This must have room for at least \a _buf_size values. + \param _buf_size The number of values that can be stored in \a _pcm. + It is recommended that this be large enough for at + least 120 ms of data at 48 kHz per channel (11520 + values total). + Smaller buffers will simply return less data, possibly + consuming more memory to buffer the data internally. + If less than \a _buf_size values are returned, + libopusfile makes no guarantee that the + remaining data in \a _pcm will be unmodified. + \return The number of samples read per channel on success, or a negative + value on failure. + The number of samples returned may be 0 if the buffer was too small + to store even a single sample for both channels, or if end-of-file + was reached. + The list of possible failure codes follows. + Most of them can only be returned by unseekable, chained streams + that encounter a new link. + \retval #OP_HOLE There was a hole in the data, and some samples + may have been skipped. + Call this function again to continue decoding + past the hole. + \retval #OP_EREAD An underlying read operation failed. + This may signal a truncation attack from an + source. + \retval #OP_EFAULT An internal memory allocation failed. + \retval #OP_EIMPL An unseekable stream encountered a new link that + used a feature that is not implemented, such as + an unsupported channel family. + \retval #OP_EINVAL The stream was only partially open. + \retval #OP_ENOTFORMAT An unseekable stream encountered a new link that + did not have any logical Opus streams in it. + \retval #OP_EBADHEADER An unseekable stream encountered a new link with a + required header packet that was not properly + formatted, contained illegal values, or was + missing altogether. + \retval #OP_EVERSION An unseekable stream encountered a new link with + an ID header that contained an unrecognized + version number. + \retval #OP_EBADPACKET Failed to properly decode the next packet. + \retval #OP_EBADLINK We failed to find data we had seen before. + \retval #OP_EBADTIMESTAMP An unseekable stream encountered a new link with + a starting timestamp that failed basic validity + checks.*/ +OP_WARN_UNUSED_RESULT int op_read_stereo(OggOpusFile *_of, + opus_int16 *_pcm,int _buf_size) OP_ARG_NONNULL(1); + +/**Reads more samples from the stream and downmixes to stereo, if necessary. + This function is intended for simple players that want a uniform output + format, even if the channel count changes between links in a chained + stream. + \note \a _buf_size indicates the total number of values that can be stored + in \a _pcm, while the return value is the number of samples per + channel, even though the channel count is known, for consistency with + op_read_float(). + \param _of The \c OggOpusFile from which to read. + \param[out] _pcm A buffer in which to store the output PCM samples, as + signed floats at 48 kHz with a nominal range of + [-1.0,1.0]. + The left and right channels are interleaved in the + buffer. + This must have room for at least \a _buf_size values. + \param _buf_size The number of values that can be stored in \a _pcm. + It is recommended that this be large enough for at + least 120 ms of data at 48 kHz per channel (11520 + values total). + Smaller buffers will simply return less data, possibly + consuming more memory to buffer the data internally. + If less than \a _buf_size values are returned, + libopusfile makes no guarantee that the + remaining data in \a _pcm will be unmodified. + \return The number of samples read per channel on success, or a negative + value on failure. + The number of samples returned may be 0 if the buffer was too small + to store even a single sample for both channels, or if end-of-file + was reached. + The list of possible failure codes follows. + Most of them can only be returned by unseekable, chained streams + that encounter a new link. + \retval #OP_HOLE There was a hole in the data, and some samples + may have been skipped. + Call this function again to continue decoding + past the hole. + \retval #OP_EREAD An underlying read operation failed. + This may signal a truncation attack from an + source. + \retval #OP_EFAULT An internal memory allocation failed. + \retval #OP_EIMPL An unseekable stream encountered a new link that + used a feature that is not implemented, such as + an unsupported channel family. + \retval #OP_EINVAL The stream was only partially open. + \retval #OP_ENOTFORMAT An unseekable stream encountered a new link that + that did not have any logical Opus streams in it. + \retval #OP_EBADHEADER An unseekable stream encountered a new link with a + required header packet that was not properly + formatted, contained illegal values, or was + missing altogether. + \retval #OP_EVERSION An unseekable stream encountered a new link with + an ID header that contained an unrecognized + version number. + \retval #OP_EBADPACKET Failed to properly decode the next packet. + \retval #OP_EBADLINK We failed to find data we had seen before. + \retval #OP_EBADTIMESTAMP An unseekable stream encountered a new link with + a starting timestamp that failed basic validity + checks.*/ +OP_WARN_UNUSED_RESULT int op_read_float_stereo(OggOpusFile *_of, + float *_pcm,int _buf_size) OP_ARG_NONNULL(1); + +/*@}*/ +/*@}*/ + +# if OP_GNUC_PREREQ(4,0) +# pragma GCC visibility pop +# endif + +# if defined(__cplusplus) +} +# endif + +#endif diff --git a/engine/voice_codecs/opus/voiceencoder_opus.cpp b/engine/voice_codecs/opus/voiceencoder_opus.cpp new file mode 100644 index 00000000..203539bc --- /dev/null +++ b/engine/voice_codecs/opus/voiceencoder_opus.cpp @@ -0,0 +1,184 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +// $NoKeywords: $ +// +//=============================================================================// +#include "ivoicecodec.h" +#include "iframeencoder.h" + +#include +#include +#include + + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" +#include "tier0/dbg.h" + +#define CHANNELS 1 + +struct opus_options +{ + int iSampleRate; + int iRawFrameSize; + int iPacketSize; +}; + +opus_options g_OpusOpts[] = +{ + {44100, 256, 120}, + {22050, 120, 60}, + {22050, 256, 60}, + {22050, 512, 64}, +}; + +class VoiceEncoder_Opus : public IFrameEncoder +{ +public: + VoiceEncoder_Opus(); + virtual ~VoiceEncoder_Opus(); + + // Interfaces IFrameDecoder + + bool Init(int quality, int &rawFrameSize, int &encodedFrameSize); + void Release(); + void DecodeFrame(const char *pCompressed, char *pDecompressedBytes); + void EncodeFrame(const char *pUncompressedBytes, char *pCompressed); + bool ResetState(); + +private: + + bool InitStates(); + void TermStates(); + + OpusCustomEncoder *m_EncoderState; // Celt internal encoder state + OpusCustomDecoder *m_DecoderState; // Celt internal decoder state + OpusCustomMode *m_Mode; + + int m_iVersion; +}; + +extern IVoiceCodec* CreateVoiceCodec_Frame(IFrameEncoder *pEncoder); + +void* CreateCeltVoiceCodec() +{ + IFrameEncoder *pEncoder = new VoiceEncoder_Opus; + return CreateVoiceCodec_Frame( pEncoder ); +} + +EXPOSE_INTERFACE_FN(CreateCeltVoiceCodec, IVoiceCodec, "vaudio_opus") + +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +VoiceEncoder_Opus::VoiceEncoder_Opus() +{ + m_EncoderState = NULL; + m_DecoderState = NULL; + m_Mode = NULL; + m_iVersion = 0; +} + +VoiceEncoder_Opus::~VoiceEncoder_Opus() +{ + TermStates(); +} + +bool VoiceEncoder_Opus::Init( int quality, int &rawFrameSize, int &encodedFrameSize) +{ + m_iVersion = quality; + + rawFrameSize = g_OpusOpts[m_iVersion].iRawFrameSize * BYTES_PER_SAMPLE; + + int iError = 0; + + m_Mode = opus_custom_mode_create( g_OpusOpts[m_iVersion].iSampleRate, g_OpusOpts[m_iVersion].iRawFrameSize, &iError ); + + m_EncoderState = opus_custom_encoder_create( m_Mode, CHANNELS, NULL); + m_DecoderState = opus_custom_decoder_create( m_Mode, CHANNELS, NULL); + + if ( !InitStates() ) + return false; + + encodedFrameSize = g_OpusOpts[m_iVersion].iPacketSize; + + return true; +} + +void VoiceEncoder_Opus::Release() +{ + delete this; +} + +void VoiceEncoder_Opus::EncodeFrame(const char *pUncompressedBytes, char *pCompressed) +{ + unsigned char output[1024]; + + opus_custom_encode( m_EncoderState, (opus_int16*)pUncompressedBytes, g_OpusOpts[m_iVersion].iRawFrameSize, output, g_OpusOpts[m_iVersion].iPacketSize ); + + for ( int i = 0; i < g_OpusOpts[m_iVersion].iPacketSize; i++ ) + { + *pCompressed = (char)output[i]; + pCompressed++; + } +} + +void VoiceEncoder_Opus::DecodeFrame(const char *pCompressed, char *pDecompressedBytes) +{ + unsigned char output[1024]; + char *out = (char *)pCompressed; + + if ( !pCompressed ) + { + int decoded = opus_custom_decode( m_DecoderState, NULL, g_OpusOpts[m_iVersion].iPacketSize, (opus_int16 *)pDecompressedBytes, g_OpusOpts[m_iVersion].iRawFrameSize ); + return; + } + + for ( int i = 0; i < g_OpusOpts[m_iVersion].iPacketSize; i++ ) + { + output[i] = ( unsigned char ) ( ( *out < 0 ) ? (*out + 256) : *out ); + out++; + } + + //celt_decoder_ctl( m_DecoderState, CELT_RESET_STATE_REQUEST, NULL ); + int decoded = opus_custom_decode( m_DecoderState, output, g_OpusOpts[m_iVersion].iPacketSize, (opus_int16 *)pDecompressedBytes, g_OpusOpts[m_iVersion].iRawFrameSize ); +} + +bool VoiceEncoder_Opus::ResetState() +{ + opus_custom_encoder_ctl(m_EncoderState, OPUS_RESET_STATE ); + opus_custom_decoder_ctl(m_DecoderState, OPUS_RESET_STATE ); + + return true; +} + +bool VoiceEncoder_Opus::InitStates() +{ + if ( !m_EncoderState || !m_DecoderState ) + return false; + + opus_custom_encoder_ctl(m_EncoderState, OPUS_RESET_STATE ); + opus_custom_decoder_ctl(m_DecoderState, OPUS_RESET_STATE ); + + return true; +} + +void VoiceEncoder_Opus::TermStates() +{ + if( m_EncoderState ) + { + opus_custom_encoder_destroy( m_EncoderState ); + m_EncoderState = NULL; + } + + if( m_DecoderState ) + { + opus_custom_decoder_destroy( m_DecoderState ); + m_DecoderState = NULL; + } + + opus_custom_mode_destroy( m_Mode ); +} diff --git a/engine/voice_codecs/opus/wscript b/engine/voice_codecs/opus/wscript new file mode 100755 index 00000000..ce9207d3 --- /dev/null +++ b/engine/voice_codecs/opus/wscript @@ -0,0 +1,53 @@ +#! /usr/bin/env python +# encoding: utf-8 + +from waflib import Utils +import os + +top = '.' +PROJECT_NAME = 'vaudio_opus' + +def options(opt): + return + +def configure(conf): + conf.define('OPUS_EXPORTS',1) + +def build(bld): + source = [ + 'voiceencoder_opus.cpp', + '../frame_encoder/voice_codec_frame.cpp', + '../../../tier1/interface.cpp' + ] + + includes = [ + '.', + '../frame_encoder', + '../../../public', + '../../../public/tier1', + '../../../public/tier0', + '../../', + '../../../common', + '../../audio/public', + 'celt' + ] + + defines = [] + + libs = ['tier0','tier1','vstdlib','OPUS'] + + install_path = bld.env.LIBDIR + + bld.shlib( + source = source, + target = PROJECT_NAME, + name = PROJECT_NAME, + features = 'c cxx', + includes = includes, + defines = defines, + use = libs, + install_path = install_path, + subsystem = bld.env.MSVC_SUBSYSTEM, + idx = bld.get_taskgen_count() + ) + diff --git a/engine/voice_codecs/speex/VoiceEncoder_Speex.h b/engine/voice_codecs/speex/VoiceEncoder_Speex.h index c3672427..1bd83fa7 100644 --- a/engine/voice_codecs/speex/VoiceEncoder_Speex.h +++ b/engine/voice_codecs/speex/VoiceEncoder_Speex.h @@ -45,7 +45,7 @@ damage. */ #include "iframeencoder.h" -#include +#include class VoiceEncoder_Speex : public IFrameEncoder { diff --git a/engine/voice_codecs/speex/source/AUTHORS b/engine/voice_codecs/speex/source/AUTHORS deleted file mode 100644 index b3fd7f53..00000000 --- a/engine/voice_codecs/speex/source/AUTHORS +++ /dev/null @@ -1,15 +0,0 @@ -Jean-Marc Valin - All the code except the following - -David Rowe via VoiceTronix - lsp.c lsp.h - Also ideas and feedback - -John Francis Edwards: - wave_out.[ch], some #ifdefs for windows port and MSVC project files - -Atsuhiko Yamanaka : - Patch to speexenc.c to add Vorbis comment format - -Radim Kolar : - Patch to speexenc.c for supporting more input formats diff --git a/engine/voice_codecs/speex/source/COPYING b/engine/voice_codecs/speex/source/COPYING deleted file mode 100644 index 37beceff..00000000 --- a/engine/voice_codecs/speex/source/COPYING +++ /dev/null @@ -1,26 +0,0 @@ -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. - -- Neither the name of the Xiph.org Foundation nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -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 FOUNDATION 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. diff --git a/engine/voice_codecs/speex/source/ChangeLog b/engine/voice_codecs/speex/source/ChangeLog deleted file mode 100644 index 10db2987..00000000 --- a/engine/voice_codecs/speex/source/ChangeLog +++ /dev/null @@ -1,6 +0,0 @@ -2002/03/27 Jean-Marc Valin: -Working encoder and decoder for both narrowband and wideband. - -2002/02/27 Jean-Marc Valin: -Got the basic encoder working as a demo with quantization only on some -parameters. diff --git a/engine/voice_codecs/speex/source/INSTALL b/engine/voice_codecs/speex/source/INSTALL deleted file mode 100644 index 15f2e5f4..00000000 --- a/engine/voice_codecs/speex/source/INSTALL +++ /dev/null @@ -1,8 +0,0 @@ -Installing Speex is as easy as: - -% ./configure [--prefix=] -% make -% make install - -Note that if you are using the code from CVS, you will need to run "autogen.sh" -instead of "configure". diff --git a/engine/voice_codecs/speex/source/Makefile.am b/engine/voice_codecs/speex/source/Makefile.am deleted file mode 100644 index 113f18da..00000000 --- a/engine/voice_codecs/speex/source/Makefile.am +++ /dev/null @@ -1,11 +0,0 @@ -## Process this file with automake to produce Makefile.in. -*-Makefile-*- - -# Disable automatic dependency tracking if using other tools than gcc and gmake -#AUTOMAKE_OPTIONS = no-dependencies - -EXTRA_DIST = Speex.spec Speex.spec.in - -SUBDIRS = libspeex @src@ doc win32 - -rpm: dist - rpmbuild -ta ${PACKAGE}-${VERSION}.tar.gz diff --git a/engine/voice_codecs/speex/source/Makefile.in b/engine/voice_codecs/speex/source/Makefile.in deleted file mode 100644 index 83e20fa6..00000000 --- a/engine/voice_codecs/speex/source/Makefile.in +++ /dev/null @@ -1,347 +0,0 @@ -# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am - -# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -# Disable automatic dependency tracking if using other tools than gcc and gmake -#AUTOMAKE_OPTIONS = no-dependencies - - -SHELL = @SHELL@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ - -bindir = @bindir@ -sbindir = @sbindir@ -libexecdir = @libexecdir@ -datadir = @datadir@ -sysconfdir = @sysconfdir@ -sharedstatedir = @sharedstatedir@ -localstatedir = @localstatedir@ -libdir = @libdir@ -infodir = @infodir@ -mandir = @mandir@ -includedir = @includedir@ -oldincludedir = /usr/include - -DESTDIR = - -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ - -top_builddir = . - -ACLOCAL = @ACLOCAL@ -AUTOCONF = @AUTOCONF@ -AUTOMAKE = @AUTOMAKE@ -AUTOHEADER = @AUTOHEADER@ - -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -transform = @program_transform_name@ - -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -host_alias = @host_alias@ -host_triplet = @host@ -AS = @AS@ -CC = @CC@ -DLLTOOL = @DLLTOOL@ -ECHO = @ECHO@ -EXEEXT = @EXEEXT@ -LIBTOOL = @LIBTOOL@ -LN_S = @LN_S@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OGG_INCLUDES = @OGG_INCLUDES@ -OGG_LDFLAGS = @OGG_LDFLAGS@ -OGG_LIBS = @OGG_LIBS@ -PACKAGE = @PACKAGE@ -RANLIB = @RANLIB@ -SPEEX_LT_AGE = @SPEEX_LT_AGE@ -SPEEX_LT_CURRENT = @SPEEX_LT_CURRENT@ -SPEEX_LT_REVISION = @SPEEX_LT_REVISION@ -STRIP = @STRIP@ -VERSION = @VERSION@ -src = @src@ - -EXTRA_DIST = Speex.spec Speex.spec.in - -SUBDIRS = libspeex @src@ doc win32 -ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_CLEAN_FILES = Speex.spec -DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \ -Makefile.in NEWS Speex.spec.in TODO acinclude.m4 aclocal.m4 \ -config.guess config.sub configure configure.in install-sh ltmain.sh \ -missing mkinstalldirs - - -DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) - -TAR = gtar -GZIP_ENV = --best -all: all-redirect -.SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps Makefile - -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - cd $(top_builddir) \ - && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status - -$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in acinclude.m4 - cd $(srcdir) && $(ACLOCAL) - -config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) - $(SHELL) ./config.status --recheck -$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) - cd $(srcdir) && $(AUTOCONF) -Speex.spec: $(top_builddir)/config.status Speex.spec.in - cd $(top_builddir) && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status - -# This directory's subdirectories are mostly independent; you can cd -# into them and run `make' without going through this Makefile. -# To change the values of `make' variables: instead of editing Makefiles, -# (1) if the variable is set in `config.status', edit `config.status' -# (which will cause the Makefiles to be regenerated when you run `make'); -# (2) otherwise, pass the desired values on the `make' command line. - -@SET_MAKE@ - -all-recursive install-data-recursive install-exec-recursive \ -installdirs-recursive install-recursive uninstall-recursive \ -check-recursive installcheck-recursive info-recursive dvi-recursive: - @set fnord $(MAKEFLAGS); amf=$$2; \ - dot_seen=no; \ - target=`echo $@ | sed s/-recursive//`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - dot_seen=yes; \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done; \ - if test "$$dot_seen" = "no"; then \ - $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ - fi; test -z "$$fail" - -mostlyclean-recursive clean-recursive distclean-recursive \ -maintainer-clean-recursive: - @set fnord $(MAKEFLAGS); amf=$$2; \ - dot_seen=no; \ - rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ - rev="$$subdir $$rev"; \ - test "$$subdir" != "." || dot_seen=yes; \ - done; \ - test "$$dot_seen" = "no" && rev=". $$rev"; \ - target=`echo $@ | sed s/-recursive//`; \ - for subdir in $$rev; do \ - echo "Making $$target in $$subdir"; \ - if test "$$subdir" = "."; then \ - local_target="$$target-am"; \ - else \ - local_target="$$target"; \ - fi; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ - || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ - done && test -z "$$fail" -tags-recursive: - list='$(SUBDIRS)'; for subdir in $$list; do \ - test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ - done - -tags: TAGS - -ID: $(HEADERS) $(SOURCES) $(LISP) - list='$(SOURCES) $(HEADERS)'; \ - unique=`for i in $$list; do echo $$i; done | \ - awk ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - here=`pwd` && cd $(srcdir) \ - && mkid -f$$here/ID $$unique $(LISP) - -TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SUBDIRS)'; for subdir in $$list; do \ - if test "$$subdir" = .; then :; else \ - test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ - fi; \ - done; \ - list='$(SOURCES) $(HEADERS)'; \ - unique=`for i in $$list; do echo $$i; done | \ - awk ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ - || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) - -mostlyclean-tags: - -clean-tags: - -distclean-tags: - -rm -f TAGS ID - -maintainer-clean-tags: - -distdir = $(PACKAGE)-$(VERSION) -top_distdir = $(distdir) - -# This target untars the dist file and tries a VPATH configuration. Then -# it guarantees that the distribution is self-contained by making another -# tarfile. -distcheck: dist - -rm -rf $(distdir) - GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz - mkdir $(distdir)/=build - mkdir $(distdir)/=inst - dc_install_base=`cd $(distdir)/=inst && pwd`; \ - cd $(distdir)/=build \ - && ../configure --srcdir=.. --prefix=$$dc_install_base \ - && $(MAKE) $(AM_MAKEFLAGS) \ - && $(MAKE) $(AM_MAKEFLAGS) dvi \ - && $(MAKE) $(AM_MAKEFLAGS) check \ - && $(MAKE) $(AM_MAKEFLAGS) install \ - && $(MAKE) $(AM_MAKEFLAGS) installcheck \ - && $(MAKE) $(AM_MAKEFLAGS) dist - -rm -rf $(distdir) - @banner="$(distdir).tar.gz is ready for distribution"; \ - dashes=`echo "$$banner" | sed s/./=/g`; \ - echo "$$dashes"; \ - echo "$$banner"; \ - echo "$$dashes" -dist: distdir - -chmod -R a+r $(distdir) - GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) - -rm -rf $(distdir) -dist-all: distdir - -chmod -R a+r $(distdir) - GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) - -rm -rf $(distdir) -distdir: $(DISTFILES) - -rm -rf $(distdir) - mkdir $(distdir) - -chmod 777 $(distdir) - @for file in $(DISTFILES); do \ - d=$(srcdir); \ - if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(distdir)/$$file; \ - else \ - test -f $(distdir)/$$file \ - || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ - || cp -p $$d/$$file $(distdir)/$$file || :; \ - fi; \ - done - for subdir in $(SUBDIRS); do \ - if test "$$subdir" = .; then :; else \ - test -d $(distdir)/$$subdir \ - || mkdir $(distdir)/$$subdir \ - || exit 1; \ - chmod 777 $(distdir)/$$subdir; \ - (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \ - || exit 1; \ - fi; \ - done -info-am: -info: info-recursive -dvi-am: -dvi: dvi-recursive -check-am: all-am -check: check-recursive -installcheck-am: -installcheck: installcheck-recursive -install-exec-am: -install-exec: install-exec-recursive - -install-data-am: -install-data: install-data-recursive - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -install: install-recursive -uninstall-am: -uninstall: uninstall-recursive -all-am: Makefile -all-redirect: all-recursive -install-strip: - $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install -installdirs: installdirs-recursive -installdirs-am: - - -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) - -rm -f config.cache config.log stamp-h stamp-h[0-9]* - -maintainer-clean-generic: -mostlyclean-am: mostlyclean-tags mostlyclean-generic - -mostlyclean: mostlyclean-recursive - -clean-am: clean-tags clean-generic mostlyclean-am - -clean: clean-recursive - -distclean-am: distclean-tags distclean-generic clean-am - -rm -f libtool - -distclean: distclean-recursive - -rm -f config.status - -maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \ - distclean-am - @echo "This command is intended for maintainers to use;" - @echo "it deletes files that may require special tools to rebuild." - -maintainer-clean: maintainer-clean-recursive - -rm -f config.status - -.PHONY: install-data-recursive uninstall-data-recursive \ -install-exec-recursive uninstall-exec-recursive installdirs-recursive \ -uninstalldirs-recursive all-recursive check-recursive \ -installcheck-recursive info-recursive dvi-recursive \ -mostlyclean-recursive distclean-recursive clean-recursive \ -maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ -distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ -dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ -install-exec install-data-am install-data install-am install \ -uninstall-am uninstall all-redirect all-am all installdirs-am \ -installdirs mostlyclean-generic distclean-generic clean-generic \ -maintainer-clean-generic clean mostlyclean distclean maintainer-clean - - -rpm: dist - rpmbuild -ta ${PACKAGE}-${VERSION}.tar.gz - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/engine/voice_codecs/speex/source/NEWS b/engine/voice_codecs/speex/source/NEWS deleted file mode 100644 index 9a995291..00000000 --- a/engine/voice_codecs/speex/source/NEWS +++ /dev/null @@ -1 +0,0 @@ -2002/02/13: Creation of the "Speex" project diff --git a/engine/voice_codecs/speex/source/README b/engine/voice_codecs/speex/source/README deleted file mode 100644 index 84fe74ad..00000000 --- a/engine/voice_codecs/speex/source/README +++ /dev/null @@ -1,9 +0,0 @@ -See INSTALL file for instruction on how to install Speex. - -The Speex is a patent-free, Open Source/Free Software voice codec. Unlike other codecs like MP3 and Ogg Vorbis, Speex is designed to compress voice at bitrates in the 2-45 kbps range. Possible applications include VoIP, internet audio streaming, archiving of speech data (e.g. voice mail), and audio books. In some sense, it is meant to be complementary to the Ogg Vorbis codec. - -To use the Speex command line tools: - -% speexenc [options] input_file.wav compressed_file.spx - -% speexdec [options] compressed_file.spx output_file.wav diff --git a/engine/voice_codecs/speex/source/Speex.spec b/engine/voice_codecs/speex/source/Speex.spec deleted file mode 100644 index ffc94c1b..00000000 --- a/engine/voice_codecs/speex/source/Speex.spec +++ /dev/null @@ -1,68 +0,0 @@ -%define name speex -%define ver 1.0.1 -%define rel 1 - -Summary: An open-source, patent-free speech codec -Name: %name -Version: %ver -Release: %rel -Copyright: BSD -Group: Application/Devel -Source: http://www.speex.org/download/%{name}-%{ver}.tar.gz -URL: http://www.speex.org/ -Vendor: Speex -Packager: Jean-Marc Valin (jean-marc.valin@hermes.usherb.ca) -BuildRoot: /var/tmp/%{name}-build-root -Docdir: /usr/share/doc - -%description -Speex is a patent-free audio codec designed especially for voice (unlike -Vorbis which targets general audio) signals and providing good narrowband -and wideband quality. This project aims to be complementary to the Vorbis -codec. - -%package devel -Summary: Speex development files -Group: Development/Libraries -Requires: %{name} = %{version} - -%description devel -Speex development files. - -%changelog -* Thu Oct 03 2002 Jean-Marc Valin -- Added devel package inspired from PLD spec file - -* Tue Jul 30 2002 Fredrik Rambris 0.5.2 -- Added buildroot and docdir and ldconfig. Makes it builadble by non-roots - and also doesn't write to actual library paths when building. - -%prep -%setup - -%build -export CFLAGS='-O3 -DRELEASE' -./configure --prefix=/usr --enable-shared --enable-static -make - -%install -rm -rf $RPM_BUILD_ROOT -make DESTDIR=$RPM_BUILD_ROOT install - -%post -p /sbin/ldconfig -%postun -p /sbin/ldconfig - -%files -%defattr(644,root,root,755) -%doc COPYING AUTHORS ChangeLog NEWS README -%doc doc/manual.pdf -/usr/share/man/man1/speexenc.1* -/usr/share/man/man1/speexdec.1* -%attr(755,root,root) %{_bindir}/speex* -%attr(755,root,root) %{_libdir}/libspeex*.so* - -%files devel -%defattr(644,root,root,755) -%attr(755,root,root) %{_libdir}/libspeex*.la -%{_includedir}/speex*.h -%{_libdir}/libspeex*.a diff --git a/engine/voice_codecs/speex/source/Speex.spec.in b/engine/voice_codecs/speex/source/Speex.spec.in deleted file mode 100644 index 9c64d8af..00000000 --- a/engine/voice_codecs/speex/source/Speex.spec.in +++ /dev/null @@ -1,68 +0,0 @@ -%define name @PACKAGE@ -%define ver @VERSION@ -%define rel 1 - -Summary: An open-source, patent-free speech codec -Name: %name -Version: %ver -Release: %rel -Copyright: BSD -Group: Application/Devel -Source: http://www.speex.org/download/%{name}-%{ver}.tar.gz -URL: http://www.speex.org/ -Vendor: Speex -Packager: Jean-Marc Valin (jean-marc.valin@hermes.usherb.ca) -BuildRoot: /var/tmp/%{name}-build-root -Docdir: /usr/share/doc - -%description -Speex is a patent-free audio codec designed especially for voice (unlike -Vorbis which targets general audio) signals and providing good narrowband -and wideband quality. This project aims to be complementary to the Vorbis -codec. - -%package devel -Summary: Speex development files -Group: Development/Libraries -Requires: %{name} = %{version} - -%description devel -Speex development files. - -%changelog -* Thu Oct 03 2002 Jean-Marc Valin -- Added devel package inspired from PLD spec file - -* Tue Jul 30 2002 Fredrik Rambris 0.5.2 -- Added buildroot and docdir and ldconfig. Makes it builadble by non-roots - and also doesn't write to actual library paths when building. - -%prep -%setup - -%build -export CFLAGS='-O3 -DRELEASE' -./configure --prefix=/usr --enable-shared --enable-static -make - -%install -rm -rf $RPM_BUILD_ROOT -make DESTDIR=$RPM_BUILD_ROOT install - -%post -p /sbin/ldconfig -%postun -p /sbin/ldconfig - -%files -%defattr(644,root,root,755) -%doc COPYING AUTHORS ChangeLog NEWS README -%doc doc/manual.pdf -/usr/share/man/man1/speexenc.1* -/usr/share/man/man1/speexdec.1* -%attr(755,root,root) %{_bindir}/speex* -%attr(755,root,root) %{_libdir}/libspeex*.so* - -%files devel -%defattr(644,root,root,755) -%attr(755,root,root) %{_libdir}/libspeex*.la -%{_includedir}/speex*.h -%{_libdir}/libspeex*.a diff --git a/engine/voice_codecs/speex/source/TODO b/engine/voice_codecs/speex/source/TODO deleted file mode 100644 index 12a1a535..00000000 --- a/engine/voice_codecs/speex/source/TODO +++ /dev/null @@ -1,18 +0,0 @@ -Features --Add maximum/minimum bit-rate control for VBR --Get the encoder to use the rate of packet loss (more conservative pitch gains) - -Long-term quality improvements --Improve perceptual enhancement (including wideband) - -Standards -*Complete Speex RTP profile --MIME type registration --MS ACM wrapper - -*required for 1.0 - -ideas: -Peelable stream (double codebook, higher bands, stereo) -LPC from spectral domain -Better psycho-acoustics? Masking curve from Vorbis diff --git a/engine/voice_codecs/speex/source/acinclude.m4 b/engine/voice_codecs/speex/source/acinclude.m4 deleted file mode 100644 index 8efb6599..00000000 --- a/engine/voice_codecs/speex/source/acinclude.m4 +++ /dev/null @@ -1,84 +0,0 @@ -AC_DEFUN(AC_FIND_FILE, -[ -$3=NONE -for i in $2; -do - for j in $1; - do - if test -r "$i/$j"; then - $3=$i - break 2 - fi - done -done -]) - -AC_DEFUN(AC_PATH_LIBOGG, -[ -OGG_LIBS="-logg" - -AC_MSG_CHECKING([for libogg]) - -ac_ogg_includes=NONE ac_ogg_libraries=NONE ac_ogg_bindir=NONE -ogg_libraries="" -ogg_includes="" -AC_ARG_WITH(ogg-dir, - [ --with-ogg-dir=DIR where the root of OGG is installed ], - [ ac_ogg_includes="$withval"/include - ac_ogg_libraries="$withval"/lib - ]) - -AC_ARG_WITH(ogg-includes, - [ --with-ogg-includes=DIR where the OGG includes are. ], - [ - ac_ogg_includes="$withval" - ]) - -ogg_libs_given=no - -AC_ARG_WITH(ogg-libraries, - [ --with-ogg-libraries=DIR where the OGG library is installed.], - [ ac_ogg_libraries="$withval" - ogg_libs_given=yes - ]) - -ogg_incdirs="/usr/include /usr/lib/ogg/include /opt/include /usr/local/ogg/include /usr/include/ogg /usr/include /usr/local/include" -if test ! "$ac_ogg_includes" = "NONE"; then - ogg_incdirs="$ac_ogg_includes $ac_ogg_includes/.. $ogg_incdirs" -fi -AC_FIND_FILE(ogg/ogg.h, $ogg_incdirs, ogg_incdir) -echo "Ogg includes in $ogg_incdir" - - -ogg_libdirs="$ac_ogg_libraries /usr/lib/ogg/lib /usr/lib /opt/lib /usr/local/ogg/lib /usr/local/lib /usr/lib/ogg /usr/local/lib" -test -n "$OGGDIR" && ogg_libdirs="$OGGDIR/lib $OGGDIR $ogg_libdirs" -if test ! "$ac_ogg_libraries" = "NONE"; then - ogg_libdirs="$ac_ogg_libraries $ogg_libdirs" -fi - -test=NONE -ogg_libdir=NONE -for dir in $ogg_libdirs; do - try="ls -1 $dir/libogg*" - if test=`eval $try 2> /dev/null`; then ogg_libdir=$dir; break; else echo "tried $dir" >&AC_FD_CC ; fi -done - -echo "Ogg libraries in $ogg_libdir" - -if test "$ogg_libdir" = "NONE" || test "$ogg_incdir" = "NONE"; then - have_libogg=no -else - have_libogg=yes - AC_DEFINE(HAVE_LIBOGG) -fi - -OGG_INCLUDES="-I$ogg_incdir" -OGG_LDFLAGS="-L$ogg_libdir" - - -AC_SUBST(OGG_LIBS) -AC_SUBST(OGG_INCLUDES) -AC_SUBST(OGG_LDFLAGS) - -]) - diff --git a/engine/voice_codecs/speex/source/aclocal.m4 b/engine/voice_codecs/speex/source/aclocal.m4 deleted file mode 100644 index 6b1bbd32..00000000 --- a/engine/voice_codecs/speex/source/aclocal.m4 +++ /dev/null @@ -1,3894 +0,0 @@ -dnl aclocal.m4 generated automatically by aclocal 1.4-p6 - -dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. -dnl This file is free software; the Free Software Foundation -dnl gives unlimited permission to copy and/or distribute it, -dnl with or without modifications, as long as this notice is preserved. - -dnl This program is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without -dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A -dnl PARTICULAR PURPOSE. - -AC_DEFUN(AC_FIND_FILE, -[ -$3=NONE -for i in $2; -do - for j in $1; - do - if test -r "$i/$j"; then - $3=$i - break 2 - fi - done -done -]) - -AC_DEFUN(AC_PATH_LIBOGG, -[ -OGG_LIBS="-logg" - -AC_MSG_CHECKING([for libogg]) - -ac_ogg_includes=NONE ac_ogg_libraries=NONE ac_ogg_bindir=NONE -ogg_libraries="" -ogg_includes="" -AC_ARG_WITH(ogg-dir, - [ --with-ogg-dir=DIR where the root of OGG is installed ], - [ ac_ogg_includes="$withval"/include - ac_ogg_libraries="$withval"/lib - ]) - -AC_ARG_WITH(ogg-includes, - [ --with-ogg-includes=DIR where the OGG includes are. ], - [ - ac_ogg_includes="$withval" - ]) - -ogg_libs_given=no - -AC_ARG_WITH(ogg-libraries, - [ --with-ogg-libraries=DIR where the OGG library is installed.], - [ ac_ogg_libraries="$withval" - ogg_libs_given=yes - ]) - -ogg_incdirs="/usr/include /usr/lib/ogg/include /opt/include /usr/local/ogg/include /usr/include/ogg /usr/include /usr/local/include" -if test ! "$ac_ogg_includes" = "NONE"; then - ogg_incdirs="$ac_ogg_includes $ac_ogg_includes/.. $ogg_incdirs" -fi -AC_FIND_FILE(ogg/ogg.h, $ogg_incdirs, ogg_incdir) -echo "Ogg includes in $ogg_incdir" - - -ogg_libdirs="$ac_ogg_libraries /usr/lib/ogg/lib /usr/lib /opt/lib /usr/local/ogg/lib /usr/local/lib /usr/lib/ogg /usr/local/lib" -test -n "$OGGDIR" && ogg_libdirs="$OGGDIR/lib $OGGDIR $ogg_libdirs" -if test ! "$ac_ogg_libraries" = "NONE"; then - ogg_libdirs="$ac_ogg_libraries $ogg_libdirs" -fi - -test=NONE -ogg_libdir=NONE -for dir in $ogg_libdirs; do - try="ls -1 $dir/libogg*" - if test=`eval $try 2> /dev/null`; then ogg_libdir=$dir; break; else echo "tried $dir" >&AC_FD_CC ; fi -done - -echo "Ogg libraries in $ogg_libdir" - -if test "$ogg_libdir" = "NONE" || test "$ogg_incdir" = "NONE"; then - have_libogg=no -else - have_libogg=yes - AC_DEFINE(HAVE_LIBOGG) -fi - -OGG_INCLUDES="-I$ogg_incdir" -OGG_LDFLAGS="-L$ogg_libdir" - - -AC_SUBST(OGG_LIBS) -AC_SUBST(OGG_INCLUDES) -AC_SUBST(OGG_LDFLAGS) - -]) - - -# Do all the work for Automake. This macro actually does too much -- -# some checks are only needed if your package does certain things. -# But this isn't really a big deal. - -# serial 1 - -dnl Usage: -dnl AM_INIT_AUTOMAKE(package,version, [no-define]) - -AC_DEFUN([AM_INIT_AUTOMAKE], -[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl -AC_REQUIRE([AC_PROG_INSTALL]) -PACKAGE=[$1] -AC_SUBST(PACKAGE) -VERSION=[$2] -AC_SUBST(VERSION) -dnl test to see if srcdir already configured -if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then - AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) -fi -ifelse([$3],, -AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) -AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) -AC_REQUIRE([AM_SANITY_CHECK]) -AC_REQUIRE([AC_ARG_PROGRAM]) -dnl FIXME This is truly gross. -missing_dir=`cd $ac_aux_dir && pwd` -AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}, $missing_dir) -AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) -AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}, $missing_dir) -AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) -AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) -AC_REQUIRE([AC_PROG_MAKE_SET])]) - -# Copyright 2002 Free Software Foundation, Inc. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - -# AM_AUTOMAKE_VERSION(VERSION) -# ---------------------------- -# Automake X.Y traces this macro to ensure aclocal.m4 has been -# generated from the m4 files accompanying Automake X.Y. -AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.4"]) - -# AM_SET_CURRENT_AUTOMAKE_VERSION -# ------------------------------- -# Call AM_AUTOMAKE_VERSION so it can be traced. -# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. -AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], - [AM_AUTOMAKE_VERSION([1.4-p6])]) - -# -# Check to make sure that the build environment is sane. -# - -AC_DEFUN([AM_SANITY_CHECK], -[AC_MSG_CHECKING([whether build environment is sane]) -# Just in case -sleep 1 -echo timestamp > conftestfile -# Do `set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` - if test "[$]*" = "X"; then - # -L didn't work. - set X `ls -t $srcdir/configure conftestfile` - fi - if test "[$]*" != "X $srcdir/configure conftestfile" \ - && test "[$]*" != "X conftestfile $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken -alias in your environment]) - fi - - test "[$]2" = conftestfile - ) -then - # Ok. - : -else - AC_MSG_ERROR([newly created file is older than distributed files! -Check your system clock]) -fi -rm -f conftest* -AC_MSG_RESULT(yes)]) - -dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) -dnl The program must properly implement --version. -AC_DEFUN([AM_MISSING_PROG], -[AC_MSG_CHECKING(for working $2) -# Run test in a subshell; some versions of sh will print an error if -# an executable is not found, even if stderr is redirected. -# Redirect stdin to placate older versions of autoconf. Sigh. -if ($2 --version) < /dev/null > /dev/null 2>&1; then - $1=$2 - AC_MSG_RESULT(found) -else - $1="$3/missing $2" - AC_MSG_RESULT(missing) -fi -AC_SUBST($1)]) - -# Add --enable-maintainer-mode option to configure. -# From Jim Meyering - -# serial 1 - -AC_DEFUN([AM_MAINTAINER_MODE], -[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) - dnl maintainer-mode is disabled by default - AC_ARG_ENABLE(maintainer-mode, -[ --enable-maintainer-mode enable make rules and dependencies not useful - (and sometimes confusing) to the casual installer], - USE_MAINTAINER_MODE=$enableval, - USE_MAINTAINER_MODE=no) - AC_MSG_RESULT($USE_MAINTAINER_MODE) - AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes) - MAINT=$MAINTAINER_MODE_TRUE - AC_SUBST(MAINT)dnl -] -) - -# Define a conditional. - -AC_DEFUN([AM_CONDITIONAL], -[AC_SUBST($1_TRUE) -AC_SUBST($1_FALSE) -if $2; then - $1_TRUE= - $1_FALSE='#' -else - $1_TRUE='#' - $1_FALSE= -fi]) - -# libtool.m4 - Configure libtool for the host system. -*-Shell-script-*- - -# serial 46 AC_PROG_LIBTOOL - -AC_DEFUN([AC_PROG_LIBTOOL], -[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' -AC_SUBST(LIBTOOL)dnl - -# Prevent multiple expansion -define([AC_PROG_LIBTOOL], []) -]) - -AC_DEFUN([AC_LIBTOOL_SETUP], -[AC_PREREQ(2.13)dnl -AC_REQUIRE([AC_ENABLE_SHARED])dnl -AC_REQUIRE([AC_ENABLE_STATIC])dnl -AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_PROG_LD])dnl -AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl -AC_REQUIRE([AC_PROG_NM])dnl -AC_REQUIRE([LT_AC_PROG_SED])dnl - -AC_REQUIRE([AC_PROG_LN_S])dnl -AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl -AC_REQUIRE([AC_OBJEXT])dnl -AC_REQUIRE([AC_EXEEXT])dnl -dnl - -_LT_AC_PROG_ECHO_BACKSLASH -# Only perform the check for file, if the check method requires it -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - AC_PATH_MAGIC - fi - ;; -esac - -AC_CHECK_TOOL(RANLIB, ranlib, :) -AC_CHECK_TOOL(STRIP, strip, :) - -ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) -ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], -enable_win32_dll=yes, enable_win32_dll=no) - -AC_ARG_ENABLE(libtool-lock, - [ --disable-libtool-lock avoid locking (might break parallel builds)]) -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -*-*-irix6*) - # Find out which ABI we are using. - echo '[#]line __oline__ "configure"' > conftest.$ac_ext - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-linux*) - # Test if the compiler is 64bit - echo 'int i;' > conftest.$ac_ext - lt_cv_cc_64bit_output=no - if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.$ac_objext` in - *"ELF 64"*) - lt_cv_cc_64bit_output=yes - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -belf" - AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, - [AC_LANG_SAVE - AC_LANG_C - AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) - AC_LANG_RESTORE]) - if test x"$lt_cv_cc_needs_belf" != x"yes"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" - fi - ;; - -ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], -[*-*-cygwin* | *-*-mingw* | *-*-pw32*) - AC_CHECK_TOOL(DLLTOOL, dlltool, false) - AC_CHECK_TOOL(AS, as, false) - AC_CHECK_TOOL(OBJDUMP, objdump, false) - - # recent cygwin and mingw systems supply a stub DllMain which the user - # can override, but on older systems we have to supply one - AC_CACHE_CHECK([if libtool should supply DllMain function], lt_cv_need_dllmain, - [AC_TRY_LINK([], - [extern int __attribute__((__stdcall__)) DllMain(void*, int, void*); - DllMain (0, 0, 0);], - [lt_cv_need_dllmain=no],[lt_cv_need_dllmain=yes])]) - - case $host/$CC in - *-*-cygwin*/gcc*-mno-cygwin*|*-*-mingw*) - # old mingw systems require "-dll" to link a DLL, while more recent ones - # require "-mdll" - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -mdll" - AC_CACHE_CHECK([how to link DLLs], lt_cv_cc_dll_switch, - [AC_TRY_LINK([], [], [lt_cv_cc_dll_switch=-mdll],[lt_cv_cc_dll_switch=-dll])]) - CFLAGS="$SAVE_CFLAGS" ;; - *-*-cygwin* | *-*-pw32*) - # cygwin systems need to pass --dll to the linker, and not link - # crt.o which will require a WinMain@16 definition. - lt_cv_cc_dll_switch="-Wl,--dll -nostartfiles" ;; - esac - ;; - ]) -esac - -_LT_AC_LTCONFIG_HACK - -]) - -# AC_LIBTOOL_HEADER_ASSERT -# ------------------------ -AC_DEFUN([AC_LIBTOOL_HEADER_ASSERT], -[AC_CACHE_CHECK([whether $CC supports assert without backlinking], - [lt_cv_func_assert_works], - [case $host in - *-*-solaris*) - if test "$GCC" = yes && test "$with_gnu_ld" != yes; then - case `$CC --version 2>/dev/null` in - [[12]].*) lt_cv_func_assert_works=no ;; - *) lt_cv_func_assert_works=yes ;; - esac - fi - ;; - esac]) - -if test "x$lt_cv_func_assert_works" = xyes; then - AC_CHECK_HEADERS(assert.h) -fi -])# AC_LIBTOOL_HEADER_ASSERT - -# _LT_AC_CHECK_DLFCN -# -------------------- -AC_DEFUN([_LT_AC_CHECK_DLFCN], -[AC_CHECK_HEADERS(dlfcn.h) -])# _LT_AC_CHECK_DLFCN - -# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE -# --------------------------------- -AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], -[AC_REQUIRE([AC_CANONICAL_HOST]) -AC_REQUIRE([AC_PROG_NM]) -AC_REQUIRE([AC_OBJEXT]) -# Check for command to grab the raw symbol name followed by C symbol from nm. -AC_MSG_CHECKING([command to parse $NM output]) -AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [dnl - -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[[BCDEGRST]]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' - -# Transform the above into a raw symbol and a C symbol. -symxfrm='\1 \2\3 \3' - -# Transform an extracted symbol line into a proper C declaration -lt_cv_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[[BCDT]]' - ;; -cygwin* | mingw* | pw32*) - symcode='[[ABCDGISTW]]' - ;; -hpux*) # Its linker distinguishes data from code symbols - lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" - ;; -irix* | nonstopux*) - symcode='[[BCDEGRST]]' - ;; -osf*) - symcode='[[BCDEGQRST]]' - ;; -solaris* | sysv5*) - symcode='[[BDT]]' - ;; -sysv4) - symcode='[[DFNSTU]]' - ;; -esac - -# Handle CRLF in mingw tool chain -opt_cr= -case $host_os in -mingw*) - opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then - symcode='[[ABCDGISTW]]' -fi - -# Try without a prefix undercore, then with it. -for ac_symprfx in "" "_"; do - - # Write the raw and C identifiers. -lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'" - - # Check to see that the pipe works correctly. - pipe_works=no - rm -f conftest* - cat > conftest.$ac_ext < $nlist) && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if egrep ' nm_test_var$' "$nlist" >/dev/null; then - if egrep ' nm_test_func$' "$nlist" >/dev/null; then - cat < conftest.$ac_ext -#ifdef __cplusplus -extern "C" { -#endif - -EOF - # Now generate the symbol file. - eval "$lt_cv_global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext' - - cat <> conftest.$ac_ext -#if defined (__STDC__) && __STDC__ -# define lt_ptr void * -#else -# define lt_ptr char * -# define const -#endif - -/* The mapping between symbol names and symbols. */ -const struct { - const char *name; - lt_ptr address; -} -lt_preloaded_symbols[[]] = -{ -EOF - sed "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr) \&\2},/" < "$nlist" >> conftest.$ac_ext - cat <<\EOF >> conftest.$ac_ext - {0, (lt_ptr) 0} -}; - -#ifdef __cplusplus -} -#endif -EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - save_LIBS="$LIBS" - save_CFLAGS="$CFLAGS" - LIBS="conftstm.$ac_objext" - CFLAGS="$CFLAGS$no_builtin_flag" - if AC_TRY_EVAL(ac_link) && test -s conftest$ac_exeext; then - pipe_works=yes - fi - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" - else - echo "cannot find nm_test_func in $nlist" >&AC_FD_CC - fi - else - echo "cannot find nm_test_var in $nlist" >&AC_FD_CC - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AC_FD_CC - fi - else - echo "$progname: failed program was:" >&AC_FD_CC - cat conftest.$ac_ext >&5 - fi - rm -f conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done -]) -global_symbol_pipe="$lt_cv_sys_global_symbol_pipe" -if test -z "$lt_cv_sys_global_symbol_pipe"; then - global_symbol_to_cdecl= - global_symbol_to_c_name_address= -else - global_symbol_to_cdecl="$lt_cv_global_symbol_to_cdecl" - global_symbol_to_c_name_address="$lt_cv_global_symbol_to_c_name_address" -fi -if test -z "$global_symbol_pipe$global_symbol_to_cdec$global_symbol_to_c_name_address"; -then - AC_MSG_RESULT(failed) -else - AC_MSG_RESULT(ok) -fi -]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE - -# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR -# --------------------------------- -AC_DEFUN([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR], -[# Find the correct PATH separator. Usually this is `:', but -# DJGPP uses `;' like DOS. -if test "X${PATH_SEPARATOR+set}" != Xset; then - UNAME=${UNAME-`uname 2>/dev/null`} - case X$UNAME in - *-DOS) lt_cv_sys_path_separator=';' ;; - *) lt_cv_sys_path_separator=':' ;; - esac - PATH_SEPARATOR=$lt_cv_sys_path_separator -fi -])# _LT_AC_LIBTOOL_SYS_PATH_SEPARATOR - -# _LT_AC_PROG_ECHO_BACKSLASH -# -------------------------- -# Add some code to the start of the generated configure script which -# will find an echo command which doesn't interpret backslashes. -AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], -[ifdef([AC_DIVERSION_NOTICE], [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], - [AC_DIVERT_PUSH(NOTICE)]) -_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR - -# Check that we are running under the correct shell. -SHELL=${CONFIG_SHELL-/bin/sh} - -case X$ECHO in -X*--fallback-echo) - # Remove one level of quotation (which was required for Make). - ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` - ;; -esac - -echo=${ECHO-echo} -if test "X[$]1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X[$]1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then - # Yippee, $echo works! - : -else - # Restart under the correct shell. - exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} -fi - -if test "X[$]1" = X--fallback-echo; then - # used as fallback echo - shift - cat </dev/null && - echo_test_string="`eval $cmd`" && - (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null - then - break - fi - done -fi - -if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - : -else - # The Solaris, AIX, and Digital Unix default echo programs unquote - # backslashes. This makes it impossible to quote backslashes using - # echo "$something" | sed 's/\\/\\\\/g' - # - # So, first we look for a working echo in the user's PATH. - - IFS="${IFS= }"; save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for dir in $PATH /usr/ucb; do - if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && - test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - echo="$dir/echo" - break - fi - done - IFS="$save_ifs" - - if test "X$echo" = Xecho; then - # We didn't find a better echo, so look for alternatives. - if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # This shell has a builtin print -r that does the trick. - echo='print -r' - elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && - test "X$CONFIG_SHELL" != X/bin/ksh; then - # If we have ksh, try running configure again with it. - ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} - export ORIGINAL_CONFIG_SHELL - CONFIG_SHELL=/bin/ksh - export CONFIG_SHELL - exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} - else - # Try using printf. - echo='printf %s\n' - if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # Cool, printf works - : - elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL - export CONFIG_SHELL - SHELL="$CONFIG_SHELL" - export SHELL - echo="$CONFIG_SHELL [$]0 --fallback-echo" - elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - echo="$CONFIG_SHELL [$]0 --fallback-echo" - else - # maybe with a smaller string... - prev=: - - for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do - if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null - then - break - fi - prev="$cmd" - done - - if test "$prev" != 'sed 50q "[$]0"'; then - echo_test_string=`eval $prev` - export echo_test_string - exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} - else - # Oops. We lost completely, so just stick with echo. - echo=echo - fi - fi - fi - fi -fi -fi - -# Copy echo and quote the copy suitably for passing to libtool from -# the Makefile, instead of quoting the original, which is used later. -ECHO=$echo -if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then - ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" -fi - -AC_SUBST(ECHO) -AC_DIVERT_POP -])# _LT_AC_PROG_ECHO_BACKSLASH - -# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, -# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) -# ------------------------------------------------------------------ -AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], -[if test "$cross_compiling" = yes; then : - [$4] -else - AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -}] -EOF - if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) $1 ;; - x$lt_dlneed_uscore) $2 ;; - x$lt_unknown|x*) $3 ;; - esac - else : - # compilation failed - $3 - fi -fi -rm -fr conftest* -])# _LT_AC_TRY_DLOPEN_SELF - -# AC_LIBTOOL_DLOPEN_SELF -# ------------------- -AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], -[if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - cygwin* | mingw* | pw32*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - *) - AC_CHECK_FUNC([shl_load], - [lt_cv_dlopen="shl_load"], - [AC_CHECK_LIB([dld], [shl_load], - [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], - [AC_CHECK_FUNC([dlopen], - [lt_cv_dlopen="dlopen"], - [AC_CHECK_LIB([dl], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], - [AC_CHECK_LIB([svld], [dlopen], - [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], - [AC_CHECK_LIB([dld], [dld_link], - [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) - ]) - ]) - ]) - ]) - ]) - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - AC_CACHE_CHECK([whether a program can dlopen itself], - lt_cv_dlopen_self, [dnl - _LT_AC_TRY_DLOPEN_SELF( - lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, - lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) - ]) - - if test "x$lt_cv_dlopen_self" = xyes; then - LDFLAGS="$LDFLAGS $link_static_flag" - AC_CACHE_CHECK([whether a statically linked program can dlopen itself], - lt_cv_dlopen_self_static, [dnl - _LT_AC_TRY_DLOPEN_SELF( - lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, - lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) - ]) - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi -])# AC_LIBTOOL_DLOPEN_SELF - -AC_DEFUN([_LT_AC_LTCONFIG_HACK], -[AC_REQUIRE([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])dnl -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed='sed -e s/^X//' -sed_quote_subst='s/\([[\\"\\`$\\\\]]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\([[\\"\\`\\\\]]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Constants: -rm="rm -f" - -# Global variables: -default_ofile=libtool -can_build_shared=yes - -# All known linkers require a `.a' archive for static linking (except M$VC, -# which needs '.lib'). -libext=a -ltmain="$ac_aux_dir/ltmain.sh" -ofile="$default_ofile" -with_gnu_ld="$lt_cv_prog_gnu_ld" -need_locks="$enable_libtool_lock" - -old_CC="$CC" -old_CFLAGS="$CFLAGS" - -# Set sane defaults for various variables -test -z "$AR" && AR=ar -test -z "$AR_FLAGS" && AR_FLAGS=cru -test -z "$AS" && AS=as -test -z "$CC" && CC=cc -test -z "$DLLTOOL" && DLLTOOL=dlltool -test -z "$LD" && LD=ld -test -z "$LN_S" && LN_S="ln -s" -test -z "$MAGIC_CMD" && MAGIC_CMD=file -test -z "$NM" && NM=nm -test -z "$OBJDUMP" && OBJDUMP=objdump -test -z "$RANLIB" && RANLIB=: -test -z "$STRIP" && STRIP=: -test -z "$ac_objext" && ac_objext=o - -if test x"$host" != x"$build"; then - ac_tool_prefix=${host_alias}- -else - ac_tool_prefix= -fi - -# Transform linux* to *-*-linux-gnu*, to support old configure scripts. -case $host_os in -linux-gnu*) ;; -linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'` -esac - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - openbsd*) - old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" - ;; - *) - old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" -fi - -# Allow CC to be a program name with arguments. -set dummy $CC -compiler="[$]2" - -AC_MSG_CHECKING([for objdir]) -rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - objdir=_libs -fi -rmdir .libs 2>/dev/null -AC_MSG_RESULT($objdir) - - -AC_ARG_WITH(pic, -[ --with-pic try to use only PIC/non-PIC objects [default=use both]], -pic_mode="$withval", pic_mode=default) -test -z "$pic_mode" && pic_mode=default - -# We assume here that the value for lt_cv_prog_cc_pic will not be cached -# in isolation, and that seeing it set (from the cache) indicates that -# the associated values are set (in the cache) correctly too. -AC_MSG_CHECKING([for $compiler option to produce PIC]) -AC_CACHE_VAL(lt_cv_prog_cc_pic, -[ lt_cv_prog_cc_pic= - lt_cv_prog_cc_shlib= - lt_cv_prog_cc_wl= - lt_cv_prog_cc_static= - lt_cv_prog_cc_no_builtin= - lt_cv_prog_cc_can_build_shared=$can_build_shared - - if test "$GCC" = yes; then - lt_cv_prog_cc_wl='-Wl,' - lt_cv_prog_cc_static='-static' - - case $host_os in - aix*) - # Below there is a dirty hack to force normal static linking with -ldl - # The problem is because libdl dynamically linked with both libc and - # libC (AIX C++ library), which obviously doesn't included in libraries - # list by gcc. This cause undefined symbols with -static flags. - # This hack allows C programs to be linked with "-static -ldl", but - # not sure about C++ programs. - lt_cv_prog_cc_static="$lt_cv_prog_cc_static ${lt_cv_prog_cc_wl}-lC" - ;; - amigaos*) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - lt_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4' - ;; - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - lt_cv_prog_cc_pic='-fno-common' - ;; - cygwin* | mingw* | pw32* | os2*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_cv_prog_cc_pic='-DDLL_EXPORT' - ;; - sysv4*MP*) - if test -d /usr/nec; then - lt_cv_prog_cc_pic=-Kconform_pic - fi - ;; - *) - lt_cv_prog_cc_pic='-fPIC' - ;; - esac - else - # PORTME Check for PIC flags for the system compiler. - case $host_os in - aix3* | aix4* | aix5*) - lt_cv_prog_cc_wl='-Wl,' - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_cv_prog_cc_static='-Bstatic' - else - lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - hpux9* | hpux10* | hpux11*) - # Is there a better lt_cv_prog_cc_static that works with the bundled CC? - lt_cv_prog_cc_wl='-Wl,' - lt_cv_prog_cc_static="${lt_cv_prog_cc_wl}-a ${lt_cv_prog_cc_wl}archive" - lt_cv_prog_cc_pic='+Z' - ;; - - irix5* | irix6* | nonstopux*) - lt_cv_prog_cc_wl='-Wl,' - lt_cv_prog_cc_static='-non_shared' - # PIC (with -KPIC) is the default. - ;; - - cygwin* | mingw* | pw32* | os2*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_cv_prog_cc_pic='-DDLL_EXPORT' - ;; - - newsos6) - lt_cv_prog_cc_pic='-KPIC' - lt_cv_prog_cc_static='-Bstatic' - ;; - - osf3* | osf4* | osf5*) - # All OSF/1 code is PIC. - lt_cv_prog_cc_wl='-Wl,' - lt_cv_prog_cc_static='-non_shared' - ;; - - sco3.2v5*) - lt_cv_prog_cc_pic='-Kpic' - lt_cv_prog_cc_static='-dn' - lt_cv_prog_cc_shlib='-belf' - ;; - - solaris*) - lt_cv_prog_cc_pic='-KPIC' - lt_cv_prog_cc_static='-Bstatic' - lt_cv_prog_cc_wl='-Wl,' - ;; - - sunos4*) - lt_cv_prog_cc_pic='-PIC' - lt_cv_prog_cc_static='-Bstatic' - lt_cv_prog_cc_wl='-Qoption ld ' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - lt_cv_prog_cc_pic='-KPIC' - lt_cv_prog_cc_static='-Bstatic' - lt_cv_prog_cc_wl='-Wl,' - ;; - - uts4*) - lt_cv_prog_cc_pic='-pic' - lt_cv_prog_cc_static='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - lt_cv_prog_cc_pic='-Kconform_pic' - lt_cv_prog_cc_static='-Bstatic' - fi - ;; - - *) - lt_cv_prog_cc_can_build_shared=no - ;; - esac - fi -]) -if test -z "$lt_cv_prog_cc_pic"; then - AC_MSG_RESULT([none]) -else - AC_MSG_RESULT([$lt_cv_prog_cc_pic]) - - # Check to make sure the pic_flag actually works. - AC_MSG_CHECKING([if $compiler PIC flag $lt_cv_prog_cc_pic works]) - AC_CACHE_VAL(lt_cv_prog_cc_pic_works, [dnl - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC" - AC_TRY_COMPILE([], [], [dnl - case $host_os in - hpux9* | hpux10* | hpux11*) - # On HP-UX, both CC and GCC only warn that PIC is supported... then - # they create non-PIC objects. So, if there were any warnings, we - # assume that PIC is not supported. - if test -s conftest.err; then - lt_cv_prog_cc_pic_works=no - else - lt_cv_prog_cc_pic_works=yes - fi - ;; - *) - lt_cv_prog_cc_pic_works=yes - ;; - esac - ], [dnl - lt_cv_prog_cc_pic_works=no - ]) - CFLAGS="$save_CFLAGS" - ]) - - if test "X$lt_cv_prog_cc_pic_works" = Xno; then - lt_cv_prog_cc_pic= - lt_cv_prog_cc_can_build_shared=no - else - lt_cv_prog_cc_pic=" $lt_cv_prog_cc_pic" - fi - - AC_MSG_RESULT([$lt_cv_prog_cc_pic_works]) -fi - -# Check for any special shared library compilation flags. -if test -n "$lt_cv_prog_cc_shlib"; then - AC_MSG_WARN([\`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries]) - if echo "$old_CC $old_CFLAGS " | egrep -e "[[ ]]$lt_cv_prog_cc_shlib[[ ]]" >/dev/null; then : - else - AC_MSG_WARN([add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure]) - lt_cv_prog_cc_can_build_shared=no - fi -fi - -AC_MSG_CHECKING([if $compiler static flag $lt_cv_prog_cc_static works]) -AC_CACHE_VAL([lt_cv_prog_cc_static_works], [dnl - lt_cv_prog_cc_static_works=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static" - AC_TRY_LINK([], [], [lt_cv_prog_cc_static_works=yes]) - LDFLAGS="$save_LDFLAGS" -]) - -# Belt *and* braces to stop my trousers falling down: -test "X$lt_cv_prog_cc_static_works" = Xno && lt_cv_prog_cc_static= -AC_MSG_RESULT([$lt_cv_prog_cc_static_works]) - -pic_flag="$lt_cv_prog_cc_pic" -special_shlib_compile_flags="$lt_cv_prog_cc_shlib" -wl="$lt_cv_prog_cc_wl" -link_static_flag="$lt_cv_prog_cc_static" -no_builtin_flag="$lt_cv_prog_cc_no_builtin" -can_build_shared="$lt_cv_prog_cc_can_build_shared" - - -# Check to see if options -o and -c are simultaneously supported by compiler -AC_MSG_CHECKING([if $compiler supports -c -o file.$ac_objext]) -AC_CACHE_VAL([lt_cv_compiler_c_o], [ -$rm -r conftest 2>/dev/null -mkdir conftest -cd conftest -echo "int some_variable = 0;" > conftest.$ac_ext -mkdir out -# According to Tom Tromey, Ian Lance Taylor reported there are C compilers -# that will create temporary files in the current directory regardless of -# the output directory. Thus, making CWD read-only will cause this test -# to fail, enabling locking or at least warning the user not to do parallel -# builds. -chmod -w . -save_CFLAGS="$CFLAGS" -CFLAGS="$CFLAGS -o out/conftest2.$ac_objext" -compiler_c_o=no -if { (eval echo configure:__oline__: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s out/conftest.err; then - lt_cv_compiler_c_o=no - else - lt_cv_compiler_c_o=yes - fi -else - # Append any errors to the config.log. - cat out/conftest.err 1>&AC_FD_CC - lt_cv_compiler_c_o=no -fi -CFLAGS="$save_CFLAGS" -chmod u+w . -$rm conftest* out/* -rmdir out -cd .. -rmdir conftest -$rm -r conftest 2>/dev/null -]) -compiler_c_o=$lt_cv_compiler_c_o -AC_MSG_RESULT([$compiler_c_o]) - -if test x"$compiler_c_o" = x"yes"; then - # Check to see if we can write to a .lo - AC_MSG_CHECKING([if $compiler supports -c -o file.lo]) - AC_CACHE_VAL([lt_cv_compiler_o_lo], [ - lt_cv_compiler_o_lo=no - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -c -o conftest.lo" - save_objext="$ac_objext" - ac_objext=lo - AC_TRY_COMPILE([], [int some_variable = 0;], [dnl - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - lt_cv_compiler_o_lo=no - else - lt_cv_compiler_o_lo=yes - fi - ]) - ac_objext="$save_objext" - CFLAGS="$save_CFLAGS" - ]) - compiler_o_lo=$lt_cv_compiler_o_lo - AC_MSG_RESULT([$compiler_o_lo]) -else - compiler_o_lo=no -fi - -# Check to see if we can do hard links to lock some files if needed -hard_links="nottested" -if test "$compiler_c_o" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - AC_MSG_CHECKING([if we can lock with hard links]) - hard_links=yes - $rm conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - AC_MSG_RESULT([$hard_links]) - if test "$hard_links" = no; then - AC_MSG_WARN([\`$CC' does not support \`-c -o', so \`make -j' may be unsafe]) - need_locks=warn - fi -else - need_locks=no -fi - -if test "$GCC" = yes; then - # Check to see if options -fno-rtti -fno-exceptions are supported by compiler - AC_MSG_CHECKING([if $compiler supports -fno-rtti -fno-exceptions]) - echo "int some_variable = 0;" > conftest.$ac_ext - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext" - compiler_rtti_exceptions=no - AC_TRY_COMPILE([], [int some_variable = 0;], [dnl - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - compiler_rtti_exceptions=no - else - compiler_rtti_exceptions=yes - fi - ]) - CFLAGS="$save_CFLAGS" - AC_MSG_RESULT([$compiler_rtti_exceptions]) - - if test "$compiler_rtti_exceptions" = "yes"; then - no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions' - else - no_builtin_flag=' -fno-builtin' - fi -fi - -# See if the linker supports building shared libraries. -AC_MSG_CHECKING([whether the linker ($LD) supports shared libraries]) - -allow_undefined_flag= -no_undefined_flag= -need_lib_prefix=unknown -need_version=unknown -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -archive_cmds= -archive_expsym_cmds= -old_archive_from_new_cmds= -old_archive_from_expsyms_cmds= -export_dynamic_flag_spec= -whole_archive_flag_spec= -thread_safe_flag_spec= -hardcode_into_libs=no -hardcode_libdir_flag_spec= -hardcode_libdir_separator= -hardcode_direct=no -hardcode_minus_L=no -hardcode_shlibpath_var=unsupported -runpath_var= -link_all_deplibs=unknown -always_export_symbols=no -export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols' -# include_expsyms should be a list of space-separated symbols to be *always* -# included in the symbol list -include_expsyms= -# exclude_expsyms can be an egrep regular expression of symbols to exclude -# it will be wrapped by ` (' and `)$', so one must not match beginning or -# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', -# as well as any symbol that contains `d'. -exclude_expsyms="_GLOBAL_OFFSET_TABLE_" -# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out -# platforms (ab)use it in PIC code, but their linkers get confused if -# the symbol is explicitly referenced. Since portable code cannot -# rely on this symbol name, it's probably fine to never include it in -# preloaded symbol tables. -extract_expsyms_cmds= - -case $host_os in -cygwin* | mingw* | pw32*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; -openbsd*) - with_gnu_ld=no - ;; -esac - -ld_shlibs=yes -if test "$with_gnu_ld" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # See if GNU ld supports shared libraries. - case $host_os in - aix3* | aix4* | aix5*) - # On AIX, the GNU linker is very broken - # Note:Check GNU linker on AIX 5-IA64 when/if it becomes available. - ld_shlibs=no - cat <&2 - -*** Warning: the GNU linker, at least up to release 2.9.1, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to modify your PATH -*** so that a non-GNU linker is found, and then restart. - -EOF - ;; - - amigaos*) - archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - - # Samuel A. Falvo II reports - # that the semantics of dynamic libraries on AmigaOS, at least up - # to version 4, is to share data among multiple programs linked - # with the same dynamic library. Since this doesn't match the - # behavior of shared libraries on other platforms, we can use - # them. - ld_shlibs=no - ;; - - beos*) - if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - allow_undefined_flag=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - ld_shlibs=no - fi - ;; - - cygwin* | mingw* | pw32*) - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec='-L$libdir' - allow_undefined_flag=unsupported - always_export_symbols=yes - - extract_expsyms_cmds='test -f $output_objdir/impgen.c || \ - sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //;s/^# *$//; p; }" -e d < $''0 > $output_objdir/impgen.c~ - test -f $output_objdir/impgen.exe || (cd $output_objdir && \ - if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \ - else $CC -o impgen impgen.c ; fi)~ - $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def' - - old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib' - - # cygwin and mingw dlls have different entry points and sets of symbols - # to exclude. - # FIXME: what about values for MSVC? - dll_entry=__cygwin_dll_entry@12 - dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~ - case $host_os in - mingw*) - # mingw values - dll_entry=_DllMainCRTStartup@12 - dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~ - ;; - esac - - # mingw and cygwin differ, and it's simplest to just exclude the union - # of the two symbol sets. - dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12 - - # recent cygwin and mingw systems supply a stub DllMain which the user - # can override, but on older systems we have to supply one (in ltdll.c) - if test "x$lt_cv_need_dllmain" = "xyes"; then - ltdll_obj='$output_objdir/$soname-ltdll.'"$ac_objext " - ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $''0 > $output_objdir/$soname-ltdll.c~ - test -f $output_objdir/$soname-ltdll.$ac_objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~' - else - ltdll_obj= - ltdll_cmds= - fi - - # Extract the symbol export list from an `--export-all' def file, - # then regenerate the def file from the symbol export list, so that - # the compiled dll only exports the symbol export list. - # Be careful not to strip the DATA tag left be newer dlltools. - export_symbols_cmds="$ltdll_cmds"' - $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~ - sed -e "1,/EXPORTS/d" -e "s/ @ [[0-9]]*//" -e "s/ *;.*$//" < $output_objdir/$soname-def > $export_symbols' - - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is. - # If DATA tags from a recent dlltool are present, honour them! - archive_expsym_cmds='if test "x`sed 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname-def; - else - echo EXPORTS > $output_objdir/$soname-def; - _lt_hint=1; - cat $export_symbols | while read symbol; do - set dummy \$symbol; - case \[$]# in - 2) echo " \[$]2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;; - 4) echo " \[$]2 \[$]3 \[$]4 ; " >> $output_objdir/$soname-def; _lt_hint=`expr \$_lt_hint - 1`;; - *) echo " \[$]2 @ \$_lt_hint \[$]3 ; " >> $output_objdir/$soname-def;; - esac; - _lt_hint=`expr 1 + \$_lt_hint`; - done; - fi~ - '"$ltdll_cmds"' - $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ - $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~ - $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ - $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~ - $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags' - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - archive_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris* | sysv5*) - if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then - ld_shlibs=no - cat <&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -EOF - elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - - sunos4*) - archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - *) - if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - esac - - if test "$ld_shlibs" = yes; then - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' - export_dynamic_flag_spec='${wl}--export-dynamic' - case $host_os in - cygwin* | mingw* | pw32*) - # dlltool doesn't understand --whole-archive et. al. - whole_archive_flag_spec= - ;; - *) - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec= - fi - ;; - esac - fi -else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - allow_undefined_flag=unsupported - always_export_symbols=yes - archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - hardcode_minus_L=yes - if test "$GCC" = yes && test -z "$link_static_flag"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - hardcode_direct=unsupported - fi - ;; - - aix4* | aix5*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) - for ld_flag in $LDFLAGS; do - case $ld_flag in - *-brtl*) - aix_use_runtimelinking=yes - break - ;; - esac - done - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - hardcode_direct=yes - archive_cmds='' - hardcode_libdir_separator=':' - if test "$GCC" = yes; then - case $host_os in aix4.[[012]]|aix4.[[012]].*) - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && \ - strings "$collect2name" | grep resolve_lib_name >/dev/null - then - # We have reworked collect2 - hardcode_direct=yes - else - # We have old collect2 - hardcode_direct=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - hardcode_minus_L=yes - hardcode_libdir_flag_spec='-L$libdir' - hardcode_libdir_separator= - fi - esac - - shared_flag='-shared' - else - # not using gcc - if test "$host_cpu" = ia64; then - shared_flag='${wl}-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - # It seems that -bexpall can do strange things, so it is better to - # generate a list of symbols to export. - always_export_symbols=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - allow_undefined_flag='-berok' - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib' - archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' - allow_undefined_flag="-z nodefs" - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname ${wl}-h$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" - else - hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib' - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - allow_undefined_flag='${wl}-berok' - # This is a bit strange, but is similar to how AIX traditionally builds - # it's shared libraries. - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"' ~$AR -crlo $objdir/$libname$release.a $objdir/$soname' - fi - fi - ;; - - amigaos*) - archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - # see comment about different semantics on the GNU ld section - ld_shlibs=no - ;; - - cygwin* | mingw* | pw32*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec=' ' - allow_undefined_flag=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - old_archive_from_new_cmds='true' - # FIXME: Should let the user specify the lib program. - old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs' - fix_srcfile_path='`cygpath -w "$srcfile"`' - ;; - - darwin* | rhapsody*) - case "$host_os" in - rhapsody* | darwin1.[[012]]) - allow_undefined_flag='-undefined suppress' - ;; - *) # Darwin 1.3 on - allow_undefined_flag='-flat_namespace -undefined suppress' - ;; - esac - # FIXME: Relying on posixy $() will cause problems for - # cross-compilation, but unfortunately the echo tests do not - # yet detect zsh echo's removal of \ escapes. Also zsh mangles - # `"' quotes if we put them in here... so don't! - archive_cmds='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs && $CC $(test .$module = .yes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib ${lib}-master.o $deplibs$linker_flags $(test .$module != .yes && echo -install_name $rpath/$soname $verstring)' - # We need to add '_' to the symbols in $export_symbols first - #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols' - hardcode_direct=yes - hardcode_shlibpath_var=no - whole_archive_flag_spec='-all_load $convenience' - ;; - - freebsd1*) - ld_shlibs=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd*) - archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - hpux9* | hpux10* | hpux11*) - case $host_os in - hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;; - *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;; - esac - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - hardcode_minus_L=yes # Not in the search PATH, but as the default - # location of the library. - export_dynamic_flag_spec='${wl}-E' - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - else - archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec='-rpath $libdir' - fi - hardcode_libdir_separator=: - link_all_deplibs=yes - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - newsos6) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_shlibpath_var=no - ;; - - openbsd*) - hardcode_direct=yes - hardcode_shlibpath_var=no - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - export_dynamic_flag_spec='${wl}-E' - else - case "$host_os" in - openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-R$libdir' - ;; - *) - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - ;; - esac - fi - ;; - - os2*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - allow_undefined_flag=unsupported - archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - fi - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ - $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' - - #Both c and cxx compiler support -rpath directly - hardcode_libdir_flag_spec='-rpath $libdir' - fi - hardcode_libdir_separator=: - ;; - - sco3.2v5*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - export_dynamic_flag_spec='${wl}-Bexport' - ;; - - solaris*) - # gcc --version < 3.0 without binutils cannot create self contained - # shared libraries reliably, requiring libgcc.a to resolve some of - # the object symbols generated in some cases. Libraries that use - # assert need libgcc.a to resolve __eprintf, for example. Linking - # a copy of libgcc.a into every shared library to guarantee resolving - # such symbols causes other problems: According to Tim Van Holder - # , C++ libraries end up with a separate - # (to the application) exception stack for one thing. - no_undefined_flag=' -z defs' - if test "$GCC" = yes; then - case `$CC --version 2>/dev/null` in - [[12]].*) - cat <&2 - -*** Warning: Releases of GCC earlier than version 3.0 cannot reliably -*** create self contained shared libraries on Solaris systems, without -*** introducing a dependency on libgcc.a. Therefore, libtool is disabling -*** -no-undefined support, which will at least allow you to build shared -*** libraries. However, you may find that when you link such libraries -*** into an application without using GCC, you have to manually add -*** \`gcc --print-libgcc-file-name\` to the link command. We urge you to -*** upgrade to a newer version of GCC. Another option is to rebuild your -*** current GCC to use the GNU linker from GNU binutils 2.9.1 or newer. - -EOF - no_undefined_flag= - ;; - esac - fi - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_shlibpath_var=no - case $host_os in - solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; - *) # Supported since Solaris 2.6 (maybe 2.5.1?) - whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; - esac - link_all_deplibs=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - sysv4) - case $host_vendor in - sni) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' - reload_cmds='$CC -r -o $output$reload_objs' - hardcode_direct=no - ;; - motorola) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no - ;; - - sysv4.3*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - export_dynamic_flag_spec='-Bexport' - ;; - - sysv5*) - no_undefined_flag=' -z text' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - hardcode_libdir_flag_spec= - hardcode_shlibpath_var=no - runpath_var='LD_RUN_PATH' - ;; - - uts4*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - dgux*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - sysv4*MP*) - if test -d /usr/nec; then - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ld_shlibs=yes - fi - ;; - - sysv4.2uw2*) - archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_minus_L=no - hardcode_shlibpath_var=no - hardcode_runpath_var=yes - runpath_var=LD_RUN_PATH - ;; - - sysv5uw7* | unixware7*) - no_undefined_flag='${wl}-z ${wl}text' - if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no - ;; - - *) - ld_shlibs=no - ;; - esac -fi -AC_MSG_RESULT([$ld_shlibs]) -test "$ld_shlibs" = no && can_build_shared=no - -# Check hardcoding attributes. -AC_MSG_CHECKING([how to hardcode library paths into programs]) -hardcode_action= -if test -n "$hardcode_libdir_flag_spec" || \ - test -n "$runpath_var"; then - - # We can hardcode non-existant directories. - if test "$hardcode_direct" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$hardcode_shlibpath_var" != no && - test "$hardcode_minus_L" != no; then - # Linking always hardcodes the temporary library directory. - hardcode_action=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - hardcode_action=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - hardcode_action=unsupported -fi -AC_MSG_RESULT([$hardcode_action]) - -striplib= -old_striplib= -AC_MSG_CHECKING([whether stripping libraries is possible]) -if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - AC_MSG_RESULT([yes]) -else - AC_MSG_RESULT([no]) -fi - -reload_cmds='$LD$reload_flag -o $output$reload_objs' -test -z "$deplibs_check_method" && deplibs_check_method=unknown - -# PORTME Fill in your ld.so characteristics -AC_MSG_CHECKING([dynamic linker characteristics]) -library_names_spec= -libname_spec='lib$name' -soname_spec= -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib /usr/X11R6/lib" -sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib /usr/X11R6/lib" - -case $host_os in -aix3*) - version_type=linux - library_names_spec='${libname}${release}.so$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}.so$major' - ;; - -aix4* | aix5*) - version_type=linux - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[[01]] | aix4.[[01]].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can - # not hardcode correct soname into executable. Probably we can - # add versioning support to collect2, so additional links can - # be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}.so$major' - fi - shlibpath_var=LIBPATH - fi - hardcode_into_libs=yes - ;; - -amigaos*) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done' - ;; - -beos*) - library_names_spec='${libname}.so' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi4*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - export_dynamic_flag_spec=-rdynamic - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32*) - version_type=windows - need_version=no - need_lib_prefix=no - case $GCC,$host_os in - yes,cygwin*) - library_names_spec='$libname.dll.a' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll' - postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i;echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog .libs/$dlname \$dldir/$dlname' - postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $rm \$dlpath' - ;; - yes,mingw*) - library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll' - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g" -e "s,=/,/,g"` - ;; - yes,pw32*) - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll' - ;; - *) - library_names_spec='${libname}`echo ${release} | sed -e 's/[[.]]/-/g'`${versuffix}.dll $libname.lib' - ;; - esac - dynamic_linker='Win32 ld.exe' - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - # FIXME: Relying on posixy $() will cause problems for - # cross-compilation, but unfortunately the echo tests do not - # yet detect zsh echo's removal of \ escapes. - library_names_spec='${libname}${release}${versuffix}.$(test .$module = .yes && echo so || echo dylib) ${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib) ${libname}.$(test .$module = .yes && echo so || echo dylib)' - soname_spec='${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib)' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - ;; - -freebsd1*) - dynamic_linker=no - ;; - -freebsd*) - objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2*) - shlibpath_overrides_runpath=yes - ;; - *) - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - dynamic_linker="$host_os dld.sl" - version_type=sunos - need_lib_prefix=no - need_version=no - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl' - soname_spec='${libname}${release}.sl$major' - # HP-UX runs *really* slowly unless shared libraries are mode 555. - postinstall_cmds='chmod 555 $lib' - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) version_type=irix ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}.so$major' - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux-gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - case $host_cpu:$lt_cv_cc_64bit_output in - powerpc64:yes | s390x:yes | sparc64:yes | x86_64:yes) - sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /usr/X11R6/lib64" - sys_lib_search_path_spec="/lib64 /usr/lib64 /usr/local/lib64 /usr/X11R6/lib64" - ;; - esac - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so' - soname_spec='${libname}${release}.so$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -openbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case "$host_os" in - openbsd2.[[89]] | openbsd2.[[89]].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - ;; - -os2*) - libname_spec='$name' - need_lib_prefix=no - library_names_spec='$libname.dll $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_version=no - soname_spec='${libname}${release}.so$major' - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - hardcode_into_libs=yes - ;; - -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}.so$major' - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - shlibpath_var=LD_LIBRARY_PATH - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - version_type=linux - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - export_dynamic_flag_spec='${wl}-Blargedynsym' - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so' - soname_spec='$libname.so.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -*) - dynamic_linker=no - ;; -esac -AC_MSG_RESULT([$dynamic_linker]) -test "$dynamic_linker" = no && can_build_shared=no - -# Report the final consequences. -AC_MSG_CHECKING([if libtool supports shared libraries]) -AC_MSG_RESULT([$can_build_shared]) - -AC_MSG_CHECKING([whether to build shared libraries]) -test "$can_build_shared" = "no" && enable_shared=no - -# On AIX, shared libraries and static libraries use the same namespace, and -# are all built from PIC. -case "$host_os" in -aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - -aix4*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; -esac -AC_MSG_RESULT([$enable_shared]) - -AC_MSG_CHECKING([whether to build static libraries]) -# Make sure either enable_shared or enable_static is yes. -test "$enable_shared" = yes || enable_static=yes -AC_MSG_RESULT([$enable_static]) - -if test "$hardcode_action" = relink; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -AC_LIBTOOL_DLOPEN_SELF - -if test "$enable_shared" = yes && test "$GCC" = yes; then - case $archive_cmds in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - AC_MSG_CHECKING([whether -lc should be explicitly linked in]) - AC_CACHE_VAL([lt_cv_archive_cmds_need_lc], - [$rm conftest* - echo 'static int dummy;' > conftest.$ac_ext - - if AC_TRY_EVAL(ac_compile); then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$lt_cv_prog_cc_wl - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - save_allow_undefined_flag=$allow_undefined_flag - allow_undefined_flag= - if AC_TRY_EVAL(archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) - then - lt_cv_archive_cmds_need_lc=no - else - lt_cv_archive_cmds_need_lc=yes - fi - allow_undefined_flag=$save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi]) - AC_MSG_RESULT([$lt_cv_archive_cmds_need_lc]) - ;; - esac -fi -need_lc=${lt_cv_archive_cmds_need_lc-yes} - -# The second clause should only fire when bootstrapping the -# libtool distribution, otherwise you forgot to ship ltmain.sh -# with your package, and you will get complaints that there are -# no rules to generate ltmain.sh. -if test -f "$ltmain"; then - : -else - # If there is no Makefile yet, we rely on a make rule to execute - # `config.status --recheck' to rerun these tests and create the - # libtool script then. - test -f Makefile && make "$ltmain" -fi - -if test -f "$ltmain"; then - trap "$rm \"${ofile}T\"; exit 1" 1 2 15 - $rm -f "${ofile}T" - - echo creating $ofile - - # Now quote all the things that may contain metacharacters while being - # careful not to overquote the AC_SUBSTed values. We take copies of the - # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS SED \ - AR AR_FLAGS CC LD LN_S NM SHELL \ - reload_flag reload_cmds wl \ - pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \ - thread_safe_flag_spec whole_archive_flag_spec libname_spec \ - library_names_spec soname_spec \ - RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \ - old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds \ - postuninstall_cmds extract_expsyms_cmds old_archive_from_expsyms_cmds \ - old_striplib striplib file_magic_cmd export_symbols_cmds \ - deplibs_check_method allow_undefined_flag no_undefined_flag \ - finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \ - global_symbol_to_c_name_address \ - hardcode_libdir_flag_spec hardcode_libdir_separator \ - sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ - compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do - - case $var in - reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \ - old_postinstall_cmds | old_postuninstall_cmds | \ - export_symbols_cmds | archive_cmds | archive_expsym_cmds | \ - extract_expsyms_cmds | old_archive_from_expsyms_cmds | \ - postinstall_cmds | postuninstall_cmds | \ - finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) - # Double-quote double-evaled strings. - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" - ;; - *) - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" - ;; - esac - done - - cat <<__EOF__ > "${ofile}T" -#! $SHELL - -# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -# Copyright (C) 1996-2000 Free Software Foundation, Inc. -# Originally by Gordon Matzigkeit , 1996 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# A sed that does not truncate output. -SED=$lt_SED - -# Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="${SED} -e s/^X//" - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi - -# ### BEGIN LIBTOOL CONFIG - -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$need_lc - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# The host system. -host_alias=$host_alias -host=$host - -# An echo program that does not interpret backslashes. -echo=$lt_echo - -# The archiver. -AR=$lt_AR -AR_FLAGS=$lt_AR_FLAGS - -# The default C compiler. -CC=$lt_CC - -# Is the compiler the GNU C compiler? -with_gcc=$GCC - -# The linker used to build libraries. -LD=$lt_LD - -# Whether we need hard or soft links. -LN_S=$lt_LN_S - -# A BSD-compatible nm program. -NM=$lt_NM - -# A symbol stripping program -STRIP=$STRIP - -# Used to examine libraries when file_magic_cmd begins "file" -MAGIC_CMD=$MAGIC_CMD - -# Used on cygwin: DLL creation program. -DLLTOOL="$DLLTOOL" - -# Used on cygwin: object dumper. -OBJDUMP="$OBJDUMP" - -# Used on cygwin: assembler. -AS="$AS" - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# How to pass a linker flag through the compiler. -wl=$lt_wl - -# Object file suffix (normally "o"). -objext="$ac_objext" - -# Old archive suffix (normally "a"). -libext="$libext" - -# Executable file suffix (normally ""). -exeext="$exeext" - -# Additional compiler flags for building library objects. -pic_flag=$lt_pic_flag -pic_mode=$pic_mode - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_compiler_c_o - -# Can we write directly to a .lo ? -compiler_o_lo=$lt_compiler_o_lo - -# Must we lock files when doing compilation ? -need_locks=$lt_need_locks - -# Do we need the lib prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_link_static_flag - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_no_builtin_flag - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec - -# Compiler flag to generate thread-safe objects. -thread_safe_flag_spec=$lt_thread_safe_flag_spec - -# Library versioning type. -version_type=$version_type - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME. -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Commands used to build and install an old-style archive. -RANLIB=$lt_RANLIB -old_archive_cmds=$lt_old_archive_cmds -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds - -# Commands used to build and install a shared archive. -archive_cmds=$lt_archive_cmds -archive_expsym_cmds=$lt_archive_expsym_cmds -postinstall_cmds=$lt_postinstall_cmds -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method == file_magic. -file_magic_cmd=$lt_file_magic_cmd - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag - -# Flag that forces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# Same as above, but a single script fragment to be evaled but not shown. -finish_eval=$lt_finish_eval - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_global_symbol_pipe - -# Transform the output of nm in a proper C declaration -global_symbol_to_cdecl=$lt_global_symbol_to_cdecl - -# Transform the output of nm in a C name address pair -global_symbol_to_c_name_address=$lt_global_symbol_to_c_name_address - -# This is the shared library runtime path variable. -runpath_var=$runpath_var - -# This is the shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator - -# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the -# resulting binary. -hardcode_direct=$hardcode_direct - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L=$hardcode_minus_L - -# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into -# the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at relink time. -variables_saved_for_relink="$variables_saved_for_relink" - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs - -# Compile-time system search path for libraries -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Run-time system search path for libraries -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec - -# Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$fix_srcfile_path" - -# Set to yes if exported symbols are required. -always_export_symbols=$always_export_symbols - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms - -# ### END LIBTOOL CONFIG - -__EOF__ - - case $host_os in - aix3*) - cat <<\EOF >> "${ofile}T" - -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -EOF - ;; - esac - - case $host_os in - cygwin* | mingw* | pw32* | os2*) - cat <<'EOF' >> "${ofile}T" - # This is a source program that is used to create dlls on Windows - # Don't remove nor modify the starting and closing comments -# /* ltdll.c starts here */ -# #define WIN32_LEAN_AND_MEAN -# #include -# #undef WIN32_LEAN_AND_MEAN -# #include -# -# #ifndef __CYGWIN__ -# # ifdef __CYGWIN32__ -# # define __CYGWIN__ __CYGWIN32__ -# # endif -# #endif -# -# #ifdef __cplusplus -# extern "C" { -# #endif -# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); -# #ifdef __cplusplus -# } -# #endif -# -# #ifdef __CYGWIN__ -# #include -# DECLARE_CYGWIN_DLL( DllMain ); -# #endif -# HINSTANCE __hDllInstance_base; -# -# BOOL APIENTRY -# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) -# { -# __hDllInstance_base = hInst; -# return TRUE; -# } -# /* ltdll.c ends here */ - # This is a source program that is used to create import libraries - # on Windows for dlls which lack them. Don't remove nor modify the - # starting and closing comments -# /* impgen.c starts here */ -# /* Copyright (C) 1999-2000 Free Software Foundation, Inc. -# -# This file is part of GNU libtool. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# */ -# -# #include /* for printf() */ -# #include /* for open(), lseek(), read() */ -# #include /* for O_RDONLY, O_BINARY */ -# #include /* for strdup() */ -# -# /* O_BINARY isn't required (or even defined sometimes) under Unix */ -# #ifndef O_BINARY -# #define O_BINARY 0 -# #endif -# -# static unsigned int -# pe_get16 (fd, offset) -# int fd; -# int offset; -# { -# unsigned char b[2]; -# lseek (fd, offset, SEEK_SET); -# read (fd, b, 2); -# return b[0] + (b[1]<<8); -# } -# -# static unsigned int -# pe_get32 (fd, offset) -# int fd; -# int offset; -# { -# unsigned char b[4]; -# lseek (fd, offset, SEEK_SET); -# read (fd, b, 4); -# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); -# } -# -# static unsigned int -# pe_as32 (ptr) -# void *ptr; -# { -# unsigned char *b = ptr; -# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); -# } -# -# int -# main (argc, argv) -# int argc; -# char *argv[]; -# { -# int dll; -# unsigned long pe_header_offset, opthdr_ofs, num_entries, i; -# unsigned long export_rva, export_size, nsections, secptr, expptr; -# unsigned long name_rvas, nexp; -# unsigned char *expdata, *erva; -# char *filename, *dll_name; -# -# filename = argv[1]; -# -# dll = open(filename, O_RDONLY|O_BINARY); -# if (dll < 1) -# return 1; -# -# dll_name = filename; -# -# for (i=0; filename[i]; i++) -# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':') -# dll_name = filename + i +1; -# -# pe_header_offset = pe_get32 (dll, 0x3c); -# opthdr_ofs = pe_header_offset + 4 + 20; -# num_entries = pe_get32 (dll, opthdr_ofs + 92); -# -# if (num_entries < 1) /* no exports */ -# return 1; -# -# export_rva = pe_get32 (dll, opthdr_ofs + 96); -# export_size = pe_get32 (dll, opthdr_ofs + 100); -# nsections = pe_get16 (dll, pe_header_offset + 4 +2); -# secptr = (pe_header_offset + 4 + 20 + -# pe_get16 (dll, pe_header_offset + 4 + 16)); -# -# expptr = 0; -# for (i = 0; i < nsections; i++) -# { -# char sname[8]; -# unsigned long secptr1 = secptr + 40 * i; -# unsigned long vaddr = pe_get32 (dll, secptr1 + 12); -# unsigned long vsize = pe_get32 (dll, secptr1 + 16); -# unsigned long fptr = pe_get32 (dll, secptr1 + 20); -# lseek(dll, secptr1, SEEK_SET); -# read(dll, sname, 8); -# if (vaddr <= export_rva && vaddr+vsize > export_rva) -# { -# expptr = fptr + (export_rva - vaddr); -# if (export_rva + export_size > vaddr + vsize) -# export_size = vsize - (export_rva - vaddr); -# break; -# } -# } -# -# expdata = (unsigned char*)malloc(export_size); -# lseek (dll, expptr, SEEK_SET); -# read (dll, expdata, export_size); -# erva = expdata - export_rva; -# -# nexp = pe_as32 (expdata+24); -# name_rvas = pe_as32 (expdata+32); -# -# printf ("EXPORTS\n"); -# for (i = 0; i> "${ofile}T" || (rm -f "${ofile}T"; exit 1) - - mv -f "${ofile}T" "$ofile" || \ - (rm -f "$ofile" && cp "${ofile}T" "$ofile" && rm -f "${ofile}T") - chmod +x "$ofile" -fi - -])# _LT_AC_LTCONFIG_HACK - -# AC_LIBTOOL_DLOPEN - enable checks for dlopen support -AC_DEFUN([AC_LIBTOOL_DLOPEN], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])]) - -# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's -AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])]) - -# AC_ENABLE_SHARED - implement the --enable-shared flag -# Usage: AC_ENABLE_SHARED[(DEFAULT)] -# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to -# `yes'. -AC_DEFUN([AC_ENABLE_SHARED], -[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl -AC_ARG_ENABLE(shared, -changequote(<<, >>)dnl -<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT], -changequote([, ])dnl -[p=${PACKAGE-default} -case $enableval in -yes) enable_shared=yes ;; -no) enable_shared=no ;; -*) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," - for pkg in $enableval; do - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS="$ac_save_ifs" - ;; -esac], -enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl -]) - -# AC_DISABLE_SHARED - set the default shared flag to --disable-shared -AC_DEFUN([AC_DISABLE_SHARED], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl -AC_ENABLE_SHARED(no)]) - -# AC_ENABLE_STATIC - implement the --enable-static flag -# Usage: AC_ENABLE_STATIC[(DEFAULT)] -# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to -# `yes'. -AC_DEFUN([AC_ENABLE_STATIC], -[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl -AC_ARG_ENABLE(static, -changequote(<<, >>)dnl -<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT], -changequote([, ])dnl -[p=${PACKAGE-default} -case $enableval in -yes) enable_static=yes ;; -no) enable_static=no ;; -*) - enable_static=no - # Look at the argument we got. We use all the common list separators. - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," - for pkg in $enableval; do - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS="$ac_save_ifs" - ;; -esac], -enable_static=AC_ENABLE_STATIC_DEFAULT)dnl -]) - -# AC_DISABLE_STATIC - set the default static flag to --disable-static -AC_DEFUN([AC_DISABLE_STATIC], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl -AC_ENABLE_STATIC(no)]) - - -# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag -# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)] -# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to -# `yes'. -AC_DEFUN([AC_ENABLE_FAST_INSTALL], -[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl -AC_ARG_ENABLE(fast-install, -changequote(<<, >>)dnl -<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT], -changequote([, ])dnl -[p=${PACKAGE-default} -case $enableval in -yes) enable_fast_install=yes ;; -no) enable_fast_install=no ;; -*) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," - for pkg in $enableval; do - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS="$ac_save_ifs" - ;; -esac], -enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl -]) - -# AC_DISABLE_FAST_INSTALL - set the default to --disable-fast-install -AC_DEFUN([AC_DISABLE_FAST_INSTALL], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl -AC_ENABLE_FAST_INSTALL(no)]) - -# AC_LIBTOOL_PICMODE - implement the --with-pic flag -# Usage: AC_LIBTOOL_PICMODE[(MODE)] -# Where MODE is either `yes' or `no'. If omitted, it defaults to -# `both'. -AC_DEFUN([AC_LIBTOOL_PICMODE], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl -pic_mode=ifelse($#,1,$1,default)]) - - -# AC_PATH_TOOL_PREFIX - find a file program which can recognise shared library -AC_DEFUN([AC_PATH_TOOL_PREFIX], -[AC_MSG_CHECKING([for $1]) -AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, -[case $MAGIC_CMD in - /*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; - ?:/*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. - ;; - *) - ac_save_MAGIC_CMD="$MAGIC_CMD" - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" -dnl $ac_dummy forces splitting on constant user-supplied paths. -dnl POSIX.2 word splitting is done only on the output of word expansions, -dnl not every word. This closes a longstanding sh security hole. - ac_dummy="ifelse([$2], , $PATH, [$2])" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$1; then - lt_cv_path_MAGIC_CMD="$ac_dir/$1" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - egrep "$file_magic_regex" > /dev/null; then - : - else - cat <&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -EOF - fi ;; - esac - fi - break - fi - done - IFS="$ac_save_ifs" - MAGIC_CMD="$ac_save_MAGIC_CMD" - ;; -esac]) -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - AC_MSG_RESULT($MAGIC_CMD) -else - AC_MSG_RESULT(no) -fi -]) - - -# AC_PATH_MAGIC - find a file program which can recognise a shared library -AC_DEFUN([AC_PATH_MAGIC], -[AC_REQUIRE([AC_CHECK_TOOL_PREFIX])dnl -AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin:$PATH) -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - AC_PATH_TOOL_PREFIX(file, /usr/bin:$PATH) - else - MAGIC_CMD=: - fi -fi -]) - - -# AC_PROG_LD - find the path to the GNU or non-GNU linker -AC_DEFUN([AC_PROG_LD], -[AC_ARG_WITH(gnu-ld, -[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], -test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) -AC_REQUIRE([AC_PROG_CC])dnl -AC_REQUIRE([AC_CANONICAL_HOST])dnl -AC_REQUIRE([AC_CANONICAL_BUILD])dnl -AC_REQUIRE([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR])dnl -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - AC_MSG_CHECKING([for ld used by GCC]) - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [[\\/]]* | [[A-Za-z]]:[[\\/]]*) - re_direlt='/[[^/]][[^/]]*/\.\./' - # Canonicalize the path of ld - ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` - while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - AC_MSG_CHECKING([for GNU ld]) -else - AC_MSG_CHECKING([for non-GNU ld]) -fi -AC_CACHE_VAL(lt_cv_path_LD, -[if test -z "$LD"; then - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then - test "$with_gnu_ld" != no && break - else - test "$with_gnu_ld" != yes && break - fi - fi - done - IFS="$ac_save_ifs" -else - lt_cv_path_LD="$LD" # Let the user override the test with a path. -fi]) -LD="$lt_cv_path_LD" -if test -n "$LD"; then - AC_MSG_RESULT($LD) -else - AC_MSG_RESULT(no) -fi -test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) -AC_PROG_LD_GNU -]) - -# AC_PROG_LD_GNU - -AC_DEFUN([AC_PROG_LD_GNU], -[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, -[# I'd rather use --version here, but apparently some GNU ld's only accept -v. -if $LD -v 2>&1 &5; then - lt_cv_prog_gnu_ld=yes -else - lt_cv_prog_gnu_ld=no -fi]) -with_gnu_ld=$lt_cv_prog_gnu_ld -]) - -# AC_PROG_LD_RELOAD_FLAG - find reload flag for linker -# -- PORTME Some linkers may need a different reload flag. -AC_DEFUN([AC_PROG_LD_RELOAD_FLAG], -[AC_CACHE_CHECK([for $LD option to reload object files], lt_cv_ld_reload_flag, -[lt_cv_ld_reload_flag='-r']) -reload_flag=$lt_cv_ld_reload_flag -test -n "$reload_flag" && reload_flag=" $reload_flag" -]) - -# AC_DEPLIBS_CHECK_METHOD - how to check for library dependencies -# -- PORTME fill in with the dynamic library characteristics -AC_DEFUN([AC_DEPLIBS_CHECK_METHOD], -[AC_CACHE_CHECK([how to recognise dependent libraries], -lt_cv_deplibs_check_method, -[lt_cv_file_magic_cmd='$MAGIC_CMD' -lt_cv_file_magic_test_file= -lt_cv_deplibs_check_method='unknown' -# Need to set the preceding variable on all platforms that support -# interlibrary dependencies. -# 'none' -- dependencies not supported. -# `unknown' -- same as none, but documents that we really don't know. -# 'pass_all' -- all dependencies passed with no checks. -# 'test_compile' -- check by making test program. -# 'file_magic [[regex]]' -- check by looking for files in library path -# which responds to the $file_magic_cmd with a given egrep regex. -# If you have `file' or equivalent on your system and you're not sure -# whether `pass_all' will *always* work, you probably want this one. - -case $host_os in -aix4* | aix5*) - lt_cv_deplibs_check_method=pass_all - ;; - -beos*) - lt_cv_deplibs_check_method=pass_all - ;; - -bsdi4*) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' - lt_cv_file_magic_test_file=/shlib/libc.so - ;; - -cygwin* | mingw* | pw32*) - lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library' - lt_cv_file_magic_cmd='/usr/bin/file -L' - case "$host_os" in - rhapsody* | darwin1.[[012]]) - lt_cv_file_magic_test_file=`echo /System/Library/Frameworks/System.framework/Versions/*/System | head -1` - ;; - *) # Darwin 1.3 on - lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib' - ;; - esac - ;; - -freebsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[[3-9]]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20*|hpux11*) - lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - irix5* | nonstopux*) - # this will be overridden with pass_all, but let us keep it just in case - lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" - ;; - *) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - # this will be overridden with pass_all, but let us keep it just in case - lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[[1234]] dynamic lib MIPS - version 1" - ;; - esac - lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be Linux ELF. -linux-gnu*) - case $host_cpu in - alpha* | hppa* | i*86 | mips | mipsel | powerpc* | sparc* | ia64* | x86_64*) - lt_cv_deplibs_check_method=pass_all ;; - *) - # glibc up to 2.1.1 does not perform some relocations on ARM - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; - esac - lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` - ;; - -netbsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[[^/\.]]+\.so\.[[0-9]]+\.[[0-9]]+$' - else - lt_cv_deplibs_check_method='match_pattern /lib[[^/\.]]+\.so$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -openbsd*) - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB shared object' - else - lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library' - fi - ;; - -osf3* | osf4* | osf5*) - # this will be overridden with pass_all, but let us keep it just in case - lt_cv_deplibs_check_method='file_magic COFF format alpha shared library' - lt_cv_file_magic_test_file=/shlib/libc.so - lt_cv_deplibs_check_method=pass_all - ;; - -sco3.2v5*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - lt_cv_file_magic_test_file=/lib/libc.so - ;; - -sysv5uw[[78]]* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; -esac -]) -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -]) - - -# AC_PROG_NM - find the path to a BSD-compatible name lister -AC_DEFUN([AC_PROG_NM], -[AC_REQUIRE([_LT_AC_LIBTOOL_SYS_PATH_SEPARATOR])dnl -AC_MSG_CHECKING([for BSD-compatible nm]) -AC_CACHE_VAL(lt_cv_path_NM, -[if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM="$NM" -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do - test -z "$ac_dir" && ac_dir=. - tmp_nm=$ac_dir/${ac_tool_prefix}nm - if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then - lt_cv_path_NM="$tmp_nm -B" - break - elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then - lt_cv_path_NM="$tmp_nm -p" - break - else - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - fi - fi - done - IFS="$ac_save_ifs" - test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm -fi]) -NM="$lt_cv_path_NM" -AC_MSG_RESULT([$NM]) -]) - -# AC_CHECK_LIBM - check for math library -AC_DEFUN([AC_CHECK_LIBM], -[AC_REQUIRE([AC_CANONICAL_HOST])dnl -LIBM= -case $host in -*-*-beos* | *-*-cygwin* | *-*-pw32*) - # These system don't have libm - ;; -*-ncr-sysv4.3*) - AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") - AC_CHECK_LIB(m, main, LIBM="$LIBM -lm") - ;; -*) - AC_CHECK_LIB(m, main, LIBM="-lm") - ;; -esac -]) - -# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for -# the libltdl convenience library and LTDLINCL to the include flags for -# the libltdl header and adds --enable-ltdl-convenience to the -# configure arguments. Note that LIBLTDL and LTDLINCL are not -# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not -# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed -# with '${top_builddir}/' and LTDLINCL will be prefixed with -# '${top_srcdir}/' (note the single quotes!). If your package is not -# flat and you're not using automake, define top_builddir and -# top_srcdir appropriately in the Makefiles. -AC_DEFUN([AC_LIBLTDL_CONVENIENCE], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl - case $enable_ltdl_convenience in - no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; - "") enable_ltdl_convenience=yes - ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; - esac - LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la - LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) - # For backwards non-gettext consistent compatibility... - INCLTDL="$LTDLINCL" -]) - -# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for -# the libltdl installable library and LTDLINCL to the include flags for -# the libltdl header and adds --enable-ltdl-install to the configure -# arguments. Note that LIBLTDL and LTDLINCL are not AC_SUBSTed, nor is -# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed -# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will -# be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed -# with '${top_srcdir}/' (note the single quotes!). If your package is -# not flat and you're not using automake, define top_builddir and -# top_srcdir appropriately in the Makefiles. -# In the future, this macro may have to be called after AC_PROG_LIBTOOL. -AC_DEFUN([AC_LIBLTDL_INSTALLABLE], -[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl - AC_CHECK_LIB(ltdl, main, - [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], - [if test x"$enable_ltdl_install" = xno; then - AC_MSG_WARN([libltdl not installed, but installation disabled]) - else - enable_ltdl_install=yes - fi - ]) - if test x"$enable_ltdl_install" = x"yes"; then - ac_configure_args="$ac_configure_args --enable-ltdl-install" - LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la - LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) - else - ac_configure_args="$ac_configure_args --enable-ltdl-install=no" - LIBLTDL="-lltdl" - LTDLINCL= - fi - # For backwards non-gettext consistent compatibility... - INCLTDL="$LTDLINCL" -]) - -# old names -AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) -AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) -AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) -AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) -AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) -AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) -AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) - -# This is just to silence aclocal about the macro not being used -ifelse([AC_DISABLE_FAST_INSTALL]) - -# NOTE: This macro has been submitted for inclusion into # -# GNU Autoconf as AC_PROG_SED. When it is available in # -# a released version of Autoconf we should remove this # -# macro and use it instead. # -# LT_AC_PROG_SED -# -------------- -# Check for a fully-functional sed program, that truncates -# as few characters as possible. Prefer GNU sed if found. -AC_DEFUN([LT_AC_PROG_SED], -[AC_MSG_CHECKING([for a sed that does not truncate output]) -AC_CACHE_VAL(lt_cv_path_SED, -[# Loop through the user's path and test for sed and gsed. -# Then use that list of sed's as ones to test for truncation. -as_executable_p="test -f" -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then - _sed_list="$_sed_list $as_dir/$ac_prog$ac_exec_ext" - fi - done - done -done - - # Create a temporary directory, and hook for its removal unless debugging. -$debug || -{ - trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 - trap '{ (exit 1); exit 1; }' 1 2 13 15 -} - -# Create a (secure) tmp directory for tmp files. -: ${TMPDIR=/tmp} -{ - tmp=`(umask 077 && mktemp -d -q "$TMPDIR/sedXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" -} || -{ - tmp=$TMPDIR/sed$$-$RANDOM - (umask 077 && mkdir $tmp) -} || -{ - echo "$me: cannot create a temporary directory in $TMPDIR" >&2 - { (exit 1); exit 1; } -} - _max=0 - _count=0 - # Add /usr/xpg4/bin/sed as it is typically found on Solaris - # along with /bin/sed that truncates output. - for _sed in $_sed_list /usr/xpg4/bin/sed; do - test ! -f ${_sed} && break - cat /dev/null > "$tmp/sed.in" - _count=0 - echo ${ECHO_N-$ac_n} "0123456789${ECHO_C-$ac_c}" >"$tmp/sed.in" - # Check for GNU sed and select it if it is found. - if "${_sed}" --version 2>&1 < /dev/null | egrep '(GNU)' > /dev/null; then - lt_cv_path_SED=${_sed} - break - fi - while true; do - cat "$tmp/sed.in" "$tmp/sed.in" >"$tmp/sed.tmp" - mv "$tmp/sed.tmp" "$tmp/sed.in" - cp "$tmp/sed.in" "$tmp/sed.nl" - echo >>"$tmp/sed.nl" - ${_sed} -e 's/a$//' < "$tmp/sed.nl" >"$tmp/sed.out" || break - cmp -s "$tmp/sed.out" "$tmp/sed.nl" || break - # 40000 chars as input seems more than enough - test $_count -gt 10 && break - _count=`expr $_count + 1` - if test $_count -gt $_max; then - _max=$_count - lt_cv_path_SED=$_sed - fi - done - done - rm -rf "$tmp" -]) -if test "X$SED" != "X"; then - lt_cv_path_SED=$SED -else - SED=$lt_cv_path_SED -fi -AC_MSG_RESULT([$SED]) -]) - diff --git a/engine/voice_codecs/speex/source/config.guess b/engine/voice_codecs/speex/source/config.guess deleted file mode 100644 index 5145e357..00000000 --- a/engine/voice_codecs/speex/source/config.guess +++ /dev/null @@ -1,1363 +0,0 @@ -#! /bin/sh -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002 Free Software Foundation, Inc. - -timestamp='2002-10-21' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Originally written by Per Bothner . -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit 0 ;; - --version | -v ) - echo "$version" ; exit 0 ;; - --help | --h* | -h ) - echo "$usage"; exit 0 ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -trap 'exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. Note that the use of a -# compiler to aid in system detection is discouraged as it requires -# temporary files to be created and, as you can see below, it is a -# headache to deal with in a portable fashion. - -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -# This shell variable is my proudest work .. or something. --bje - -set_cc_for_build='tmpdir=${TMPDIR-/tmp}/config-guess-$$ ; -(old=`umask` && umask 077 && mkdir $tmpdir && umask $old && unset old) - || (echo "$me: cannot create $tmpdir" >&2 && exit 1) ; -dummy=$tmpdir/dummy ; -files="$dummy.c $dummy.o $dummy.rel $dummy" ; -trap '"'"'rm -f $files; rmdir $tmpdir; exit 1'"'"' 1 2 15 ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - rm -f $files ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; -unset files' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit 0 ;; - amiga:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - arc:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - hp300:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mac68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - macppc:OpenBSD:*:*) - echo powerpc-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvme88k:OpenBSD:*:*) - echo m88k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - mvmeppc:OpenBSD:*:*) - echo powerpc-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - pmax:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - sgi:OpenBSD:*:*) - echo mipseb-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - sun3:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - wgrisc:OpenBSD:*:*) - echo mipsel-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - *:OpenBSD:*:*) - echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} - exit 0 ;; - alpha:OSF1:*:*) - if test $UNAME_RELEASE = "V4.0"; then - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - fi - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - eval $set_cc_for_build - cat <$dummy.s - .data -\$Lformat: - .byte 37,100,45,37,120,10,0 # "%d-%x\n" - - .text - .globl main - .align 4 - .ent main -main: - .frame \$30,16,\$26,0 - ldgp \$29,0(\$27) - .prologue 1 - .long 0x47e03d80 # implver \$0 - lda \$2,-1 - .long 0x47e20c21 # amask \$2,\$1 - lda \$16,\$Lformat - mov \$0,\$17 - not \$1,\$18 - jsr \$26,printf - ldgp \$29,0(\$26) - mov 0,\$16 - jsr \$26,exit - .end main -EOF - $CC_FOR_BUILD -o $dummy $dummy.s 2>/dev/null - if test "$?" = 0 ; then - case `$dummy` in - 0-0) - UNAME_MACHINE="alpha" - ;; - 1-0) - UNAME_MACHINE="alphaev5" - ;; - 1-1) - UNAME_MACHINE="alphaev56" - ;; - 1-101) - UNAME_MACHINE="alphapca56" - ;; - 2-303) - UNAME_MACHINE="alphaev6" - ;; - 2-307) - UNAME_MACHINE="alphaev67" - ;; - 2-1307) - UNAME_MACHINE="alphaev68" - ;; - 3-1307) - UNAME_MACHINE="alphaev7" - ;; - esac - fi - rm -f $dummy.s $dummy && rmdir $tmpdir - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit 0 ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit 0 ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit 0 ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit 0;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit 0 ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit 0 ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit 0 ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit 0;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit 0;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit 0 ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit 0 ;; - DRS?6000:UNIX_SV:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7 && exit 0 ;; - esac ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - i86pc:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit 0 ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit 0 ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit 0 ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit 0 ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit 0 ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit 0 ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit 0 ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit 0 ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit 0 ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit 0 ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit 0 ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit 0 ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit 0 ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c \ - && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ - && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 - rm -f $dummy.c $dummy && rmdir $tmpdir - echo mips-mips-riscos${UNAME_RELEASE} - exit 0 ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit 0 ;; - Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit 0 ;; - Night_Hawk:*:*:PowerMAX_OS) - echo powerpc-harris-powermax - exit 0 ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit 0 ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit 0 ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit 0 ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit 0 ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit 0 ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit 0 ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit 0 ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit 0 ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit 0 ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit 0 ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit 0 ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit 0 ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 - rm -f $dummy.c $dummy && rmdir $tmpdir - echo rs6000-ibm-aix3.2.5 - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit 0 ;; - *:AIX:*:[45]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit 0 ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit 0 ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit 0 ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit 0 ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit 0 ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit 0 ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit 0 ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit 0 ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` - if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi - rm -f $dummy.c $dummy && rmdir $tmpdir - fi ;; - esac - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit 0 ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit 0 ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 - rm -f $dummy.c $dummy && rmdir $tmpdir - echo unknown-hitachi-hiuxwe2 - exit 0 ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit 0 ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit 0 ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit 0 ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit 0 ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit 0 ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit 0 ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit 0 ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit 0 ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit 0 ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit 0 ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit 0 ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit 0 ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*T3D:*:*:*) - echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit 0 ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit 0 ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit 0 ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit 0 ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit 0 ;; - *:FreeBSD:*:*) - # Determine whether the default compiler uses glibc. - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - #if __GLIBC__ >= 2 - LIBC=gnu - #else - LIBC= - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` - rm -f $dummy.c && rmdir $tmpdir - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC} - exit 0 ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit 0 ;; - i*:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit 0 ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit 0 ;; - x86:Interix*:3*) - echo i386-pc-interix3 - exit 0 ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i386-pc-interix - exit 0 ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit 0 ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit 0 ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit 0 ;; - *:GNU:*:*) - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit 0 ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit 0 ;; - arm*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - mips:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips - #undef mipsel - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mipsel - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips - #else - CPU= - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` - rm -f $dummy.c && rmdir $tmpdir - test x"${CPU}" != x && echo "${CPU}-pc-linux-gnu" && exit 0 - ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit 0 ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit 0 ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit 0 ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit 0 ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit 0 ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit 0 ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit 0 ;; - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit 0 ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit 0 ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit 0 ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit 0 ;; - esac - # Determine whether the default compiler is a.out or elf - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif - #else - #ifdef __INTEL_COMPILER - LIBC=gnu - #else - LIBC=gnuaout - #endif - #endif -EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` - rm -f $dummy.c && rmdir $tmpdir - test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0 - test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 - ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit 0 ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit 0 ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit 0 ;; - i*86:*:5:[78]*) - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit 0 ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` - (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit 0 ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit 0 ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp - exit 0 ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit 0 ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit 0 ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit 0 ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit 0 ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit 0 ;; - M68*:*:R3V[567]*:*) - test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; - 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4.3${OS_REL} && exit 0 - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && echo i486-ncr-sysv4 && exit 0 ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit 0 ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit 0 ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit 0 ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit 0 ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit 0 ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit 0 ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit 0 ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes . - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit 0 ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit 0 ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit 0 ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit 0 ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit 0 ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit 0 ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit 0 ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit 0 ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit 0 ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit 0 ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit 0 ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit 0 ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit 0 ;; - *:Darwin:*:*) - echo `uname -p`-apple-darwin${UNAME_RELEASE} - exit 0 ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit 0 ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit 0 ;; - NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit 0 ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit 0 ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit 0 ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit 0 ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit 0 ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit 0 ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit 0 ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit 0 ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit 0 ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit 0 ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit 0 ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit 0 ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit 0 ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit 0 ;; -esac - -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -eval $set_cc_for_build -cat >$dummy.c < -# include -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && rm -f $dummy.c $dummy && rmdir $tmpdir && exit 0 -rm -f $dummy.c $dummy && rmdir $tmpdir - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit 0 ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit 0 ;; - c34*) - echo c34-convex-bsd - exit 0 ;; - c38*) - echo c38-convex-bsd - exit 0 ;; - c4*) - echo c4-convex-bsd - exit 0 ;; - esac -fi - -cat >&2 < in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/engine/voice_codecs/speex/source/config.sub b/engine/voice_codecs/speex/source/config.sub deleted file mode 100644 index 1dea9b79..00000000 --- a/engine/voice_codecs/speex/source/config.sub +++ /dev/null @@ -1,1470 +0,0 @@ -#! /bin/sh -# Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002 Free Software Foundation, Inc. - -timestamp='2002-09-05' - -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.sub ($timestamp) - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit 0 ;; - --version | -v ) - echo "$version" ; exit 0 ;; - --help | --h* | -h ) - echo "$usage"; exit 0 ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit 0;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | freebsd*-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis) - os= - basic_machine=$1 - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ - | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | i370 | i860 | i960 | ia64 \ - | ip2k \ - | m32r | m68000 | m68k | m88k | mcore \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64vr | mips64vrel \ - | mips64orion | mips64orionel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mipsisa32 | mipsisa32el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | ns16k | ns32k \ - | openrisc | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ - | pyramid \ - | sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \ - | strongarm \ - | tahoe | thumb | tic80 | tron \ - | v850 | v850e \ - | we32k \ - | x86 | xscale | xstormy16 | xtensa \ - | z8k) - basic_machine=$basic_machine-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12) - # Motorola 68HC11/12. - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* \ - | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* \ - | clipper-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* \ - | m32r-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | mcore-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipstx39 | mipstx39el \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ - | pyramid-* \ - | romp-* | rs6000-* \ - | sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \ - | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* | tic30-* | tic4x-* | tic54x-* | tic80-* | tron-* \ - | v850-* | v850e-* | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \ - | xtensa-* \ - | ymp-* \ - | z8k-*) - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - crds | unos) - basic_machine=m68k-crds - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - mmix*) - basic_machine=mmix-knuth - os=-mmixware - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - or32 | or32-*) - basic_machine=or32-unknown - os=-coff - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2) - basic_machine=i686-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc) basic_machine=powerpc-unknown - ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sb1) - basic_machine=mipsisa64sb1-unknown - ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3d) - basic_machine=alpha-cray - os=-unicos - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tic4x | c4x*) - basic_machine=tic4x-unknown - os=-coff - ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - windows32) - basic_machine=i386-pc - os=-windows32-msvcrt - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele) - basic_machine=sh-unknown - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparc | sparcv9 | sparcv9b) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ - | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* | -powermax*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto*) - os=-nto-qnx - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -atheos*) - os=-atheos - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -nova*) - os=-rtmk-nova - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - # This must come before the *-dec entry. - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 - ;; - m68*-cisco) - os=-aout - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-ibm) - os=-aix - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit 0 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/engine/voice_codecs/speex/source/configure b/engine/voice_codecs/speex/source/configure deleted file mode 100644 index 809abf69..00000000 --- a/engine/voice_codecs/speex/source/configure +++ /dev/null @@ -1,6110 +0,0 @@ -#! /bin/sh - -# Guess values for system-dependent variables and create Makefiles. -# Generated automatically using autoconf version 2.13 -# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. - -# Defaults: -ac_help= -ac_default_prefix=/usr/local -# Any additions from configure.in: -ac_help="$ac_help - --enable-maintainer-mode enable make rules and dependencies not useful - (and sometimes confusing) to the casual installer" -ac_help="$ac_help - --enable-shared[=PKGS] build shared libraries [default=yes]" -ac_help="$ac_help - --enable-static[=PKGS] build static libraries [default=yes]" -ac_help="$ac_help - --enable-fast-install[=PKGS] optimize for fast installation [default=yes]" -ac_help="$ac_help - --with-gnu-ld assume the C compiler uses GNU ld [default=no]" - -# Find the correct PATH separator. Usually this is `:', but -# DJGPP uses `;' like DOS. -if test "X${PATH_SEPARATOR+set}" != Xset; then - UNAME=${UNAME-`uname 2>/dev/null`} - case X$UNAME in - *-DOS) lt_cv_sys_path_separator=';' ;; - *) lt_cv_sys_path_separator=':' ;; - esac - PATH_SEPARATOR=$lt_cv_sys_path_separator -fi - - -# Check that we are running under the correct shell. -SHELL=${CONFIG_SHELL-/bin/sh} - -case X$ECHO in -X*--fallback-echo) - # Remove one level of quotation (which was required for Make). - ECHO=`echo "$ECHO" | sed 's,\\\\\$\\$0,'$0','` - ;; -esac - -echo=${ECHO-echo} -if test "X$1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X$1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then - # Yippee, $echo works! - : -else - # Restart under the correct shell. - exec $SHELL "$0" --no-reexec ${1+"$@"} -fi - -if test "X$1" = X--fallback-echo; then - # used as fallback echo - shift - cat </dev/null && - echo_test_string="`eval $cmd`" && - (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null - then - break - fi - done -fi - -if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - : -else - # The Solaris, AIX, and Digital Unix default echo programs unquote - # backslashes. This makes it impossible to quote backslashes using - # echo "$something" | sed 's/\\/\\\\/g' - # - # So, first we look for a working echo in the user's PATH. - - IFS="${IFS= }"; save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for dir in $PATH /usr/ucb; do - if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && - test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - echo="$dir/echo" - break - fi - done - IFS="$save_ifs" - - if test "X$echo" = Xecho; then - # We didn't find a better echo, so look for alternatives. - if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # This shell has a builtin print -r that does the trick. - echo='print -r' - elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && - test "X$CONFIG_SHELL" != X/bin/ksh; then - # If we have ksh, try running configure again with it. - ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} - export ORIGINAL_CONFIG_SHELL - CONFIG_SHELL=/bin/ksh - export CONFIG_SHELL - exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} - else - # Try using printf. - echo='printf %s\n' - if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # Cool, printf works - : - elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL - export CONFIG_SHELL - SHELL="$CONFIG_SHELL" - export SHELL - echo="$CONFIG_SHELL $0 --fallback-echo" - elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - echo="$CONFIG_SHELL $0 --fallback-echo" - else - # maybe with a smaller string... - prev=: - - for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do - if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null - then - break - fi - prev="$cmd" - done - - if test "$prev" != 'sed 50q "$0"'; then - echo_test_string=`eval $prev` - export echo_test_string - exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} - else - # Oops. We lost completely, so just stick with echo. - echo=echo - fi - fi - fi - fi -fi -fi - -# Copy echo and quote the copy suitably for passing to libtool from -# the Makefile, instead of quoting the original, which is used later. -ECHO=$echo -if test "X$ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then - ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" -fi - - -ac_help="$ac_help - --disable-libtool-lock avoid locking (might break parallel builds)" -ac_help="$ac_help - --with-pic try to use only PIC/non-PIC objects [default=use both]" -ac_help="$ac_help - --enable-ogg=[yes/no] Turn on or off the use of ogg -libraries [default=yes]" -ac_help="$ac_help - --with-ogg-dir=DIR where the root of OGG is installed " -ac_help="$ac_help - --with-ogg-includes=DIR where the OGG includes are. " -ac_help="$ac_help - --with-ogg-libraries=DIR where the OGG library is installed." -ac_help="$ac_help - --enable-sse enable SSE support" - -# Initialize some variables set by options. -# The variables have the same names as the options, with -# dashes changed to underlines. -build=NONE -cache_file=./config.cache -exec_prefix=NONE -host=NONE -no_create= -nonopt=NONE -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -target=NONE -verbose= -x_includes=NONE -x_libraries=NONE -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datadir='${prefix}/share' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -libdir='${exec_prefix}/lib' -includedir='${prefix}/include' -oldincludedir='/usr/include' -infodir='${prefix}/info' -mandir='${prefix}/man' - -# Initialize some other variables. -subdirs= -MFLAGS= MAKEFLAGS= -SHELL=${CONFIG_SHELL-/bin/sh} -# Maximum number of lines to put in a shell here document. -ac_max_here_lines=12 - -ac_prev= -for ac_option -do - - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval "$ac_prev=\$ac_option" - ac_prev= - continue - fi - - case "$ac_option" in - -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; - *) ac_optarg= ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case "$ac_option" in - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir="$ac_optarg" ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build="$ac_optarg" ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file="$ac_optarg" ;; - - -datadir | --datadir | --datadi | --datad | --data | --dat | --da) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ - | --da=*) - datadir="$ac_optarg" ;; - - -disable-* | --disable-*) - ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then - { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } - fi - ac_feature=`echo $ac_feature| sed 's/-/_/g'` - eval "enable_${ac_feature}=no" ;; - - -enable-* | --enable-*) - ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then - { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } - fi - ac_feature=`echo $ac_feature| sed 's/-/_/g'` - case "$ac_option" in - *=*) ;; - *) ac_optarg=yes ;; - esac - eval "enable_${ac_feature}='$ac_optarg'" ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix="$ac_optarg" ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he) - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat << EOF -Usage: configure [options] [host] -Options: [defaults in brackets after descriptions] -Configuration: - --cache-file=FILE cache test results in FILE - --help print this message - --no-create do not create output files - --quiet, --silent do not print \`checking...' messages - --version print the version of autoconf that created configure -Directory and file names: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [same as prefix] - --bindir=DIR user executables in DIR [EPREFIX/bin] - --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] - --libexecdir=DIR program executables in DIR [EPREFIX/libexec] - --datadir=DIR read-only architecture-independent data in DIR - [PREFIX/share] - --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data in DIR - [PREFIX/com] - --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] - --libdir=DIR object code libraries in DIR [EPREFIX/lib] - --includedir=DIR C header files in DIR [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] - --infodir=DIR info documentation in DIR [PREFIX/info] - --mandir=DIR man documentation in DIR [PREFIX/man] - --srcdir=DIR find the sources in DIR [configure dir or ..] - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM - run sed PROGRAM on installed program names -EOF - cat << EOF -Host type: - --build=BUILD configure for building on BUILD [BUILD=HOST] - --host=HOST configure for HOST [guessed] - --target=TARGET configure for TARGET [TARGET=HOST] -Features and packages: - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --x-includes=DIR X include files are in DIR - --x-libraries=DIR X library files are in DIR -EOF - if test -n "$ac_help"; then - echo "--enable and --with options recognized:$ac_help" - fi - exit 0 ;; - - -host | --host | --hos | --ho) - ac_prev=host ;; - -host=* | --host=* | --hos=* | --ho=*) - host="$ac_optarg" ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir="$ac_optarg" ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir="$ac_optarg" ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir="$ac_optarg" ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir="$ac_optarg" ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst \ - | --locals | --local | --loca | --loc | --lo) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* \ - | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) - localstatedir="$ac_optarg" ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir="$ac_optarg" ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir="$ac_optarg" ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix="$ac_optarg" ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix="$ac_optarg" ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix="$ac_optarg" ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name="$ac_optarg" ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir="$ac_optarg" ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir="$ac_optarg" ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site="$ac_optarg" ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir="$ac_optarg" ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir="$ac_optarg" ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target="$ac_optarg" ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers) - echo "configure generated by autoconf version 2.13" - exit 0 ;; - - -with-* | --with-*) - ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then - { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } - fi - ac_package=`echo $ac_package| sed 's/-/_/g'` - case "$ac_option" in - *=*) ;; - *) ac_optarg=yes ;; - esac - eval "with_${ac_package}='$ac_optarg'" ;; - - -without-* | --without-*) - ac_package=`echo $ac_option|sed -e 's/-*without-//'` - # Reject names that are not valid shell variable names. - if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then - { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } - fi - ac_package=`echo $ac_package| sed 's/-/_/g'` - eval "with_${ac_package}=no" ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes="$ac_optarg" ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries="$ac_optarg" ;; - - -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } - ;; - - *) - if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then - echo "configure: warning: $ac_option: invalid host type" 1>&2 - fi - if test "x$nonopt" != xNONE; then - { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } - fi - nonopt="$ac_option" - ;; - - esac -done - -if test -n "$ac_prev"; then - { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } -fi - -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 - -# File descriptor usage: -# 0 standard input -# 1 file creation -# 2 errors and warnings -# 3 some systems may open it to /dev/tty -# 4 used on the Kubota Titan -# 6 checking for... messages and results -# 5 compiler messages saved in config.log -if test "$silent" = yes; then - exec 6>/dev/null -else - exec 6>&1 -fi -exec 5>./config.log - -echo "\ -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. -" 1>&5 - -# Strip out --no-create and --no-recursion so they do not pile up. -# Also quote any args containing shell metacharacters. -ac_configure_args= -for ac_arg -do - case "$ac_arg" in - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c) ;; - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; - *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) - ac_configure_args="$ac_configure_args '$ac_arg'" ;; - *) ac_configure_args="$ac_configure_args $ac_arg" ;; - esac -done - -# NLS nuisances. -# Only set these to C if already set. These must not be set unconditionally -# because not all systems understand e.g. LANG=C (notably SCO). -# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! -# Non-C LC_CTYPE values break the ctype check. -if test "${LANG+set}" = set; then LANG=C; export LANG; fi -if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi -if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi -if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -rf conftest* confdefs.h -# AIX cpp loses on an empty file, so make sure it contains at least a newline. -echo > confdefs.h - -# A filename unique to this package, relative to the directory that -# configure is in, which we can look for to find out if srcdir is correct. -ac_unique_file=libspeex/speex.h - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then its parent. - ac_prog=$0 - ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` - test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. - srcdir=$ac_confdir - if test ! -r $srcdir/$ac_unique_file; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r $srcdir/$ac_unique_file; then - if test "$ac_srcdir_defaulted" = yes; then - { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } - else - { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } - fi -fi -srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` - -# Prefer explicitly selected file to automatically selected ones. -if test -z "$CONFIG_SITE"; then - if test "x$prefix" != xNONE; then - CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" - else - CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" - fi -fi -for ac_site_file in $CONFIG_SITE; do - if test -r "$ac_site_file"; then - echo "loading site script $ac_site_file" - . "$ac_site_file" - fi -done - -if test -r "$cache_file"; then - echo "loading cache $cache_file" - . $cache_file -else - echo "creating cache $cache_file" - > $cache_file -fi - -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - -ac_exeext= -ac_objext=o -if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then - # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. - if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then - ac_n= ac_c=' -' ac_t=' ' - else - ac_n=-n ac_c= ac_t= - fi -else - ac_n= ac_c='\c' ac_t= -fi - - - -SPEEX_MAJOR_VERSION=1 -SPEEX_MINOR_VERSION=0 -SPEEX_MICRO_VERSION=1 -SPEEX_VERSION=1.0.1 - -SPEEX_LT_CURRENT=2 -SPEEX_LT_REVISION=0 -SPEEX_LT_AGE=1 - - - - - -# For automake. -VERSION=$SPEEX_VERSION -PACKAGE=speex - -ac_aux_dir= -for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do - if test -f $ac_dir/install-sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f $ac_dir/install.sh; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - fi -done -if test -z "$ac_aux_dir"; then - { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } -fi -ac_config_guess=$ac_aux_dir/config.guess -ac_config_sub=$ac_aux_dir/config.sub -ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. - -am__api_version="1.4" -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# ./install, which can be erroneously created by make from ./install.sh. -echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:760: checking for a BSD compatible install" >&5 -if test -z "$INSTALL"; then -if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" - for ac_dir in $PATH; do - # Account for people who put trailing slashes in PATH elements. - case "$ac_dir/" in - /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - if test -f $ac_dir/$ac_prog; then - if test $ac_prog = install && - grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - else - ac_cv_path_install="$ac_dir/$ac_prog -c" - break 2 - fi - fi - done - ;; - esac - done - IFS="$ac_save_IFS" - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL="$ac_cv_path_install" - else - # As a last resort, use the slow shell script. We don't cache a - # path for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the path is relative. - INSTALL="$ac_install_sh" - fi -fi -echo "$ac_t""$INSTALL" 1>&6 - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 -echo "configure:813: checking whether build environment is sane" >&5 -# Just in case -sleep 1 -echo timestamp > conftestfile -# Do `set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t $srcdir/configure conftestfile` - fi - if test "$*" != "X $srcdir/configure conftestfile" \ - && test "$*" != "X conftestfile $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - { echo "configure: error: ls -t appears to fail. Make sure there is not a broken -alias in your environment" 1>&2; exit 1; } - fi - - test "$2" = conftestfile - ) -then - # Ok. - : -else - { echo "configure: error: newly created file is older than distributed files! -Check your system clock" 1>&2; exit 1; } -fi -rm -f conftest* -echo "$ac_t""yes" 1>&6 -if test "$program_transform_name" = s,x,x,; then - program_transform_name= -else - # Double any \ or $. echo might interpret backslashes. - cat <<\EOF_SED > conftestsed -s,\\,\\\\,g; s,\$,$$,g -EOF_SED - program_transform_name="`echo $program_transform_name|sed -f conftestsed`" - rm -f conftestsed -fi -test "$program_prefix" != NONE && - program_transform_name="s,^,${program_prefix},; $program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" - -# sed with no file args requires a program. -test "$program_transform_name" = "" && program_transform_name="s,x,x," - -echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 -echo "configure:870: checking whether ${MAKE-make} sets \${MAKE}" >&5 -set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftestmake <<\EOF -all: - @echo 'ac_maketemp="${MAKE}"' -EOF -# GNU make sometimes prints "make[1]: Entering...", which would confuse us. -eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` -if test -n "$ac_maketemp"; then - eval ac_cv_prog_make_${ac_make}_set=yes -else - eval ac_cv_prog_make_${ac_make}_set=no -fi -rm -f conftestmake -fi -if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then - echo "$ac_t""yes" 1>&6 - SET_MAKE= -else - echo "$ac_t""no" 1>&6 - SET_MAKE="MAKE=${MAKE-make}" -fi - - -PACKAGE=$PACKAGE - -VERSION=$VERSION - -if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then - { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } -fi - - - -missing_dir=`cd $ac_aux_dir && pwd` -echo $ac_n "checking for working aclocal-${am__api_version}""... $ac_c" 1>&6 -echo "configure:909: checking for working aclocal-${am__api_version}" >&5 -# Run test in a subshell; some versions of sh will print an error if -# an executable is not found, even if stderr is redirected. -# Redirect stdin to placate older versions of autoconf. Sigh. -if (aclocal-${am__api_version} --version) < /dev/null > /dev/null 2>&1; then - ACLOCAL=aclocal-${am__api_version} - echo "$ac_t""found" 1>&6 -else - ACLOCAL="$missing_dir/missing aclocal-${am__api_version}" - echo "$ac_t""missing" 1>&6 -fi - -echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 -echo "configure:922: checking for working autoconf" >&5 -# Run test in a subshell; some versions of sh will print an error if -# an executable is not found, even if stderr is redirected. -# Redirect stdin to placate older versions of autoconf. Sigh. -if (autoconf --version) < /dev/null > /dev/null 2>&1; then - AUTOCONF=autoconf - echo "$ac_t""found" 1>&6 -else - AUTOCONF="$missing_dir/missing autoconf" - echo "$ac_t""missing" 1>&6 -fi - -echo $ac_n "checking for working automake-${am__api_version}""... $ac_c" 1>&6 -echo "configure:935: checking for working automake-${am__api_version}" >&5 -# Run test in a subshell; some versions of sh will print an error if -# an executable is not found, even if stderr is redirected. -# Redirect stdin to placate older versions of autoconf. Sigh. -if (automake-${am__api_version} --version) < /dev/null > /dev/null 2>&1; then - AUTOMAKE=automake-${am__api_version} - echo "$ac_t""found" 1>&6 -else - AUTOMAKE="$missing_dir/missing automake-${am__api_version}" - echo "$ac_t""missing" 1>&6 -fi - -echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 -echo "configure:948: checking for working autoheader" >&5 -# Run test in a subshell; some versions of sh will print an error if -# an executable is not found, even if stderr is redirected. -# Redirect stdin to placate older versions of autoconf. Sigh. -if (autoheader --version) < /dev/null > /dev/null 2>&1; then - AUTOHEADER=autoheader - echo "$ac_t""found" 1>&6 -else - AUTOHEADER="$missing_dir/missing autoheader" - echo "$ac_t""missing" 1>&6 -fi - -echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 -echo "configure:961: checking for working makeinfo" >&5 -# Run test in a subshell; some versions of sh will print an error if -# an executable is not found, even if stderr is redirected. -# Redirect stdin to placate older versions of autoconf. Sigh. -if (makeinfo --version) < /dev/null > /dev/null 2>&1; then - MAKEINFO=makeinfo - echo "$ac_t""found" 1>&6 -else - MAKEINFO="$missing_dir/missing makeinfo" - echo "$ac_t""missing" 1>&6 -fi - - -echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6 -echo "configure:975: checking whether to enable maintainer-specific portions of Makefiles" >&5 - # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given. -if test "${enable_maintainer_mode+set}" = set; then - enableval="$enable_maintainer_mode" - USE_MAINTAINER_MODE=$enableval -else - USE_MAINTAINER_MODE=no -fi - - echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6 - - -if test $USE_MAINTAINER_MODE = yes; then - MAINTAINER_MODE_TRUE= - MAINTAINER_MODE_FALSE='#' -else - MAINTAINER_MODE_TRUE='#' - MAINTAINER_MODE_FALSE= -fi - MAINT=$MAINTAINER_MODE_TRUE - - - - -# Make sure we can run config.sub. -if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : -else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } -fi - -echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:1005: checking host system type" >&5 - -host_alias=$host -case "$host_alias" in -NONE) - case $nonopt in - NONE) - if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : - else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } - fi ;; - *) host_alias=$nonopt ;; - esac ;; -esac - -host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` -host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` -host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` -echo "$ac_t""$host" 1>&6 - -# Find the correct PATH separator. Usually this is `:', but -# DJGPP uses `;' like DOS. -if test "X${PATH_SEPARATOR+set}" != Xset; then - UNAME=${UNAME-`uname 2>/dev/null`} - case X$UNAME in - *-DOS) lt_cv_sys_path_separator=';' ;; - *) lt_cv_sys_path_separator=':' ;; - esac - PATH_SEPARATOR=$lt_cv_sys_path_separator -fi - -echo $ac_n "checking for Cygwin environment""... $ac_c" 1>&6 -echo "configure:1037: checking for Cygwin environment" >&5 -if eval "test \"`echo '$''{'ac_cv_cygwin'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - ac_cv_cygwin=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - ac_cv_cygwin=no -fi -rm -f conftest* -rm -f conftest* -fi - -echo "$ac_t""$ac_cv_cygwin" 1>&6 -CYGWIN= -test "$ac_cv_cygwin" = yes && CYGWIN=yes -echo $ac_n "checking for mingw32 environment""... $ac_c" 1>&6 -echo "configure:1070: checking for mingw32 environment" >&5 -if eval "test \"`echo '$''{'ac_cv_mingw32'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - ac_cv_mingw32=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - ac_cv_mingw32=no -fi -rm -f conftest* -rm -f conftest* -fi - -echo "$ac_t""$ac_cv_mingw32" 1>&6 -MINGW32= -test "$ac_cv_mingw32" = yes && MINGW32=yes -echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:1099: checking how to run the C preprocessor" >&5 -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then -if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - # This must be in double quotes, not single quotes, because CPP may get - # substituted into the Makefile and "${CC-cc}" will confuse make. - CPP="${CC-cc} -E" - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. - cat > conftest.$ac_ext < -Syntax Error -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1120: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - : -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - CPP="${CC-cc} -E -traditional-cpp" - cat > conftest.$ac_ext < -Syntax Error -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1137: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - : -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - CPP="${CC-cc} -nologo -E" - cat > conftest.$ac_ext < -Syntax Error -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1154: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - : -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - CPP=/lib/cpp -fi -rm -f conftest* -fi -rm -f conftest* -fi -rm -f conftest* - ac_cv_prog_CPP="$CPP" -fi - CPP="$ac_cv_prog_CPP" -else - ac_cv_prog_CPP="$CPP" -fi -echo "$ac_t""$CPP" 1>&6 - -# Check whether --enable-shared or --disable-shared was given. -if test "${enable_shared+set}" = set; then - enableval="$enable_shared" - p=${PACKAGE-default} -case $enableval in -yes) enable_shared=yes ;; -no) enable_shared=no ;; -*) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," - for pkg in $enableval; do - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS="$ac_save_ifs" - ;; -esac -else - enable_shared=yes -fi - -# Check whether --enable-static or --disable-static was given. -if test "${enable_static+set}" = set; then - enableval="$enable_static" - p=${PACKAGE-default} -case $enableval in -yes) enable_static=yes ;; -no) enable_static=no ;; -*) - enable_static=no - # Look at the argument we got. We use all the common list separators. - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," - for pkg in $enableval; do - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS="$ac_save_ifs" - ;; -esac -else - enable_static=yes -fi - -# Check whether --enable-fast-install or --disable-fast-install was given. -if test "${enable_fast_install+set}" = set; then - enableval="$enable_fast_install" - p=${PACKAGE-default} -case $enableval in -yes) enable_fast_install=yes ;; -no) enable_fast_install=no ;; -*) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," - for pkg in $enableval; do - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS="$ac_save_ifs" - ;; -esac -else - enable_fast_install=yes -fi - -echo $ac_n "checking build system type""... $ac_c" 1>&6 -echo "configure:1248: checking build system type" >&5 - -build_alias=$build -case "$build_alias" in -NONE) - case $nonopt in - NONE) build_alias=$host_alias ;; - *) build_alias=$nonopt ;; - esac ;; -esac - -build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` -build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` -build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` -build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` -echo "$ac_t""$build" 1>&6 - -# Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1268: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_CC="gcc" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1298: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_prog_rejected=no - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - break - fi - done - IFS="$ac_save_ifs" -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# -gt 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - set dummy "$ac_dir/$ac_word" "$@" - shift - ac_cv_prog_CC="$@" - fi -fi -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - if test -z "$CC"; then - case "`uname -s`" in - *win32* | *WIN32*) - # Extract the first word of "cl", so it can be a program name with args. -set dummy cl; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1349: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_CC="cl" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -CC="$ac_cv_prog_CC" -if test -n "$CC"; then - echo "$ac_t""$CC" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - ;; - esac - fi - test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } -fi - -echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:1381: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 - -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - -cat > conftest.$ac_ext << EOF - -#line 1392 "configure" -#include "confdefs.h" - -main(){return(0);} -EOF -if { (eval echo configure:1397: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - ac_cv_prog_cc_works=yes - # If we can't run a trivial program, we are probably using a cross compiler. - if (./conftest; exit) 2>/dev/null; then - ac_cv_prog_cc_cross=no - else - ac_cv_prog_cc_cross=yes - fi -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - ac_cv_prog_cc_works=no -fi -rm -fr conftest* -ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - -echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 -if test $ac_cv_prog_cc_works = no; then - { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } -fi -echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:1423: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 -echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 -cross_compiling=$ac_cv_prog_cc_cross - -echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:1428: checking whether we are using GNU C" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then - ac_cv_prog_gcc=yes -else - ac_cv_prog_gcc=no -fi -fi - -echo "$ac_t""$ac_cv_prog_gcc" 1>&6 - -if test $ac_cv_prog_gcc = yes; then - GCC=yes -else - GCC= -fi - -ac_test_CFLAGS="${CFLAGS+set}" -ac_save_CFLAGS="$CFLAGS" -CFLAGS= -echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:1456: checking whether ${CC-cc} accepts -g" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - echo 'void f(){}' > conftest.c -if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then - ac_cv_prog_cc_g=yes -else - ac_cv_prog_cc_g=no -fi -rm -f conftest* - -fi - -echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 -if test "$ac_test_CFLAGS" = set; then - CFLAGS="$ac_save_CFLAGS" -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi - -# Check whether --with-gnu-ld or --without-gnu-ld was given. -if test "${with_gnu_ld+set}" = set; then - withval="$with_gnu_ld" - test "$withval" = no || with_gnu_ld=yes -else - with_gnu_ld=no -fi - -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6 -echo "configure:1499: checking for ld used by GCC" >&5 - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [\\/]* | [A-Za-z]:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' - # Canonicalize the path of ld - ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` - while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do - ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - echo $ac_n "checking for GNU ld""... $ac_c" 1>&6 -echo "configure:1529: checking for GNU ld" >&5 -else - echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 -echo "configure:1532: checking for non-GNU ld" >&5 -fi -if eval "test \"`echo '$''{'lt_cv_path_LD'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -z "$LD"; then - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - if "$lt_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then - test "$with_gnu_ld" != no && break - else - test "$with_gnu_ld" != yes && break - fi - fi - done - IFS="$ac_save_ifs" -else - lt_cv_path_LD="$LD" # Let the user override the test with a path. -fi -fi - -LD="$lt_cv_path_LD" -if test -n "$LD"; then - echo "$ac_t""$LD" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi -test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; } -echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6 -echo "configure:1567: checking if the linker ($LD) is GNU ld" >&5 -if eval "test \"`echo '$''{'lt_cv_prog_gnu_ld'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - # I'd rather use --version here, but apparently some GNU ld's only accept -v. -if $LD -v 2>&1 &5; then - lt_cv_prog_gnu_ld=yes -else - lt_cv_prog_gnu_ld=no -fi -fi - -echo "$ac_t""$lt_cv_prog_gnu_ld" 1>&6 -with_gnu_ld=$lt_cv_prog_gnu_ld - - -echo $ac_n "checking for $LD option to reload object files""... $ac_c" 1>&6 -echo "configure:1584: checking for $LD option to reload object files" >&5 -if eval "test \"`echo '$''{'lt_cv_ld_reload_flag'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - lt_cv_ld_reload_flag='-r' -fi - -echo "$ac_t""$lt_cv_ld_reload_flag" 1>&6 -reload_flag=$lt_cv_ld_reload_flag -test -n "$reload_flag" && reload_flag=" $reload_flag" - -echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6 -echo "configure:1596: checking for BSD-compatible nm" >&5 -if eval "test \"`echo '$''{'lt_cv_path_NM'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM="$NM" -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do - test -z "$ac_dir" && ac_dir=. - tmp_nm=$ac_dir/${ac_tool_prefix}nm - if test -f $tmp_nm || test -f $tmp_nm$ac_exeext ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - if ($tmp_nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep '(/dev/null|Invalid file or object type)' >/dev/null; then - lt_cv_path_NM="$tmp_nm -B" - break - elif ($tmp_nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then - lt_cv_path_NM="$tmp_nm -p" - break - else - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - fi - fi - done - IFS="$ac_save_ifs" - test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm -fi -fi - -NM="$lt_cv_path_NM" -echo "$ac_t""$NM" 1>&6 - -echo $ac_n "checking for a sed that does not truncate output""... $ac_c" 1>&6 -echo "configure:1634: checking for a sed that does not truncate output" >&5 -if eval "test \"`echo '$''{'lt_cv_path_SED'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - # Loop through the user's path and test for sed and gsed. -# Then use that list of sed's as ones to test for truncation. -as_executable_p="test -f" -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then - _sed_list="$_sed_list $as_dir/$ac_prog$ac_exec_ext" - fi - done - done -done - - # Create a temporary directory, and hook for its removal unless debugging. -$debug || -{ - trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 - trap '{ (exit 1); exit 1; }' 1 2 13 15 -} - -# Create a (secure) tmp directory for tmp files. -: ${TMPDIR=/tmp} -{ - tmp=`(umask 077 && mktemp -d -q "$TMPDIR/sedXXXXXX") 2>/dev/null` && - test -n "$tmp" && test -d "$tmp" -} || -{ - tmp=$TMPDIR/sed$$-$RANDOM - (umask 077 && mkdir $tmp) -} || -{ - echo "$me: cannot create a temporary directory in $TMPDIR" >&2 - { (exit 1); exit 1; } -} - _max=0 - _count=0 - # Add /usr/xpg4/bin/sed as it is typically found on Solaris - # along with /bin/sed that truncates output. - for _sed in $_sed_list /usr/xpg4/bin/sed; do - test ! -f ${_sed} && break - cat /dev/null > "$tmp/sed.in" - _count=0 - echo ${ECHO_N-$ac_n} "0123456789${ECHO_C-$ac_c}" >"$tmp/sed.in" - # Check for GNU sed and select it if it is found. - if "${_sed}" --version 2>&1 < /dev/null | egrep '(GNU)' > /dev/null; then - lt_cv_path_SED=${_sed} - break - fi - while true; do - cat "$tmp/sed.in" "$tmp/sed.in" >"$tmp/sed.tmp" - mv "$tmp/sed.tmp" "$tmp/sed.in" - cp "$tmp/sed.in" "$tmp/sed.nl" - echo >>"$tmp/sed.nl" - ${_sed} -e 's/a$//' < "$tmp/sed.nl" >"$tmp/sed.out" || break - cmp -s "$tmp/sed.out" "$tmp/sed.nl" || break - # 40000 chars as input seems more than enough - test $_count -gt 10 && break - _count=`expr $_count + 1` - if test $_count -gt $_max; then - _max=$_count - lt_cv_path_SED=$_sed - fi - done - done - rm -rf "$tmp" - -fi - -if test "X$SED" != "X"; then - lt_cv_path_SED=$SED -else - SED=$lt_cv_path_SED -fi -echo "$ac_t""$SED" 1>&6 - -echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 -echo "configure:1718: checking whether ln -s works" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - rm -f conftestdata -if ln -s X conftestdata 2>/dev/null -then - rm -f conftestdata - ac_cv_prog_LN_S="ln -s" -else - ac_cv_prog_LN_S=ln -fi -fi -LN_S="$ac_cv_prog_LN_S" -if test "$ac_cv_prog_LN_S" = "ln -s"; then - echo "$ac_t""yes" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -echo $ac_n "checking how to recognise dependent libraries""... $ac_c" 1>&6 -echo "configure:1739: checking how to recognise dependent libraries" >&5 -if eval "test \"`echo '$''{'lt_cv_deplibs_check_method'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - lt_cv_file_magic_cmd='$MAGIC_CMD' -lt_cv_file_magic_test_file= -lt_cv_deplibs_check_method='unknown' -# Need to set the preceding variable on all platforms that support -# interlibrary dependencies. -# 'none' -- dependencies not supported. -# `unknown' -- same as none, but documents that we really don't know. -# 'pass_all' -- all dependencies passed with no checks. -# 'test_compile' -- check by making test program. -# 'file_magic [[regex]]' -- check by looking for files in library path -# which responds to the $file_magic_cmd with a given egrep regex. -# If you have `file' or equivalent on your system and you're not sure -# whether `pass_all' will *always* work, you probably want this one. - -case $host_os in -aix4* | aix5*) - lt_cv_deplibs_check_method=pass_all - ;; - -beos*) - lt_cv_deplibs_check_method=pass_all - ;; - -bsdi4*) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' - lt_cv_file_magic_test_file=/shlib/libc.so - ;; - -cygwin* | mingw* | pw32*) - lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method='file_magic Mach-O dynamically linked shared library' - lt_cv_file_magic_cmd='/usr/bin/file -L' - case "$host_os" in - rhapsody* | darwin1.[012]) - lt_cv_file_magic_test_file=`echo /System/Library/Frameworks/System.framework/Versions/*/System | head -1` - ;; - *) # Darwin 1.3 on - lt_cv_file_magic_test_file='/usr/lib/libSystem.dylib' - ;; - esac - ;; - -freebsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD)/i[3-9]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20*|hpux11*) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - irix5* | nonstopux*) - # this will be overridden with pass_all, but let us keep it just in case - lt_cv_deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" - ;; - *) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - # this will be overridden with pass_all, but let us keep it just in case - lt_cv_deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1" - ;; - esac - lt_cv_file_magic_test_file=`echo /lib${libsuff}/libc.so*` - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be Linux ELF. -linux-gnu*) - case $host_cpu in - alpha* | hppa* | i*86 | mips | mipsel | powerpc* | sparc* | ia64* | x86_64*) - lt_cv_deplibs_check_method=pass_all ;; - *) - # glibc up to 2.1.1 does not perform some relocations on ARM - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; - esac - lt_cv_file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` - ;; - -netbsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so\.[0-9]+\.[0-9]+$' - else - lt_cv_deplibs_check_method='match_pattern /lib[^/\.]+\.so$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -openbsd*) - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object' - else - lt_cv_deplibs_check_method='file_magic OpenBSD.* shared library' - fi - ;; - -osf3* | osf4* | osf5*) - # this will be overridden with pass_all, but let us keep it just in case - lt_cv_deplibs_check_method='file_magic COFF format alpha shared library' - lt_cv_file_magic_test_file=/shlib/libc.so - lt_cv_deplibs_check_method=pass_all - ;; - -sco3.2v5*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - lt_cv_file_magic_test_file=/lib/libc.so - ;; - -sysv5uw[78]* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; -esac - -fi - -echo "$ac_t""$lt_cv_deplibs_check_method" 1>&6 -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method - -echo $ac_n "checking for object suffix""... $ac_c" 1>&6 -echo "configure:1925: checking for object suffix" >&5 -if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - rm -f conftest* -echo 'int i = 1;' > conftest.$ac_ext -if { (eval echo configure:1931: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - for ac_file in conftest.*; do - case $ac_file in - *.c) ;; - *) ac_cv_objext=`echo $ac_file | sed -e s/conftest.//` ;; - esac - done -else - { echo "configure: error: installation or configuration problem; compiler does not work" 1>&2; exit 1; } -fi -rm -f conftest* -fi - -echo "$ac_t""$ac_cv_objext" 1>&6 -OBJEXT=$ac_cv_objext -ac_objext=$ac_cv_objext - - - -echo $ac_n "checking for executable suffix""... $ac_c" 1>&6 -echo "configure:1951: checking for executable suffix" >&5 -if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test "$CYGWIN" = yes || test "$MINGW32" = yes; then - ac_cv_exeext=.exe -else - rm -f conftest* - echo 'int main () { return 0; }' > conftest.$ac_ext - ac_cv_exeext= - if { (eval echo configure:1961: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then - for file in conftest.*; do - case $file in - *.c | *.o | *.obj) ;; - *) ac_cv_exeext=`echo $file | sed -e s/conftest//` ;; - esac - done - else - { echo "configure: error: installation or configuration problem: compiler cannot create executables." 1>&2; exit 1; } - fi - rm -f conftest* - test x"${ac_cv_exeext}" = x && ac_cv_exeext=no -fi -fi - -EXEEXT="" -test x"${ac_cv_exeext}" != xno && EXEEXT=${ac_cv_exeext} -echo "$ac_t""${ac_cv_exeext}" 1>&6 -ac_exeext=$EXEEXT - -if test $host != $build; then - ac_tool_prefix=${host_alias}- -else - ac_tool_prefix= -fi - - - - -# Check for command to grab the raw symbol name followed by C symbol from nm. -echo $ac_n "checking command to parse $NM output""... $ac_c" 1>&6 -echo "configure:1992: checking command to parse $NM output" >&5 -if eval "test \"`echo '$''{'lt_cv_sys_global_symbol_pipe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[BCDEGRST]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([_A-Za-z][_A-Za-z0-9]*\)' - -# Transform the above into a raw symbol and a C symbol. -symxfrm='\1 \2\3 \3' - -# Transform an extracted symbol line into a proper C declaration -lt_cv_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[BCDT]' - ;; -cygwin* | mingw* | pw32*) - symcode='[ABCDGISTW]' - ;; -hpux*) # Its linker distinguishes data from code symbols - lt_cv_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - lt_cv_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" - ;; -irix* | nonstopux*) - symcode='[BCDEGRST]' - ;; -osf*) - symcode='[BCDEGQRST]' - ;; -solaris* | sysv5*) - symcode='[BDT]' - ;; -sysv4) - symcode='[DFNSTU]' - ;; -esac - -# Handle CRLF in mingw tool chain -opt_cr= -case $host_os in -mingw*) - opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then - symcode='[ABCDGISTW]' -fi - -# Try without a prefix undercore, then with it. -for ac_symprfx in "" "_"; do - - # Write the raw and C identifiers. -lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*\($ac_symprfx\)$sympat$opt_cr$/$symxfrm/p'" - - # Check to see that the pipe works correctly. - pipe_works=no - rm -f conftest* - cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then - # Now try to grab the symbols. - nlist=conftest.nm - if { (eval echo configure:2078: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\") 1>&5; (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5; } && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if egrep ' nm_test_var$' "$nlist" >/dev/null; then - if egrep ' nm_test_func$' "$nlist" >/dev/null; then - cat < conftest.$ac_ext -#ifdef __cplusplus -extern "C" { -#endif - -EOF - # Now generate the symbol file. - eval "$lt_cv_global_symbol_to_cdecl"' < "$nlist" >> conftest.$ac_ext' - - cat <> conftest.$ac_ext -#if defined (__STDC__) && __STDC__ -# define lt_ptr void * -#else -# define lt_ptr char * -# define const -#endif - -/* The mapping between symbol names and symbols. */ -const struct { - const char *name; - lt_ptr address; -} -lt_preloaded_symbols[] = -{ -EOF - sed "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr) \&\2},/" < "$nlist" >> conftest.$ac_ext - cat <<\EOF >> conftest.$ac_ext - {0, (lt_ptr) 0} -}; - -#ifdef __cplusplus -} -#endif -EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - save_LIBS="$LIBS" - save_CFLAGS="$CFLAGS" - LIBS="conftstm.$ac_objext" - CFLAGS="$CFLAGS$no_builtin_flag" - if { (eval echo configure:2129: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest$ac_exeext; then - pipe_works=yes - fi - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" - else - echo "cannot find nm_test_func in $nlist" >&5 - fi - else - echo "cannot find nm_test_var in $nlist" >&5 - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 - fi - else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - fi - rm -f conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done - -fi - -global_symbol_pipe="$lt_cv_sys_global_symbol_pipe" -if test -z "$lt_cv_sys_global_symbol_pipe"; then - global_symbol_to_cdecl= - global_symbol_to_c_name_address= -else - global_symbol_to_cdecl="$lt_cv_global_symbol_to_cdecl" - global_symbol_to_c_name_address="$lt_cv_global_symbol_to_c_name_address" -fi -if test -z "$global_symbol_pipe$global_symbol_to_cdec$global_symbol_to_c_name_address"; -then - echo "$ac_t""failed" 1>&6 -else - echo "$ac_t""ok" 1>&6 -fi - -for ac_hdr in dlfcn.h -do -ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` -echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:2178: checking for $ac_hdr" >&5 -if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2188: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - rm -rf conftest* - eval "ac_cv_header_$ac_safe=yes" -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_header_$ac_safe=no" -fi -rm -f conftest* -fi -if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` - cat >> confdefs.h <&6 -fi -done - - - - - - -# Only perform the check for file, if the check method requires it -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - echo $ac_n "checking for ${ac_tool_prefix}file""... $ac_c" 1>&6 -echo "configure:2224: checking for ${ac_tool_prefix}file" >&5 -if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - case $MAGIC_CMD in - /*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; - ?:/*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. - ;; - *) - ac_save_MAGIC_CMD="$MAGIC_CMD" - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="/usr/bin:$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/${ac_tool_prefix}file; then - lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - egrep "$file_magic_regex" > /dev/null; then - : - else - cat <&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -EOF - fi ;; - esac - fi - break - fi - done - IFS="$ac_save_ifs" - MAGIC_CMD="$ac_save_MAGIC_CMD" - ;; -esac -fi - -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - echo "$ac_t""$MAGIC_CMD" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - echo $ac_n "checking for file""... $ac_c" 1>&6 -echo "configure:2286: checking for file" >&5 -if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - case $MAGIC_CMD in - /*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; - ?:/*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a dos path. - ;; - *) - ac_save_MAGIC_CMD="$MAGIC_CMD" - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="/usr/bin:$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/file; then - lt_cv_path_MAGIC_CMD="$ac_dir/file" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - egrep "$file_magic_regex" > /dev/null; then - : - else - cat <&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -EOF - fi ;; - esac - fi - break - fi - done - IFS="$ac_save_ifs" - MAGIC_CMD="$ac_save_MAGIC_CMD" - ;; -esac -fi - -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - echo "$ac_t""$MAGIC_CMD" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - else - MAGIC_CMD=: - fi -fi - - fi - ;; -esac - -# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2357: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -RANLIB="$ac_cv_prog_RANLIB" -if test -n "$RANLIB"; then - echo "$ac_t""$RANLIB" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - -if test -z "$ac_cv_prog_RANLIB"; then -if test -n "$ac_tool_prefix"; then - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2389: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_RANLIB="ranlib" - break - fi - done - IFS="$ac_save_ifs" - test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" -fi -fi -RANLIB="$ac_cv_prog_RANLIB" -if test -n "$RANLIB"; then - echo "$ac_t""$RANLIB" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -else - RANLIB=":" -fi -fi - -# Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2424: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - break - fi - done - IFS="$ac_save_ifs" -fi -fi -STRIP="$ac_cv_prog_STRIP" -if test -n "$STRIP"; then - echo "$ac_t""$STRIP" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - - -if test -z "$ac_cv_prog_STRIP"; then -if test -n "$ac_tool_prefix"; then - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:2456: checking for $ac_word" >&5 -if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" - ac_dummy="$PATH" - for ac_dir in $ac_dummy; do - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/$ac_word; then - ac_cv_prog_STRIP="strip" - break - fi - done - IFS="$ac_save_ifs" - test -z "$ac_cv_prog_STRIP" && ac_cv_prog_STRIP=":" -fi -fi -STRIP="$ac_cv_prog_STRIP" -if test -n "$STRIP"; then - echo "$ac_t""$STRIP" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -else - STRIP=":" -fi -fi - - -enable_dlopen=no -enable_win32_dll=no - -# Check whether --enable-libtool-lock or --disable-libtool-lock was given. -if test "${enable_libtool_lock+set}" = set; then - enableval="$enable_libtool_lock" - : -fi - -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -*-*-irix6*) - # Find out which ABI we are using. - echo '#line 2505 "configure"' > conftest.$ac_ext - if { (eval echo configure:2506: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-linux*) - # Test if the compiler is 64bit - echo 'int i;' > conftest.$ac_ext - lt_cv_cc_64bit_output=no - if { (eval echo configure:2526: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - case `/usr/bin/file conftest.$ac_objext` in - *"ELF 64"*) - lt_cv_cc_64bit_output=yes - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -belf" - echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6 -echo "configure:2541: checking whether the C compiler needs -belf" >&5 -if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - - ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - - cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - lt_cv_cc_needs_belf=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - lt_cv_cc_needs_belf=no -fi -rm -f conftest* - ac_ext=c -# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. -ac_cpp='$CPP $CPPFLAGS' -ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' -cross_compiling=$ac_cv_prog_cc_cross - -fi - -echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6 - if test x"$lt_cv_cc_needs_belf" != x"yes"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" - fi - ;; - - -esac - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed='sed -e s/^X//' -sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Constants: -rm="rm -f" - -# Global variables: -default_ofile=libtool -can_build_shared=yes - -# All known linkers require a `.a' archive for static linking (except M$VC, -# which needs '.lib'). -libext=a -ltmain="$ac_aux_dir/ltmain.sh" -ofile="$default_ofile" -with_gnu_ld="$lt_cv_prog_gnu_ld" -need_locks="$enable_libtool_lock" - -old_CC="$CC" -old_CFLAGS="$CFLAGS" - -# Set sane defaults for various variables -test -z "$AR" && AR=ar -test -z "$AR_FLAGS" && AR_FLAGS=cru -test -z "$AS" && AS=as -test -z "$CC" && CC=cc -test -z "$DLLTOOL" && DLLTOOL=dlltool -test -z "$LD" && LD=ld -test -z "$LN_S" && LN_S="ln -s" -test -z "$MAGIC_CMD" && MAGIC_CMD=file -test -z "$NM" && NM=nm -test -z "$OBJDUMP" && OBJDUMP=objdump -test -z "$RANLIB" && RANLIB=: -test -z "$STRIP" && STRIP=: -test -z "$ac_objext" && ac_objext=o - -if test x"$host" != x"$build"; then - ac_tool_prefix=${host_alias}- -else - ac_tool_prefix= -fi - -# Transform linux* to *-*-linux-gnu*, to support old configure scripts. -case $host_os in -linux-gnu*) ;; -linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'` -esac - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - openbsd*) - old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" - ;; - *) - old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" -fi - -# Allow CC to be a program name with arguments. -set dummy $CC -compiler="$2" - -echo $ac_n "checking for objdir""... $ac_c" 1>&6 -echo "configure:2681: checking for objdir" >&5 -rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - objdir=_libs -fi -rmdir .libs 2>/dev/null -echo "$ac_t""$objdir" 1>&6 - - -# Check whether --with-pic or --without-pic was given. -if test "${with_pic+set}" = set; then - withval="$with_pic" - pic_mode="$withval" -else - pic_mode=default -fi - -test -z "$pic_mode" && pic_mode=default - -# We assume here that the value for lt_cv_prog_cc_pic will not be cached -# in isolation, and that seeing it set (from the cache) indicates that -# the associated values are set (in the cache) correctly too. -echo $ac_n "checking for $compiler option to produce PIC""... $ac_c" 1>&6 -echo "configure:2708: checking for $compiler option to produce PIC" >&5 -if eval "test \"`echo '$''{'lt_cv_prog_cc_pic'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - lt_cv_prog_cc_pic= - lt_cv_prog_cc_shlib= - lt_cv_prog_cc_wl= - lt_cv_prog_cc_static= - lt_cv_prog_cc_no_builtin= - lt_cv_prog_cc_can_build_shared=$can_build_shared - - if test "$GCC" = yes; then - lt_cv_prog_cc_wl='-Wl,' - lt_cv_prog_cc_static='-static' - - case $host_os in - aix*) - # Below there is a dirty hack to force normal static linking with -ldl - # The problem is because libdl dynamically linked with both libc and - # libC (AIX C++ library), which obviously doesn't included in libraries - # list by gcc. This cause undefined symbols with -static flags. - # This hack allows C programs to be linked with "-static -ldl", but - # not sure about C++ programs. - lt_cv_prog_cc_static="$lt_cv_prog_cc_static ${lt_cv_prog_cc_wl}-lC" - ;; - amigaos*) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - lt_cv_prog_cc_pic='-m68020 -resident32 -malways-restore-a4' - ;; - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - lt_cv_prog_cc_pic='-fno-common' - ;; - cygwin* | mingw* | pw32* | os2*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_cv_prog_cc_pic='-DDLL_EXPORT' - ;; - sysv4*MP*) - if test -d /usr/nec; then - lt_cv_prog_cc_pic=-Kconform_pic - fi - ;; - *) - lt_cv_prog_cc_pic='-fPIC' - ;; - esac - else - # PORTME Check for PIC flags for the system compiler. - case $host_os in - aix3* | aix4* | aix5*) - lt_cv_prog_cc_wl='-Wl,' - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_cv_prog_cc_static='-Bstatic' - else - lt_cv_prog_cc_static='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - hpux9* | hpux10* | hpux11*) - # Is there a better lt_cv_prog_cc_static that works with the bundled CC? - lt_cv_prog_cc_wl='-Wl,' - lt_cv_prog_cc_static="${lt_cv_prog_cc_wl}-a ${lt_cv_prog_cc_wl}archive" - lt_cv_prog_cc_pic='+Z' - ;; - - irix5* | irix6* | nonstopux*) - lt_cv_prog_cc_wl='-Wl,' - lt_cv_prog_cc_static='-non_shared' - # PIC (with -KPIC) is the default. - ;; - - cygwin* | mingw* | pw32* | os2*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_cv_prog_cc_pic='-DDLL_EXPORT' - ;; - - newsos6) - lt_cv_prog_cc_pic='-KPIC' - lt_cv_prog_cc_static='-Bstatic' - ;; - - osf3* | osf4* | osf5*) - # All OSF/1 code is PIC. - lt_cv_prog_cc_wl='-Wl,' - lt_cv_prog_cc_static='-non_shared' - ;; - - sco3.2v5*) - lt_cv_prog_cc_pic='-Kpic' - lt_cv_prog_cc_static='-dn' - lt_cv_prog_cc_shlib='-belf' - ;; - - solaris*) - lt_cv_prog_cc_pic='-KPIC' - lt_cv_prog_cc_static='-Bstatic' - lt_cv_prog_cc_wl='-Wl,' - ;; - - sunos4*) - lt_cv_prog_cc_pic='-PIC' - lt_cv_prog_cc_static='-Bstatic' - lt_cv_prog_cc_wl='-Qoption ld ' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - lt_cv_prog_cc_pic='-KPIC' - lt_cv_prog_cc_static='-Bstatic' - lt_cv_prog_cc_wl='-Wl,' - ;; - - uts4*) - lt_cv_prog_cc_pic='-pic' - lt_cv_prog_cc_static='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - lt_cv_prog_cc_pic='-Kconform_pic' - lt_cv_prog_cc_static='-Bstatic' - fi - ;; - - *) - lt_cv_prog_cc_can_build_shared=no - ;; - esac - fi - -fi - -if test -z "$lt_cv_prog_cc_pic"; then - echo "$ac_t""none" 1>&6 -else - echo "$ac_t""$lt_cv_prog_cc_pic" 1>&6 - - # Check to make sure the pic_flag actually works. - echo $ac_n "checking if $compiler PIC flag $lt_cv_prog_cc_pic works""... $ac_c" 1>&6 -echo "configure:2856: checking if $compiler PIC flag $lt_cv_prog_cc_pic works" >&5 - if eval "test \"`echo '$''{'lt_cv_prog_cc_pic_works'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $lt_cv_prog_cc_pic -DPIC" - cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - case $host_os in - hpux9* | hpux10* | hpux11*) - # On HP-UX, both CC and GCC only warn that PIC is supported... then - # they create non-PIC objects. So, if there were any warnings, we - # assume that PIC is not supported. - if test -s conftest.err; then - lt_cv_prog_cc_pic_works=no - else - lt_cv_prog_cc_pic_works=yes - fi - ;; - *) - lt_cv_prog_cc_pic_works=yes - ;; - esac - -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - lt_cv_prog_cc_pic_works=no - -fi -rm -f conftest* - CFLAGS="$save_CFLAGS" - -fi - - - if test "X$lt_cv_prog_cc_pic_works" = Xno; then - lt_cv_prog_cc_pic= - lt_cv_prog_cc_can_build_shared=no - else - lt_cv_prog_cc_pic=" $lt_cv_prog_cc_pic" - fi - - echo "$ac_t""$lt_cv_prog_cc_pic_works" 1>&6 -fi - -# Check for any special shared library compilation flags. -if test -n "$lt_cv_prog_cc_shlib"; then - echo "configure: warning: \`$CC' requires \`$lt_cv_prog_cc_shlib' to build shared libraries" 1>&2 - if echo "$old_CC $old_CFLAGS " | egrep -e "[ ]$lt_cv_prog_cc_shlib[ ]" >/dev/null; then : - else - echo "configure: warning: add \`$lt_cv_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" 1>&2 - lt_cv_prog_cc_can_build_shared=no - fi -fi - -echo $ac_n "checking if $compiler static flag $lt_cv_prog_cc_static works""... $ac_c" 1>&6 -echo "configure:2922: checking if $compiler static flag $lt_cv_prog_cc_static works" >&5 -if eval "test \"`echo '$''{'lt_cv_prog_cc_static_works'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - lt_cv_prog_cc_static_works=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $lt_cv_prog_cc_static" - cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - lt_cv_prog_cc_static_works=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 -fi -rm -f conftest* - LDFLAGS="$save_LDFLAGS" - -fi - - -# Belt *and* braces to stop my trousers falling down: -test "X$lt_cv_prog_cc_static_works" = Xno && lt_cv_prog_cc_static= -echo "$ac_t""$lt_cv_prog_cc_static_works" 1>&6 - -pic_flag="$lt_cv_prog_cc_pic" -special_shlib_compile_flags="$lt_cv_prog_cc_shlib" -wl="$lt_cv_prog_cc_wl" -link_static_flag="$lt_cv_prog_cc_static" -no_builtin_flag="$lt_cv_prog_cc_no_builtin" -can_build_shared="$lt_cv_prog_cc_can_build_shared" - - -# Check to see if options -o and -c are simultaneously supported by compiler -echo $ac_n "checking if $compiler supports -c -o file.$ac_objext""... $ac_c" 1>&6 -echo "configure:2964: checking if $compiler supports -c -o file.$ac_objext" >&5 -if eval "test \"`echo '$''{'lt_cv_compiler_c_o'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - -$rm -r conftest 2>/dev/null -mkdir conftest -cd conftest -echo "int some_variable = 0;" > conftest.$ac_ext -mkdir out -# According to Tom Tromey, Ian Lance Taylor reported there are C compilers -# that will create temporary files in the current directory regardless of -# the output directory. Thus, making CWD read-only will cause this test -# to fail, enabling locking or at least warning the user not to do parallel -# builds. -chmod -w . -save_CFLAGS="$CFLAGS" -CFLAGS="$CFLAGS -o out/conftest2.$ac_objext" -compiler_c_o=no -if { (eval echo configure:2983: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.$ac_objext; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s out/conftest.err; then - lt_cv_compiler_c_o=no - else - lt_cv_compiler_c_o=yes - fi -else - # Append any errors to the config.log. - cat out/conftest.err 1>&5 - lt_cv_compiler_c_o=no -fi -CFLAGS="$save_CFLAGS" -chmod u+w . -$rm conftest* out/* -rmdir out -cd .. -rmdir conftest -$rm -r conftest 2>/dev/null - -fi - -compiler_c_o=$lt_cv_compiler_c_o -echo "$ac_t""$compiler_c_o" 1>&6 - -if test x"$compiler_c_o" = x"yes"; then - # Check to see if we can write to a .lo - echo $ac_n "checking if $compiler supports -c -o file.lo""... $ac_c" 1>&6 -echo "configure:3012: checking if $compiler supports -c -o file.lo" >&5 - if eval "test \"`echo '$''{'lt_cv_compiler_o_lo'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - - lt_cv_compiler_o_lo=no - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -c -o conftest.lo" - save_objext="$ac_objext" - ac_objext=lo - cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - lt_cv_compiler_o_lo=no - else - lt_cv_compiler_o_lo=yes - fi - -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 -fi -rm -f conftest* - ac_objext="$save_objext" - CFLAGS="$save_CFLAGS" - -fi - - compiler_o_lo=$lt_cv_compiler_o_lo - echo "$ac_t""$compiler_o_lo" 1>&6 -else - compiler_o_lo=no -fi - -# Check to see if we can do hard links to lock some files if needed -hard_links="nottested" -if test "$compiler_c_o" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - echo $ac_n "checking if we can lock with hard links""... $ac_c" 1>&6 -echo "configure:3061: checking if we can lock with hard links" >&5 - hard_links=yes - $rm conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - echo "$ac_t""$hard_links" 1>&6 - if test "$hard_links" = no; then - echo "configure: warning: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" 1>&2 - need_locks=warn - fi -else - need_locks=no -fi - -if test "$GCC" = yes; then - # Check to see if options -fno-rtti -fno-exceptions are supported by compiler - echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions""... $ac_c" 1>&6 -echo "configure:3080: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 - echo "int some_variable = 0;" > conftest.$ac_ext - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.$ac_ext" - compiler_rtti_exceptions=no - cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - compiler_rtti_exceptions=no - else - compiler_rtti_exceptions=yes - fi - -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 -fi -rm -f conftest* - CFLAGS="$save_CFLAGS" - echo "$ac_t""$compiler_rtti_exceptions" 1>&6 - - if test "$compiler_rtti_exceptions" = "yes"; then - no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions' - else - no_builtin_flag=' -fno-builtin' - fi -fi - -# See if the linker supports building shared libraries. -echo $ac_n "checking whether the linker ($LD) supports shared libraries""... $ac_c" 1>&6 -echo "configure:3120: checking whether the linker ($LD) supports shared libraries" >&5 - -allow_undefined_flag= -no_undefined_flag= -need_lib_prefix=unknown -need_version=unknown -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -archive_cmds= -archive_expsym_cmds= -old_archive_from_new_cmds= -old_archive_from_expsyms_cmds= -export_dynamic_flag_spec= -whole_archive_flag_spec= -thread_safe_flag_spec= -hardcode_into_libs=no -hardcode_libdir_flag_spec= -hardcode_libdir_separator= -hardcode_direct=no -hardcode_minus_L=no -hardcode_shlibpath_var=unsupported -runpath_var= -link_all_deplibs=unknown -always_export_symbols=no -export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols' -# include_expsyms should be a list of space-separated symbols to be *always* -# included in the symbol list -include_expsyms= -# exclude_expsyms can be an egrep regular expression of symbols to exclude -# it will be wrapped by ` (' and `)$', so one must not match beginning or -# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', -# as well as any symbol that contains `d'. -exclude_expsyms="_GLOBAL_OFFSET_TABLE_" -# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out -# platforms (ab)use it in PIC code, but their linkers get confused if -# the symbol is explicitly referenced. Since portable code cannot -# rely on this symbol name, it's probably fine to never include it in -# preloaded symbol tables. -extract_expsyms_cmds= - -case $host_os in -cygwin* | mingw* | pw32*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; -openbsd*) - with_gnu_ld=no - ;; -esac - -ld_shlibs=yes -if test "$with_gnu_ld" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # See if GNU ld supports shared libraries. - case $host_os in - aix3* | aix4* | aix5*) - # On AIX, the GNU linker is very broken - # Note:Check GNU linker on AIX 5-IA64 when/if it becomes available. - ld_shlibs=no - cat <&2 - -*** Warning: the GNU linker, at least up to release 2.9.1, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to modify your PATH -*** so that a non-GNU linker is found, and then restart. - -EOF - ;; - - amigaos*) - archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - - # Samuel A. Falvo II reports - # that the semantics of dynamic libraries on AmigaOS, at least up - # to version 4, is to share data among multiple programs linked - # with the same dynamic library. Since this doesn't match the - # behavior of shared libraries on other platforms, we can use - # them. - ld_shlibs=no - ;; - - beos*) - if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - allow_undefined_flag=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - ld_shlibs=no - fi - ;; - - cygwin* | mingw* | pw32*) - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec='-L$libdir' - allow_undefined_flag=unsupported - always_export_symbols=yes - - extract_expsyms_cmds='test -f $output_objdir/impgen.c || \ - sed -e "/^# \/\* impgen\.c starts here \*\//,/^# \/\* impgen.c ends here \*\// { s/^# //;s/^# *$//; p; }" -e d < $''0 > $output_objdir/impgen.c~ - test -f $output_objdir/impgen.exe || (cd $output_objdir && \ - if test "x$HOST_CC" != "x" ; then $HOST_CC -o impgen impgen.c ; \ - else $CC -o impgen impgen.c ; fi)~ - $output_objdir/impgen $dir/$soroot > $output_objdir/$soname-def' - - old_archive_from_expsyms_cmds='$DLLTOOL --as=$AS --dllname $soname --def $output_objdir/$soname-def --output-lib $output_objdir/$newlib' - - # cygwin and mingw dlls have different entry points and sets of symbols - # to exclude. - # FIXME: what about values for MSVC? - dll_entry=__cygwin_dll_entry@12 - dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12~ - case $host_os in - mingw*) - # mingw values - dll_entry=_DllMainCRTStartup@12 - dll_exclude_symbols=DllMain@12,DllMainCRTStartup@12,DllEntryPoint@12~ - ;; - esac - - # mingw and cygwin differ, and it's simplest to just exclude the union - # of the two symbol sets. - dll_exclude_symbols=DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12,DllMainCRTStartup@12,DllEntryPoint@12 - - # recent cygwin and mingw systems supply a stub DllMain which the user - # can override, but on older systems we have to supply one (in ltdll.c) - if test "x$lt_cv_need_dllmain" = "xyes"; then - ltdll_obj='$output_objdir/$soname-ltdll.'"$ac_objext " - ltdll_cmds='test -f $output_objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $''0 > $output_objdir/$soname-ltdll.c~ - test -f $output_objdir/$soname-ltdll.$ac_objext || (cd $output_objdir && $CC -c $soname-ltdll.c)~' - else - ltdll_obj= - ltdll_cmds= - fi - - # Extract the symbol export list from an `--export-all' def file, - # then regenerate the def file from the symbol export list, so that - # the compiled dll only exports the symbol export list. - # Be careful not to strip the DATA tag left be newer dlltools. - export_symbols_cmds="$ltdll_cmds"' - $DLLTOOL --export-all --exclude-symbols '$dll_exclude_symbols' --output-def $output_objdir/$soname-def '$ltdll_obj'$libobjs $convenience~ - sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]*//" -e "s/ *;.*$//" < $output_objdir/$soname-def > $export_symbols' - - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is. - # If DATA tags from a recent dlltool are present, honour them! - archive_expsym_cmds='if test "x`sed 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname-def; - else - echo EXPORTS > $output_objdir/$soname-def; - _lt_hint=1; - cat $export_symbols | while read symbol; do - set dummy \$symbol; - case \$# in - 2) echo " \$2 @ \$_lt_hint ; " >> $output_objdir/$soname-def;; - 4) echo " \$2 \$3 \$4 ; " >> $output_objdir/$soname-def; _lt_hint=`expr \$_lt_hint - 1`;; - *) echo " \$2 @ \$_lt_hint \$3 ; " >> $output_objdir/$soname-def;; - esac; - _lt_hint=`expr 1 + \$_lt_hint`; - done; - fi~ - '"$ltdll_cmds"' - $CC -Wl,--base-file,$output_objdir/$soname-base '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ - $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp~ - $CC -Wl,--base-file,$output_objdir/$soname-base $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags~ - $DLLTOOL --as=$AS --dllname $soname --exclude-symbols '$dll_exclude_symbols' --def $output_objdir/$soname-def --base-file $output_objdir/$soname-base --output-exp $output_objdir/$soname-exp --output-lib $output_objdir/$libname.dll.a~ - $CC $output_objdir/$soname-exp '$lt_cv_cc_dll_switch' -Wl,-e,'$dll_entry' -o $output_objdir/$soname '$ltdll_obj'$libobjs $deplibs $compiler_flags' - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - archive_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared -nodefaultlibs $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris* | sysv5*) - if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then - ld_shlibs=no - cat <&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -EOF - elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - - sunos4*) - archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - *) - if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - esac - - if test "$ld_shlibs" = yes; then - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' - export_dynamic_flag_spec='${wl}--export-dynamic' - case $host_os in - cygwin* | mingw* | pw32*) - # dlltool doesn't understand --whole-archive et. al. - whole_archive_flag_spec= - ;; - *) - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | egrep 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec= - fi - ;; - esac - fi -else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - allow_undefined_flag=unsupported - always_export_symbols=yes - archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - hardcode_minus_L=yes - if test "$GCC" = yes && test -z "$link_static_flag"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - hardcode_direct=unsupported - fi - ;; - - aix4* | aix5*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix5*) - for ld_flag in $LDFLAGS; do - case $ld_flag in - *-brtl*) - aix_use_runtimelinking=yes - break - ;; - esac - done - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - hardcode_direct=yes - archive_cmds='' - hardcode_libdir_separator=':' - if test "$GCC" = yes; then - case $host_os in aix4.[012]|aix4.[012].*) - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && \ - strings "$collect2name" | grep resolve_lib_name >/dev/null - then - # We have reworked collect2 - hardcode_direct=yes - else - # We have old collect2 - hardcode_direct=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - hardcode_minus_L=yes - hardcode_libdir_flag_spec='-L$libdir' - hardcode_libdir_separator= - fi - esac - - shared_flag='-shared' - else - # not using gcc - if test "$host_cpu" = ia64; then - shared_flag='${wl}-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - # It seems that -bexpall can do strange things, so it is better to - # generate a list of symbols to export. - always_export_symbols=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - allow_undefined_flag='-berok' - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:/usr/lib:/lib' - archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' - allow_undefined_flag="-z nodefs" - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname ${wl}-h$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" - else - hardcode_libdir_flag_spec='${wl}-bnolibpath ${wl}-blibpath:$libdir:/usr/lib:/lib' - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - allow_undefined_flag='${wl}-berok' - # This is a bit strange, but is similar to how AIX traditionally builds - # it's shared libraries. - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols"' ~$AR -crlo $objdir/$libname$release.a $objdir/$soname' - fi - fi - ;; - - amigaos*) - archive_cmds='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - # see comment about different semantics on the GNU ld section - ld_shlibs=no - ;; - - cygwin* | mingw* | pw32*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec=' ' - allow_undefined_flag=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - old_archive_from_new_cmds='true' - # FIXME: Should let the user specify the lib program. - old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs' - fix_srcfile_path='`cygpath -w "$srcfile"`' - ;; - - darwin* | rhapsody*) - case "$host_os" in - rhapsody* | darwin1.[012]) - allow_undefined_flag='-undefined suppress' - ;; - *) # Darwin 1.3 on - allow_undefined_flag='-flat_namespace -undefined suppress' - ;; - esac - # FIXME: Relying on posixy $() will cause problems for - # cross-compilation, but unfortunately the echo tests do not - # yet detect zsh echo's removal of \ escapes. Also zsh mangles - # `"' quotes if we put them in here... so don't! - archive_cmds='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs && $CC $(test .$module = .yes && echo -bundle || echo -dynamiclib) $allow_undefined_flag -o $lib ${lib}-master.o $deplibs$linker_flags $(test .$module != .yes && echo -install_name $rpath/$soname $verstring)' - # We need to add '_' to the symbols in $export_symbols first - #archive_expsym_cmds="$archive_cmds"' && strip -s $export_symbols' - hardcode_direct=yes - hardcode_shlibpath_var=no - whole_archive_flag_spec='-all_load $convenience' - ;; - - freebsd1*) - ld_shlibs=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd*) - archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - hpux9* | hpux10* | hpux11*) - case $host_os in - hpux9*) archive_cmds='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' ;; - *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' ;; - esac - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - hardcode_minus_L=yes # Not in the search PATH, but as the default - # location of the library. - export_dynamic_flag_spec='${wl}-E' - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - else - archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec='-rpath $libdir' - fi - hardcode_libdir_separator=: - link_all_deplibs=yes - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - newsos6) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_shlibpath_var=no - ;; - - openbsd*) - hardcode_direct=yes - hardcode_shlibpath_var=no - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - export_dynamic_flag_spec='${wl}-E' - else - case "$host_os" in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-R$libdir' - ;; - *) - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - ;; - esac - fi - ;; - - os2*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - allow_undefined_flag=unsupported - archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - fi - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds='for i in `cat $export_symbols`; do printf "-exported_symbol " >> $lib.exp; echo "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ - $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib~$rm $lib.exp' - - #Both c and cxx compiler support -rpath directly - hardcode_libdir_flag_spec='-rpath $libdir' - fi - hardcode_libdir_separator=: - ;; - - sco3.2v5*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - export_dynamic_flag_spec='${wl}-Bexport' - ;; - - solaris*) - # gcc --version < 3.0 without binutils cannot create self contained - # shared libraries reliably, requiring libgcc.a to resolve some of - # the object symbols generated in some cases. Libraries that use - # assert need libgcc.a to resolve __eprintf, for example. Linking - # a copy of libgcc.a into every shared library to guarantee resolving - # such symbols causes other problems: According to Tim Van Holder - # , C++ libraries end up with a separate - # (to the application) exception stack for one thing. - no_undefined_flag=' -z defs' - if test "$GCC" = yes; then - case `$CC --version 2>/dev/null` in - [12].*) - cat <&2 - -*** Warning: Releases of GCC earlier than version 3.0 cannot reliably -*** create self contained shared libraries on Solaris systems, without -*** introducing a dependency on libgcc.a. Therefore, libtool is disabling -*** -no-undefined support, which will at least allow you to build shared -*** libraries. However, you may find that when you link such libraries -*** into an application without using GCC, you have to manually add -*** \`gcc --print-libgcc-file-name\` to the link command. We urge you to -*** upgrade to a newer version of GCC. Another option is to rebuild your -*** current GCC to use the GNU linker from GNU binutils 2.9.1 or newer. - -EOF - no_undefined_flag= - ;; - esac - fi - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_shlibpath_var=no - case $host_os in - solaris2.[0-5] | solaris2.[0-5].*) ;; - *) # Supported since Solaris 2.6 (maybe 2.5.1?) - whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; - esac - link_all_deplibs=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - sysv4) - case $host_vendor in - sni) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' - reload_cmds='$CC -r -o $output$reload_objs' - hardcode_direct=no - ;; - motorola) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no - ;; - - sysv4.3*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - export_dynamic_flag_spec='-Bexport' - ;; - - sysv5*) - no_undefined_flag=' -z text' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - hardcode_libdir_flag_spec= - hardcode_shlibpath_var=no - runpath_var='LD_RUN_PATH' - ;; - - uts4*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - dgux*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - sysv4*MP*) - if test -d /usr/nec; then - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ld_shlibs=yes - fi - ;; - - sysv4.2uw2*) - archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_minus_L=no - hardcode_shlibpath_var=no - hardcode_runpath_var=yes - runpath_var=LD_RUN_PATH - ;; - - sysv5uw7* | unixware7*) - no_undefined_flag='${wl}-z ${wl}text' - if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no - ;; - - *) - ld_shlibs=no - ;; - esac -fi -echo "$ac_t""$ld_shlibs" 1>&6 -test "$ld_shlibs" = no && can_build_shared=no - -# Check hardcoding attributes. -echo $ac_n "checking how to hardcode library paths into programs""... $ac_c" 1>&6 -echo "configure:3819: checking how to hardcode library paths into programs" >&5 -hardcode_action= -if test -n "$hardcode_libdir_flag_spec" || \ - test -n "$runpath_var"; then - - # We can hardcode non-existant directories. - if test "$hardcode_direct" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$hardcode_shlibpath_var" != no && - test "$hardcode_minus_L" != no; then - # Linking always hardcodes the temporary library directory. - hardcode_action=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - hardcode_action=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - hardcode_action=unsupported -fi -echo "$ac_t""$hardcode_action" 1>&6 - -striplib= -old_striplib= -echo $ac_n "checking whether stripping libraries is possible""... $ac_c" 1>&6 -echo "configure:3847: checking whether stripping libraries is possible" >&5 -if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - echo "$ac_t""yes" 1>&6 -else - echo "$ac_t""no" 1>&6 -fi - -reload_cmds='$LD$reload_flag -o $output$reload_objs' -test -z "$deplibs_check_method" && deplibs_check_method=unknown - -# PORTME Fill in your ld.so characteristics -echo $ac_n "checking dynamic linker characteristics""... $ac_c" 1>&6 -echo "configure:3861: checking dynamic linker characteristics" >&5 -library_names_spec= -libname_spec='lib$name' -soname_spec= -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib /usr/X11R6/lib" -sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib /usr/X11R6/lib" - -case $host_os in -aix3*) - version_type=linux - library_names_spec='${libname}${release}.so$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}.so$major' - ;; - -aix4* | aix5*) - version_type=linux - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}.so$major ${libname}${release}.so$versuffix $libname.so' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[01] | aix4.[01].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can - # not hardcode correct soname into executable. Probably we can - # add versioning support to collect2, so additional links can - # be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}.so$major' - fi - shlibpath_var=LIBPATH - fi - hardcode_into_libs=yes - ;; - -amigaos*) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done' - ;; - -beos*) - library_names_spec='${libname}.so' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi4*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - export_dynamic_flag_spec=-rdynamic - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32*) - version_type=windows - need_version=no - need_lib_prefix=no - case $GCC,$host_os in - yes,cygwin*) - library_names_spec='$libname.dll.a' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll' - postinstall_cmds='dlpath=`bash 2>&1 -c '\''. $dir/${file}i;echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog .libs/$dlname \$dldir/$dlname' - postuninstall_cmds='dldll=`bash 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $rm \$dlpath' - ;; - yes,mingw*) - library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll' - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | sed -e "s/^libraries://" -e "s/;/ /g" -e "s,=/,/,g"` - ;; - yes,pw32*) - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | sed -e 's/./-/g'`${versuffix}.dll' - ;; - *) - library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib' - ;; - esac - dynamic_linker='Win32 ld.exe' - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - # FIXME: Relying on posixy $() will cause problems for - # cross-compilation, but unfortunately the echo tests do not - # yet detect zsh echo's removal of \ escapes. - library_names_spec='${libname}${release}${versuffix}.$(test .$module = .yes && echo so || echo dylib) ${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib) ${libname}.$(test .$module = .yes && echo so || echo dylib)' - soname_spec='${libname}${release}${major}.$(test .$module = .yes && echo so || echo dylib)' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - ;; - -freebsd1*) - dynamic_linker=no - ;; - -freebsd*) - objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` - version_type=freebsd-$objformat - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix' - need_version=yes - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2*) - shlibpath_overrides_runpath=yes - ;; - *) - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - dynamic_linker="$host_os dld.sl" - version_type=sunos - need_lib_prefix=no - need_version=no - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl' - soname_spec='${libname}${release}.sl$major' - # HP-UX runs *really* slowly unless shared libraries are mode 555. - postinstall_cmds='chmod 555 $lib' - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) version_type=irix ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}.so$major' - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so $libname.so' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux-gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - case $host_cpu:$lt_cv_cc_64bit_output in - powerpc64:yes | s390x:yes | sparc64:yes | x86_64:yes) - sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /usr/X11R6/lib64" - sys_lib_search_path_spec="/lib64 /usr/lib64 /usr/local/lib64 /usr/X11R6/lib64" - ;; - esac - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then - library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so' - soname_spec='${libname}${release}.so$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -openbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case "$host_os" in - openbsd2.[89] | openbsd2.[89].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - ;; - -os2*) - libname_spec='$name' - need_lib_prefix=no - library_names_spec='$libname.dll $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_version=no - soname_spec='${libname}${release}.so$major' - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - hardcode_into_libs=yes - ;; - -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}.so$major' - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - shlibpath_var=LD_LIBRARY_PATH - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - version_type=linux - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - export_dynamic_flag_spec='${wl}-Blargedynsym' - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' - soname_spec='${libname}${release}.so$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so' - soname_spec='$libname.so.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -*) - dynamic_linker=no - ;; -esac -echo "$ac_t""$dynamic_linker" 1>&6 -test "$dynamic_linker" = no && can_build_shared=no - -# Report the final consequences. -echo $ac_n "checking if libtool supports shared libraries""... $ac_c" 1>&6 -echo "configure:4279: checking if libtool supports shared libraries" >&5 -echo "$ac_t""$can_build_shared" 1>&6 - -echo $ac_n "checking whether to build shared libraries""... $ac_c" 1>&6 -echo "configure:4283: checking whether to build shared libraries" >&5 -test "$can_build_shared" = "no" && enable_shared=no - -# On AIX, shared libraries and static libraries use the same namespace, and -# are all built from PIC. -case "$host_os" in -aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - -aix4*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; -esac -echo "$ac_t""$enable_shared" 1>&6 - -echo $ac_n "checking whether to build static libraries""... $ac_c" 1>&6 -echo "configure:4306: checking whether to build static libraries" >&5 -# Make sure either enable_shared or enable_static is yes. -test "$enable_shared" = yes || enable_static=yes -echo "$ac_t""$enable_static" 1>&6 - -if test "$hardcode_action" = relink; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - cygwin* | mingw* | pw32*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - *) - echo $ac_n "checking for shl_load""... $ac_c" 1>&6 -echo "configure:4347: checking for shl_load" >&5 -if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char shl_load(); - -int main() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_shl_load) || defined (__stub___shl_load) -choke me -#else -shl_load(); -#endif - -; return 0; } -EOF -if { (eval echo configure:4375: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_func_shl_load=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_func_shl_load=no" -fi -rm -f conftest* -fi - -if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then - echo "$ac_t""yes" 1>&6 - lt_cv_dlopen="shl_load" -else - echo "$ac_t""no" 1>&6 -echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6 -echo "configure:4393: checking for shl_load in -ldld" >&5 -ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-ldld $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" -else - echo "$ac_t""no" 1>&6 -echo $ac_n "checking for dlopen""... $ac_c" 1>&6 -echo "configure:4431: checking for dlopen" >&5 -if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dlopen(); - -int main() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_dlopen) || defined (__stub___dlopen) -choke me -#else -dlopen(); -#endif - -; return 0; } -EOF -if { (eval echo configure:4459: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_func_dlopen=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_func_dlopen=no" -fi -rm -f conftest* -fi - -if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then - echo "$ac_t""yes" 1>&6 - lt_cv_dlopen="dlopen" -else - echo "$ac_t""no" 1>&6 -echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 -echo "configure:4477: checking for dlopen in -ldl" >&5 -ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-ldl $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - echo "$ac_t""no" 1>&6 -echo $ac_n "checking for dlopen in -lsvld""... $ac_c" 1>&6 -echo "configure:4515: checking for dlopen in -lsvld" >&5 -ac_lib_var=`echo svld'_'dlopen | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-lsvld $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" -else - echo "$ac_t""no" 1>&6 -echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6 -echo "configure:4553: checking for dld_link in -ldld" >&5 -ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-ldld $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" -else - echo "$ac_t""no" 1>&6 -fi - - -fi - - -fi - - -fi - - -fi - - -fi - - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6 -echo "configure:4628: checking whether a program can dlopen itself" >&5 -if eval "test \"`echo '$''{'lt_cv_dlopen_self'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -} -EOF - if { (eval echo configure:4699: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self=no - fi -fi -rm -fr conftest* - - -fi - -echo "$ac_t""$lt_cv_dlopen_self" 1>&6 - - if test "x$lt_cv_dlopen_self" = xyes; then - LDFLAGS="$LDFLAGS $link_static_flag" - echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6 -echo "configure:4722: checking whether a statically linked program can dlopen itself" >&5 -if eval "test \"`echo '$''{'lt_cv_dlopen_self_static'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self_static=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -} -EOF - if { (eval echo configure:4793: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self_static=no - fi -fi -rm -fr conftest* - - -fi - -echo "$ac_t""$lt_cv_dlopen_self_static" 1>&6 - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi - - -if test "$enable_shared" = yes && test "$GCC" = yes; then - case $archive_cmds in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - echo $ac_n "checking whether -lc should be explicitly linked in""... $ac_c" 1>&6 -echo "configure:4842: checking whether -lc should be explicitly linked in" >&5 - if eval "test \"`echo '$''{'lt_cv_archive_cmds_need_lc'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - $rm conftest* - echo 'static int dummy;' > conftest.$ac_ext - - if { (eval echo configure:4849: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$lt_cv_prog_cc_wl - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - save_allow_undefined_flag=$allow_undefined_flag - allow_undefined_flag= - if { (eval echo configure:4862: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\") 1>&5; (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5; } - then - lt_cv_archive_cmds_need_lc=no - else - lt_cv_archive_cmds_need_lc=yes - fi - allow_undefined_flag=$save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi -fi - - echo "$ac_t""$lt_cv_archive_cmds_need_lc" 1>&6 - ;; - esac -fi -need_lc=${lt_cv_archive_cmds_need_lc-yes} - -# The second clause should only fire when bootstrapping the -# libtool distribution, otherwise you forgot to ship ltmain.sh -# with your package, and you will get complaints that there are -# no rules to generate ltmain.sh. -if test -f "$ltmain"; then - : -else - # If there is no Makefile yet, we rely on a make rule to execute - # `config.status --recheck' to rerun these tests and create the - # libtool script then. - test -f Makefile && make "$ltmain" -fi - -if test -f "$ltmain"; then - trap "$rm \"${ofile}T\"; exit 1" 1 2 15 - $rm -f "${ofile}T" - - echo creating $ofile - - # Now quote all the things that may contain metacharacters while being - # careful not to overquote the AC_SUBSTed values. We take copies of the - # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS SED \ - AR AR_FLAGS CC LD LN_S NM SHELL \ - reload_flag reload_cmds wl \ - pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \ - thread_safe_flag_spec whole_archive_flag_spec libname_spec \ - library_names_spec soname_spec \ - RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \ - old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds \ - postuninstall_cmds extract_expsyms_cmds old_archive_from_expsyms_cmds \ - old_striplib striplib file_magic_cmd export_symbols_cmds \ - deplibs_check_method allow_undefined_flag no_undefined_flag \ - finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \ - global_symbol_to_c_name_address \ - hardcode_libdir_flag_spec hardcode_libdir_separator \ - sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ - compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do - - case $var in - reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \ - old_postinstall_cmds | old_postuninstall_cmds | \ - export_symbols_cmds | archive_cmds | archive_expsym_cmds | \ - extract_expsyms_cmds | old_archive_from_expsyms_cmds | \ - postinstall_cmds | postuninstall_cmds | \ - finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) - # Double-quote double-evaled strings. - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" - ;; - *) - eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" - ;; - esac - done - - cat <<__EOF__ > "${ofile}T" -#! $SHELL - -# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -# Copyright (C) 1996-2000 Free Software Foundation, Inc. -# Originally by Gordon Matzigkeit , 1996 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# A sed that does not truncate output. -SED=$lt_SED - -# Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="${SED} -e s/^X//" - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -if test "X\${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi - -# ### BEGIN LIBTOOL CONFIG - -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$need_lc - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# The host system. -host_alias=$host_alias -host=$host - -# An echo program that does not interpret backslashes. -echo=$lt_echo - -# The archiver. -AR=$lt_AR -AR_FLAGS=$lt_AR_FLAGS - -# The default C compiler. -CC=$lt_CC - -# Is the compiler the GNU C compiler? -with_gcc=$GCC - -# The linker used to build libraries. -LD=$lt_LD - -# Whether we need hard or soft links. -LN_S=$lt_LN_S - -# A BSD-compatible nm program. -NM=$lt_NM - -# A symbol stripping program -STRIP=$STRIP - -# Used to examine libraries when file_magic_cmd begins "file" -MAGIC_CMD=$MAGIC_CMD - -# Used on cygwin: DLL creation program. -DLLTOOL="$DLLTOOL" - -# Used on cygwin: object dumper. -OBJDUMP="$OBJDUMP" - -# Used on cygwin: assembler. -AS="$AS" - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# How to pass a linker flag through the compiler. -wl=$lt_wl - -# Object file suffix (normally "o"). -objext="$ac_objext" - -# Old archive suffix (normally "a"). -libext="$libext" - -# Executable file suffix (normally ""). -exeext="$exeext" - -# Additional compiler flags for building library objects. -pic_flag=$lt_pic_flag -pic_mode=$pic_mode - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_compiler_c_o - -# Can we write directly to a .lo ? -compiler_o_lo=$lt_compiler_o_lo - -# Must we lock files when doing compilation ? -need_locks=$lt_need_locks - -# Do we need the lib prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_link_static_flag - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_no_builtin_flag - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec - -# Compiler flag to generate thread-safe objects. -thread_safe_flag_spec=$lt_thread_safe_flag_spec - -# Library versioning type. -version_type=$version_type - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME. -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Commands used to build and install an old-style archive. -RANLIB=$lt_RANLIB -old_archive_cmds=$lt_old_archive_cmds -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds - -# Commands used to build and install a shared archive. -archive_cmds=$lt_archive_cmds -archive_expsym_cmds=$lt_archive_expsym_cmds -postinstall_cmds=$lt_postinstall_cmds -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method == file_magic. -file_magic_cmd=$lt_file_magic_cmd - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag - -# Flag that forces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# Same as above, but a single script fragment to be evaled but not shown. -finish_eval=$lt_finish_eval - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_global_symbol_pipe - -# Transform the output of nm in a proper C declaration -global_symbol_to_cdecl=$lt_global_symbol_to_cdecl - -# Transform the output of nm in a C name address pair -global_symbol_to_c_name_address=$lt_global_symbol_to_c_name_address - -# This is the shared library runtime path variable. -runpath_var=$runpath_var - -# This is the shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec - -# Whether we need a single -rpath flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator - -# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the -# resulting binary. -hardcode_direct=$hardcode_direct - -# Set to yes if using the -LDIR flag during linking hardcodes DIR into the -# resulting binary. -hardcode_minus_L=$hardcode_minus_L - -# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into -# the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at relink time. -variables_saved_for_relink="$variables_saved_for_relink" - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs - -# Compile-time system search path for libraries -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Run-time system search path for libraries -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec - -# Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$fix_srcfile_path" - -# Set to yes if exported symbols are required. -always_export_symbols=$always_export_symbols - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms - -# ### END LIBTOOL CONFIG - -__EOF__ - - case $host_os in - aix3*) - cat <<\EOF >> "${ofile}T" - -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -EOF - ;; - esac - - case $host_os in - cygwin* | mingw* | pw32* | os2*) - cat <<'EOF' >> "${ofile}T" - # This is a source program that is used to create dlls on Windows - # Don't remove nor modify the starting and closing comments -# /* ltdll.c starts here */ -# #define WIN32_LEAN_AND_MEAN -# #include -# #undef WIN32_LEAN_AND_MEAN -# #include -# -# #ifndef __CYGWIN__ -# # ifdef __CYGWIN32__ -# # define __CYGWIN__ __CYGWIN32__ -# # endif -# #endif -# -# #ifdef __cplusplus -# extern "C" { -# #endif -# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); -# #ifdef __cplusplus -# } -# #endif -# -# #ifdef __CYGWIN__ -# #include -# DECLARE_CYGWIN_DLL( DllMain ); -# #endif -# HINSTANCE __hDllInstance_base; -# -# BOOL APIENTRY -# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) -# { -# __hDllInstance_base = hInst; -# return TRUE; -# } -# /* ltdll.c ends here */ - # This is a source program that is used to create import libraries - # on Windows for dlls which lack them. Don't remove nor modify the - # starting and closing comments -# /* impgen.c starts here */ -# /* Copyright (C) 1999-2000 Free Software Foundation, Inc. -# -# This file is part of GNU libtool. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# */ -# -# #include /* for printf() */ -# #include /* for open(), lseek(), read() */ -# #include /* for O_RDONLY, O_BINARY */ -# #include /* for strdup() */ -# -# /* O_BINARY isn't required (or even defined sometimes) under Unix */ -# #ifndef O_BINARY -# #define O_BINARY 0 -# #endif -# -# static unsigned int -# pe_get16 (fd, offset) -# int fd; -# int offset; -# { -# unsigned char b[2]; -# lseek (fd, offset, SEEK_SET); -# read (fd, b, 2); -# return b[0] + (b[1]<<8); -# } -# -# static unsigned int -# pe_get32 (fd, offset) -# int fd; -# int offset; -# { -# unsigned char b[4]; -# lseek (fd, offset, SEEK_SET); -# read (fd, b, 4); -# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); -# } -# -# static unsigned int -# pe_as32 (ptr) -# void *ptr; -# { -# unsigned char *b = ptr; -# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); -# } -# -# int -# main (argc, argv) -# int argc; -# char *argv[]; -# { -# int dll; -# unsigned long pe_header_offset, opthdr_ofs, num_entries, i; -# unsigned long export_rva, export_size, nsections, secptr, expptr; -# unsigned long name_rvas, nexp; -# unsigned char *expdata, *erva; -# char *filename, *dll_name; -# -# filename = argv[1]; -# -# dll = open(filename, O_RDONLY|O_BINARY); -# if (dll < 1) -# return 1; -# -# dll_name = filename; -# -# for (i=0; filename[i]; i++) -# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':') -# dll_name = filename + i +1; -# -# pe_header_offset = pe_get32 (dll, 0x3c); -# opthdr_ofs = pe_header_offset + 4 + 20; -# num_entries = pe_get32 (dll, opthdr_ofs + 92); -# -# if (num_entries < 1) /* no exports */ -# return 1; -# -# export_rva = pe_get32 (dll, opthdr_ofs + 96); -# export_size = pe_get32 (dll, opthdr_ofs + 100); -# nsections = pe_get16 (dll, pe_header_offset + 4 +2); -# secptr = (pe_header_offset + 4 + 20 + -# pe_get16 (dll, pe_header_offset + 4 + 16)); -# -# expptr = 0; -# for (i = 0; i < nsections; i++) -# { -# char sname[8]; -# unsigned long secptr1 = secptr + 40 * i; -# unsigned long vaddr = pe_get32 (dll, secptr1 + 12); -# unsigned long vsize = pe_get32 (dll, secptr1 + 16); -# unsigned long fptr = pe_get32 (dll, secptr1 + 20); -# lseek(dll, secptr1, SEEK_SET); -# read(dll, sname, 8); -# if (vaddr <= export_rva && vaddr+vsize > export_rva) -# { -# expptr = fptr + (export_rva - vaddr); -# if (export_rva + export_size > vaddr + vsize) -# export_size = vsize - (export_rva - vaddr); -# break; -# } -# } -# -# expdata = (unsigned char*)malloc(export_size); -# lseek (dll, expptr, SEEK_SET); -# read (dll, expdata, export_size); -# erva = expdata - export_rva; -# -# nexp = pe_as32 (expdata+24); -# name_rvas = pe_as32 (expdata+32); -# -# printf ("EXPORTS\n"); -# for (i = 0; i> "${ofile}T" || (rm -f "${ofile}T"; exit 1) - - mv -f "${ofile}T" "$ofile" || \ - (rm -f "$ofile" && cp "${ofile}T" "$ofile" && rm -f "${ofile}T") - chmod +x "$ofile" -fi - - - - - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' - -# Prevent multiple expansion - - - -echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6 -echo "configure:5448: checking whether byte ordering is bigendian" >&5 -if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_cv_c_bigendian=unknown -# See if sys/param.h defines the BYTE_ORDER macro. -cat > conftest.$ac_ext < -#include -int main() { - -#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN - bogus endian macros -#endif -; return 0; } -EOF -if { (eval echo configure:5466: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - # It does; now see whether it defined to BIG_ENDIAN or not. -cat > conftest.$ac_ext < -#include -int main() { - -#if BYTE_ORDER != BIG_ENDIAN - not big endian -#endif -; return 0; } -EOF -if { (eval echo configure:5481: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - ac_cv_c_bigendian=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - ac_cv_c_bigendian=no -fi -rm -f conftest* -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 -fi -rm -f conftest* -if test $ac_cv_c_bigendian = unknown; then -if test "$cross_compiling" = yes; then - { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } -else - cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null -then - ac_cv_c_bigendian=no -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -fr conftest* - ac_cv_c_bigendian=yes -fi -rm -fr conftest* -fi - -fi -fi - -echo "$ac_t""$ac_cv_c_bigendian" 1>&6 -if test $ac_cv_c_bigendian = yes; then - cat >> confdefs.h <<\EOF -#define WORDS_BIGENDIAN 1 -EOF - -fi - -for ac_hdr in sys/soundcard.h -do -ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` -echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:5541: checking for $ac_hdr" >&5 -if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:5551: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - rm -rf conftest* - eval "ac_cv_header_$ac_safe=yes" -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_header_$ac_safe=no" -fi -rm -f conftest* -fi -if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` - cat >> confdefs.h <&6 -fi -done - - -# Check whether --enable-ogg or --disable-ogg was given. -if test "${enable_ogg+set}" = set; then - enableval="$enable_ogg" - case "${enableval}" in - yes) useogg=true ;; - no) useogg=false ;; - *) { echo "configure: error: bad value ${enableval} for --enable-ogg" 1>&2; exit 1; } ;; - esac -else - useogg=true -fi - - -if test x$useogg = xtrue; then - -OGG_LIBS="-logg" - -echo $ac_n "checking for libogg""... $ac_c" 1>&6 -echo "configure:5596: checking for libogg" >&5 - -ac_ogg_includes=NONE ac_ogg_libraries=NONE ac_ogg_bindir=NONE -ogg_libraries="" -ogg_includes="" -# Check whether --with-ogg-dir or --without-ogg-dir was given. -if test "${with_ogg_dir+set}" = set; then - withval="$with_ogg_dir" - ac_ogg_includes="$withval"/include - ac_ogg_libraries="$withval"/lib - -fi - - -# Check whether --with-ogg-includes or --without-ogg-includes was given. -if test "${with_ogg_includes+set}" = set; then - withval="$with_ogg_includes" - - ac_ogg_includes="$withval" - -fi - - -ogg_libs_given=no - -# Check whether --with-ogg-libraries or --without-ogg-libraries was given. -if test "${with_ogg_libraries+set}" = set; then - withval="$with_ogg_libraries" - ac_ogg_libraries="$withval" - ogg_libs_given=yes - -fi - - -ogg_incdirs="/usr/include /usr/lib/ogg/include /opt/include /usr/local/ogg/include /usr/include/ogg /usr/include /usr/local/include" -if test ! "$ac_ogg_includes" = "NONE"; then - ogg_incdirs="$ac_ogg_includes $ac_ogg_includes/.. $ogg_incdirs" -fi - -ogg_incdir=NONE -for i in $ogg_incdirs; -do - for j in ogg/ogg.h; - do - if test -r "$i/$j"; then - ogg_incdir=$i - break 2 - fi - done -done - -echo "Ogg includes in $ogg_incdir" - - -ogg_libdirs="$ac_ogg_libraries /usr/lib/ogg/lib /usr/lib /opt/lib /usr/local/ogg/lib /usr/local/lib /usr/lib/ogg /usr/local/lib" -test -n "$OGGDIR" && ogg_libdirs="$OGGDIR/lib $OGGDIR $ogg_libdirs" -if test ! "$ac_ogg_libraries" = "NONE"; then - ogg_libdirs="$ac_ogg_libraries $ogg_libdirs" -fi - -test=NONE -ogg_libdir=NONE -for dir in $ogg_libdirs; do - try="ls -1 $dir/libogg*" - if test=`eval $try 2> /dev/null`; then ogg_libdir=$dir; break; else echo "tried $dir" >&5 ; fi -done - -echo "Ogg libraries in $ogg_libdir" - -if test "$ogg_libdir" = "NONE" || test "$ogg_incdir" = "NONE"; then - have_libogg=no -else - have_libogg=yes - cat >> confdefs.h <<\EOF -#define HAVE_LIBOGG 1 -EOF - -fi - -OGG_INCLUDES="-I$ogg_incdir" -OGG_LDFLAGS="-L$ogg_libdir" - - - - - - - -fi - -if test "$have_libogg" = yes; then - src=src -else - src= -fi - - -echo $ac_n "checking for sin in -lm""... $ac_c" 1>&6 -echo "configure:5694: checking for sin in -lm" >&5 -ac_lib_var=`echo m'_'sin | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-lm $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_tr_lib=HAVE_LIB`echo m | sed -e 's/[^a-zA-Z0-9_]/_/g' \ - -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` - cat >> confdefs.h <&6 -fi - -echo $ac_n "checking for getopt_long in -lgnugetopt""... $ac_c" 1>&6 -echo "configure:5741: checking for getopt_long in -lgnugetopt" >&5 -ac_lib_var=`echo gnugetopt'_'getopt_long | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-lgnugetopt $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_tr_lib=HAVE_LIB`echo gnugetopt | sed -e 's/[^a-zA-Z0-9_]/_/g' \ - -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'` - cat >> confdefs.h <&6 -fi - - -cat >> confdefs.h <> confdefs.h <<\EOF -#define _USE_SSE 1 -EOF - fi -fi - - - -trap '' 1 2 15 -cat > confcache <<\EOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs. It is not useful on other systems. -# If it contains results you don't want to keep, you may remove or edit it. -# -# By default, configure uses ./config.cache as the cache file, -# creating it if it does not exist already. You can give configure -# the --cache-file=FILE option to use a different cache file; that is -# what configure does when it calls configure scripts in -# subdirectories, so they share the cache. -# Giving --cache-file=/dev/null disables caching, for debugging configure. -# config.status only pays attention to the cache file if you give it the -# --recheck option to rerun configure. -# -EOF -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, don't put newlines in cache variables' values. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -(set) 2>&1 | - case `(ac_space=' '; set | grep ac_space) 2>&1` in - *ac_space=\ *) - # `set' does not quote correctly, so add quotes (double-quote substitution - # turns \\\\ into \\, and sed turns \\ into \). - sed -n \ - -e "s/'/'\\\\''/g" \ - -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" - ;; - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' - ;; - esac >> confcache -if cmp -s $cache_file confcache; then - : -else - if test -w $cache_file; then - echo "updating cache $cache_file" - cat confcache > $cache_file - else - echo "not updating unwritable cache $cache_file" - fi -fi -rm -f confcache - -trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -# Any assignment to VPATH causes Sun make to only execute -# the first set of double-colon rules, so remove it if not needed. -# If there is a colon in the path, we need to keep it. -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' -fi - -trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 - -# Transform confdefs.h into DEFS. -# Protect against shell expansion while executing Makefile rules. -# Protect against Makefile macro expansion. -cat > conftest.defs <<\EOF -s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g -s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g -s%\[%\\&%g -s%\]%\\&%g -s%\$%$$%g -EOF -DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` -rm -f conftest.defs - - -# Without the "./", some shells look in PATH for config.status. -: ${CONFIG_STATUS=./config.status} - -echo creating $CONFIG_STATUS -rm -f $CONFIG_STATUS -cat > $CONFIG_STATUS </dev/null | sed 1q`: -# -# $0 $ac_configure_args -# -# Compiler output produced by configure, useful for debugging -# configure, is in ./config.log if it exists. - -ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" -for ac_option -do - case "\$ac_option" in - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" - exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; - -version | --version | --versio | --versi | --vers | --ver | --ve | --v) - echo "$CONFIG_STATUS generated by autoconf version 2.13" - exit 0 ;; - -help | --help | --hel | --he | --h) - echo "\$ac_cs_usage"; exit 0 ;; - *) echo "\$ac_cs_usage"; exit 1 ;; - esac -done - -ac_given_srcdir=$srcdir -ac_given_INSTALL="$INSTALL" - -trap 'rm -fr `echo "Makefile libspeex/Makefile src/Makefile doc/Makefile Speex.spec - win32/Makefile win32/libspeex/Makefile win32/speexenc/Makefile - win32/speexdec/Makefile " | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 -EOF -cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF -$ac_vpsub -$extrasub -s%@SHELL@%$SHELL%g -s%@CFLAGS@%$CFLAGS%g -s%@CPPFLAGS@%$CPPFLAGS%g -s%@CXXFLAGS@%$CXXFLAGS%g -s%@FFLAGS@%$FFLAGS%g -s%@DEFS@%$DEFS%g -s%@LDFLAGS@%$LDFLAGS%g -s%@LIBS@%$LIBS%g -s%@exec_prefix@%$exec_prefix%g -s%@prefix@%$prefix%g -s%@program_transform_name@%$program_transform_name%g -s%@bindir@%$bindir%g -s%@sbindir@%$sbindir%g -s%@libexecdir@%$libexecdir%g -s%@datadir@%$datadir%g -s%@sysconfdir@%$sysconfdir%g -s%@sharedstatedir@%$sharedstatedir%g -s%@localstatedir@%$localstatedir%g -s%@libdir@%$libdir%g -s%@includedir@%$includedir%g -s%@oldincludedir@%$oldincludedir%g -s%@infodir@%$infodir%g -s%@mandir@%$mandir%g -s%@SPEEX_LT_CURRENT@%$SPEEX_LT_CURRENT%g -s%@SPEEX_LT_REVISION@%$SPEEX_LT_REVISION%g -s%@SPEEX_LT_AGE@%$SPEEX_LT_AGE%g -s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g -s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g -s%@INSTALL_DATA@%$INSTALL_DATA%g -s%@PACKAGE@%$PACKAGE%g -s%@VERSION@%$VERSION%g -s%@ACLOCAL@%$ACLOCAL%g -s%@AUTOCONF@%$AUTOCONF%g -s%@AUTOMAKE@%$AUTOMAKE%g -s%@AUTOHEADER@%$AUTOHEADER%g -s%@MAKEINFO@%$MAKEINFO%g -s%@SET_MAKE@%$SET_MAKE%g -s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g -s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g -s%@MAINT@%$MAINT%g -s%@host@%$host%g -s%@host_alias@%$host_alias%g -s%@host_cpu@%$host_cpu%g -s%@host_vendor@%$host_vendor%g -s%@host_os@%$host_os%g -s%@build@%$build%g -s%@build_alias@%$build_alias%g -s%@build_cpu@%$build_cpu%g -s%@build_vendor@%$build_vendor%g -s%@build_os@%$build_os%g -s%@CC@%$CC%g -s%@LN_S@%$LN_S%g -s%@OBJEXT@%$OBJEXT%g -s%@EXEEXT@%$EXEEXT%g -s%@ECHO@%$ECHO%g -s%@RANLIB@%$RANLIB%g -s%@STRIP@%$STRIP%g -s%@CPP@%$CPP%g -s%@LIBTOOL@%$LIBTOOL%g -s%@OGG_LIBS@%$OGG_LIBS%g -s%@OGG_INCLUDES@%$OGG_INCLUDES%g -s%@OGG_LDFLAGS@%$OGG_LDFLAGS%g -s%@src@%$src%g - -CEOF -EOF - -cat >> $CONFIG_STATUS <<\EOF - -# Split the substitutions into bite-sized pieces for seds with -# small command number limits, like on Digital OSF/1 and HP-UX. -ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. -ac_file=1 # Number of current file. -ac_beg=1 # First line for current file. -ac_end=$ac_max_sed_cmds # Line after last line for current file. -ac_more_lines=: -ac_sed_cmds="" -while $ac_more_lines; do - if test $ac_beg -gt 1; then - sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file - else - sed "${ac_end}q" conftest.subs > conftest.s$ac_file - fi - if test ! -s conftest.s$ac_file; then - ac_more_lines=false - rm -f conftest.s$ac_file - else - if test -z "$ac_sed_cmds"; then - ac_sed_cmds="sed -f conftest.s$ac_file" - else - ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" - fi - ac_file=`expr $ac_file + 1` - ac_beg=$ac_end - ac_end=`expr $ac_end + $ac_max_sed_cmds` - fi -done -if test -z "$ac_sed_cmds"; then - ac_sed_cmds=cat -fi -EOF - -cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF -for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then - # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". - case "$ac_file" in - *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` - ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; - *) ac_file_in="${ac_file}.in" ;; - esac - - # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. - - # Remove last slash and all that follows it. Not all systems have dirname. - ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` - if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then - # The file is in a subdirectory. - test ! -d "$ac_dir" && mkdir "$ac_dir" - ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" - # A "../" for each directory in $ac_dir_suffix. - ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` - else - ac_dir_suffix= ac_dots= - fi - - case "$ac_given_srcdir" in - .) srcdir=. - if test -z "$ac_dots"; then top_srcdir=. - else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; - /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; - *) # Relative path. - srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" - top_srcdir="$ac_dots$ac_given_srcdir" ;; - esac - - case "$ac_given_INSTALL" in - [/$]*) INSTALL="$ac_given_INSTALL" ;; - *) INSTALL="$ac_dots$ac_given_INSTALL" ;; - esac - - echo creating "$ac_file" - rm -f "$ac_file" - configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." - case "$ac_file" in - *Makefile*) ac_comsub="1i\\ -# $configure_input" ;; - *) ac_comsub= ;; - esac - - ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` - sed -e "$ac_comsub -s%@configure_input@%$configure_input%g -s%@srcdir@%$srcdir%g -s%@top_srcdir@%$top_srcdir%g -s%@INSTALL@%$INSTALL%g -" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file -fi; done -rm -f conftest.s* - -EOF -cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF - -exit 0 -EOF -chmod +x $CONFIG_STATUS -rm -fr confdefs* $ac_clean_files -test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 - - -if test "x$src" = "x"; then -echo "You don't seem to have libogg installed. Only the Speex library (libspeex) will be built (no encoder/decoder executable)" -echo "You can download libogg from http://www.ogg.org/ogg/index.html" -fi - -echo "Type \"make; make install\" to compile and install Speex"; diff --git a/engine/voice_codecs/speex/source/configure.in b/engine/voice_codecs/speex/source/configure.in deleted file mode 100644 index 77d63747..00000000 --- a/engine/voice_codecs/speex/source/configure.in +++ /dev/null @@ -1,69 +0,0 @@ -dnl Process this file with autoconf to produce a configure script. -*-m4-*- - -AC_INIT(libspeex/speex.h) - -SPEEX_MAJOR_VERSION=1 -SPEEX_MINOR_VERSION=0 -SPEEX_MICRO_VERSION=1 -SPEEX_VERSION=1.0.1 - -SPEEX_LT_CURRENT=2 -SPEEX_LT_REVISION=0 -SPEEX_LT_AGE=1 - -AC_SUBST(SPEEX_LT_CURRENT) -AC_SUBST(SPEEX_LT_REVISION) -AC_SUBST(SPEEX_LT_AGE) - -# For automake. -VERSION=$SPEEX_VERSION -PACKAGE=speex - -AM_INIT_AUTOMAKE($PACKAGE, $VERSION, no-define) -AM_MAINTAINER_MODE - -AC_CANONICAL_HOST -AM_PROG_LIBTOOL - -AC_C_BIGENDIAN -AC_CHECK_HEADERS(sys/soundcard.h) - -AC_ARG_ENABLE(ogg, - [ --enable-ogg=[yes/no] Turn on or off the use of ogg -libraries [default=yes]], - [case "${enableval}" in - yes) useogg=true ;; - no) useogg=false ;; - *) AC_MSG_ERROR(bad value ${enableval} for --enable-ogg) ;; - esac],[useogg=true]) - -if test x$useogg = xtrue; then -AC_PATH_LIBOGG -fi - -if test "$have_libogg" = yes; then - src=src -else - src= -fi -AC_SUBST(src) - -AC_CHECK_LIB(m, sin) -AC_CHECK_LIB(gnugetopt, getopt_long) - -AC_DEFINE_UNQUOTED(VERSION, "${VERSION}") - -AC_ARG_ENABLE(sse, [ --enable-sse enable SSE support], [if test "$enableval" = yes; then AC_DEFINE(_USE_SSE) fi]) - -dnl Output the makefiles and version.h. - -AC_OUTPUT([Makefile libspeex/Makefile src/Makefile doc/Makefile Speex.spec - win32/Makefile win32/libspeex/Makefile win32/speexenc/Makefile - win32/speexdec/Makefile ]) - -if test "x$src" = "x"; then -echo "You don't seem to have libogg installed. Only the Speex library (libspeex) will be built (no encoder/decoder executable)" -echo "You can download libogg from http://www.ogg.org/ogg/index.html" -fi - -echo "Type \"make; make install\" to compile and install Speex"; diff --git a/engine/voice_codecs/speex/source/doc/Makefile.am b/engine/voice_codecs/speex/source/doc/Makefile.am deleted file mode 100644 index a70a97b3..00000000 --- a/engine/voice_codecs/speex/source/doc/Makefile.am +++ /dev/null @@ -1,5 +0,0 @@ -docdir=$(prefix)/share/doc/@PACKAGE@-@VERSION@ - -doc_DATA = manual.pdf - -EXTRA_DIST = $(doc_DATA) diff --git a/engine/voice_codecs/speex/source/doc/Makefile.in b/engine/voice_codecs/speex/source/doc/Makefile.in deleted file mode 100644 index 6e02880b..00000000 --- a/engine/voice_codecs/speex/source/doc/Makefile.in +++ /dev/null @@ -1,213 +0,0 @@ -# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am - -# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - - -SHELL = @SHELL@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ - -bindir = @bindir@ -sbindir = @sbindir@ -libexecdir = @libexecdir@ -datadir = @datadir@ -sysconfdir = @sysconfdir@ -sharedstatedir = @sharedstatedir@ -localstatedir = @localstatedir@ -libdir = @libdir@ -infodir = @infodir@ -mandir = @mandir@ -includedir = @includedir@ -oldincludedir = /usr/include - -DESTDIR = - -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ - -top_builddir = .. - -ACLOCAL = @ACLOCAL@ -AUTOCONF = @AUTOCONF@ -AUTOMAKE = @AUTOMAKE@ -AUTOHEADER = @AUTOHEADER@ - -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -transform = @program_transform_name@ - -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -host_alias = @host_alias@ -host_triplet = @host@ -AS = @AS@ -CC = @CC@ -DLLTOOL = @DLLTOOL@ -ECHO = @ECHO@ -EXEEXT = @EXEEXT@ -LIBTOOL = @LIBTOOL@ -LN_S = @LN_S@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OGG_INCLUDES = @OGG_INCLUDES@ -OGG_LDFLAGS = @OGG_LDFLAGS@ -OGG_LIBS = @OGG_LIBS@ -PACKAGE = @PACKAGE@ -RANLIB = @RANLIB@ -SPEEX_LT_AGE = @SPEEX_LT_AGE@ -SPEEX_LT_CURRENT = @SPEEX_LT_CURRENT@ -SPEEX_LT_REVISION = @SPEEX_LT_REVISION@ -STRIP = @STRIP@ -VERSION = @VERSION@ -src = @src@ - -docdir = $(prefix)/share/doc/@PACKAGE@-@VERSION@ - -doc_DATA = manual.pdf - -EXTRA_DIST = $(doc_DATA) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_CLEAN_FILES = -DATA = $(doc_DATA) - -DIST_COMMON = Makefile.am Makefile.in - - -DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) - -TAR = gtar -GZIP_ENV = --best -all: all-redirect -.SUFFIXES: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps doc/Makefile - -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - cd $(top_builddir) \ - && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status - - -install-docDATA: $(doc_DATA) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(docdir) - @list='$(doc_DATA)'; for p in $$list; do \ - if test -f $(srcdir)/$$p; then \ - echo " $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(docdir)/$$p"; \ - $(INSTALL_DATA) $(srcdir)/$$p $(DESTDIR)$(docdir)/$$p; \ - else if test -f $$p; then \ - echo " $(INSTALL_DATA) $$p $(DESTDIR)$(docdir)/$$p"; \ - $(INSTALL_DATA) $$p $(DESTDIR)$(docdir)/$$p; \ - fi; fi; \ - done - -uninstall-docDATA: - @$(NORMAL_UNINSTALL) - list='$(doc_DATA)'; for p in $$list; do \ - rm -f $(DESTDIR)$(docdir)/$$p; \ - done -tags: TAGS -TAGS: - - -distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) - -subdir = doc - -distdir: $(DISTFILES) - @for file in $(DISTFILES); do \ - d=$(srcdir); \ - if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(distdir)/$$file; \ - else \ - test -f $(distdir)/$$file \ - || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ - || cp -p $$d/$$file $(distdir)/$$file || :; \ - fi; \ - done -info-am: -info: info-am -dvi-am: -dvi: dvi-am -check-am: all-am -check: check-am -installcheck-am: -installcheck: installcheck-am -install-exec-am: -install-exec: install-exec-am - -install-data-am: install-docDATA -install-data: install-data-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -install: install-am -uninstall-am: uninstall-docDATA -uninstall: uninstall-am -all-am: Makefile $(DATA) -all-redirect: all-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install -installdirs: - $(mkinstalldirs) $(DESTDIR)$(docdir) - - -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) - -rm -f config.cache config.log stamp-h stamp-h[0-9]* - -maintainer-clean-generic: -mostlyclean-am: mostlyclean-generic - -mostlyclean: mostlyclean-am - -clean-am: clean-generic mostlyclean-am - -clean: clean-am - -distclean-am: distclean-generic clean-am - -rm -f libtool - -distclean: distclean-am - -maintainer-clean-am: maintainer-clean-generic distclean-am - @echo "This command is intended for maintainers to use;" - @echo "it deletes files that may require special tools to rebuild." - -maintainer-clean: maintainer-clean-am - -.PHONY: uninstall-docDATA install-docDATA tags distdir info-am info \ -dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ -install-exec install-data-am install-data install-am install \ -uninstall-am uninstall all-redirect all-am all installdirs \ -mostlyclean-generic distclean-generic clean-generic \ -maintainer-clean-generic clean mostlyclean distclean maintainer-clean - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/engine/voice_codecs/speex/source/doc/manual.pdf b/engine/voice_codecs/speex/source/doc/manual.pdf deleted file mode 100644 index 8a076c44..00000000 Binary files a/engine/voice_codecs/speex/source/doc/manual.pdf and /dev/null differ diff --git a/engine/voice_codecs/speex/source/install-sh b/engine/voice_codecs/speex/source/install-sh deleted file mode 100644 index e9de2384..00000000 --- a/engine/voice_codecs/speex/source/install-sh +++ /dev/null @@ -1,251 +0,0 @@ -#!/bin/sh -# -# install - install a program, script, or datafile -# This comes from X11R5 (mit/util/scripts/install.sh). -# -# Copyright 1991 by the Massachusetts Institute of Technology -# -# Permission to use, copy, modify, distribute, and sell this software and its -# documentation for any purpose is hereby granted without fee, provided that -# the above copyright notice appear in all copies and that both that -# copyright notice and this permission notice appear in supporting -# documentation, and that the name of M.I.T. not be used in advertising or -# publicity pertaining to distribution of the software without specific, -# written prior permission. M.I.T. makes no representations about the -# suitability of this software for any purpose. It is provided "as is" -# without express or implied warranty. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# `make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. It can only install one file at a time, a restriction -# shared with many OS's install programs. - - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit="${DOITPROG-}" - - -# put in absolute paths if you don't have them in your path; or use env. vars. - -mvprog="${MVPROG-mv}" -cpprog="${CPPROG-cp}" -chmodprog="${CHMODPROG-chmod}" -chownprog="${CHOWNPROG-chown}" -chgrpprog="${CHGRPPROG-chgrp}" -stripprog="${STRIPPROG-strip}" -rmprog="${RMPROG-rm}" -mkdirprog="${MKDIRPROG-mkdir}" - -transformbasename="" -transform_arg="" -instcmd="$mvprog" -chmodcmd="$chmodprog 0755" -chowncmd="" -chgrpcmd="" -stripcmd="" -rmcmd="$rmprog -f" -mvcmd="$mvprog" -src="" -dst="" -dir_arg="" - -while [ x"$1" != x ]; do - case $1 in - -c) instcmd="$cpprog" - shift - continue;; - - -d) dir_arg=true - shift - continue;; - - -m) chmodcmd="$chmodprog $2" - shift - shift - continue;; - - -o) chowncmd="$chownprog $2" - shift - shift - continue;; - - -g) chgrpcmd="$chgrpprog $2" - shift - shift - continue;; - - -s) stripcmd="$stripprog" - shift - continue;; - - -t=*) transformarg=`echo $1 | sed 's/-t=//'` - shift - continue;; - - -b=*) transformbasename=`echo $1 | sed 's/-b=//'` - shift - continue;; - - *) if [ x"$src" = x ] - then - src=$1 - else - # this colon is to work around a 386BSD /bin/sh bug - : - dst=$1 - fi - shift - continue;; - esac -done - -if [ x"$src" = x ] -then - echo "install: no input file specified" - exit 1 -else - true -fi - -if [ x"$dir_arg" != x ]; then - dst=$src - src="" - - if [ -d $dst ]; then - instcmd=: - chmodcmd="" - else - instcmd=mkdir - fi -else - -# Waiting for this to be detected by the "$instcmd $src $dsttmp" command -# might cause directories to be created, which would be especially bad -# if $src (and thus $dsttmp) contains '*'. - - if [ -f $src -o -d $src ] - then - true - else - echo "install: $src does not exist" - exit 1 - fi - - if [ x"$dst" = x ] - then - echo "install: no destination specified" - exit 1 - else - true - fi - -# If destination is a directory, append the input filename; if your system -# does not like double slashes in filenames, you may need to add some logic - - if [ -d $dst ] - then - dst="$dst"/`basename $src` - else - true - fi -fi - -## this sed command emulates the dirname command -dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` - -# Make sure that the destination directory exists. -# this part is taken from Noah Friedman's mkinstalldirs script - -# Skip lots of stat calls in the usual case. -if [ ! -d "$dstdir" ]; then -defaultIFS=' -' -IFS="${IFS-${defaultIFS}}" - -oIFS="${IFS}" -# Some sh's can't handle IFS=/ for some reason. -IFS='%' -set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` -IFS="${oIFS}" - -pathcomp='' - -while [ $# -ne 0 ] ; do - pathcomp="${pathcomp}${1}" - shift - - if [ ! -d "${pathcomp}" ] ; - then - $mkdirprog "${pathcomp}" - else - true - fi - - pathcomp="${pathcomp}/" -done -fi - -if [ x"$dir_arg" != x ] -then - $doit $instcmd $dst && - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi -else - -# If we're going to rename the final executable, determine the name now. - - if [ x"$transformarg" = x ] - then - dstfile=`basename $dst` - else - dstfile=`basename $dst $transformbasename | - sed $transformarg`$transformbasename - fi - -# don't allow the sed command to completely eliminate the filename - - if [ x"$dstfile" = x ] - then - dstfile=`basename $dst` - else - true - fi - -# Make a temp file name in the proper directory. - - dsttmp=$dstdir/#inst.$$# - -# Move or copy the file name to the temp name - - $doit $instcmd $src $dsttmp && - - trap "rm -f ${dsttmp}" 0 && - -# and set any options; do chmod last to preserve setuid bits - -# If any of these fail, we abort the whole thing. If we want to -# ignore errors from any of these, just make sure not to ignore -# errors from the above "$doit $instcmd $src $dsttmp" command. - - if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && - if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && - if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && - if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && - -# Now rename the file to the real destination. - - $doit $rmcmd -f $dstdir/$dstfile && - $doit $mvcmd $dsttmp $dstdir/$dstfile - -fi && - - -exit 0 diff --git a/engine/voice_codecs/speex/source/libspeex/Makefile.am b/engine/voice_codecs/speex/source/libspeex/Makefile.am deleted file mode 100644 index 940bc379..00000000 --- a/engine/voice_codecs/speex/source/libspeex/Makefile.am +++ /dev/null @@ -1,77 +0,0 @@ -## Process this file with automake to produce Makefile.in. -*-Makefile-*- - -# $Id: Makefile.am,v 1.49 2003/03/17 22:40:57 jm Exp $ - -# Disable automatic dependency tracking if using other tools than gcc and gmake -#AUTOMAKE_OPTIONS = no-dependencies - -lib_LTLIBRARIES = libspeex.la - -# Sources for compilation in the library -libspeex_la_SOURCES = nb_celp.c \ - sb_celp.c \ - lpc.c \ - ltp.c \ - lsp.c \ - quant_lsp.c \ - lsp_tables_nb.c \ - gain_table.c \ - gain_table_lbr.c \ - cb_search.c \ - filters.c \ - bits.c \ - modes.c \ - vq.c \ - high_lsp_tables.c \ - vbr.c \ - hexc_table.c \ - exc_5_256_table.c \ - exc_5_64_table.c \ - exc_8_128_table.c \ - exc_10_32_table.c \ - exc_10_16_table.c \ - exc_20_32_table.c \ - hexc_10_32_table.c \ - misc.c \ - speex_header.c \ - speex_callbacks.c \ - math_approx.c \ - stereo.c - - -include_HEADERS = speex.h \ - speex_bits.h \ - speex_header.h \ - speex_callbacks.h \ - speex_stereo.h - -noinst_HEADERS = lsp.h \ - nb_celp.h \ - lpc.h \ - ltp.h \ - quant_lsp.h \ - cb_search.h \ - filters.h \ - stack_alloc.h \ - vq.h \ - modes.h \ - sb_celp.h \ - vbr.h \ - misc.h \ - ltp_sse.h \ - filters_sse.h \ - math_approx.h - - -libspeex_la_LDFLAGS = -version-info @SPEEX_LT_CURRENT@:@SPEEX_LT_REVISION@:@SPEEX_LT_AGE@ - -noinst_PROGRAMS = testenc testenc_wb testenc_uwb - -testenc_SOURCES = testenc.c -testenc_LDADD = libspeex.la - -testenc_wb_SOURCES = testenc_wb.c -testenc_wb_LDADD = libspeex.la - -testenc_uwb_SOURCES = testenc_uwb.c -testenc_uwb_LDADD = libspeex.la diff --git a/engine/voice_codecs/speex/source/libspeex/Makefile.in b/engine/voice_codecs/speex/source/libspeex/Makefile.in deleted file mode 100644 index b4e2a5f7..00000000 --- a/engine/voice_codecs/speex/source/libspeex/Makefile.in +++ /dev/null @@ -1,450 +0,0 @@ -# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am - -# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. -# This Makefile.in is free software; the Free Software Foundation -# gives unlimited permission to copy and/or distribute it, -# with or without modifications, as long as this notice is preserved. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY, to the extent permitted by law; without -# even the implied warranty of MERCHANTABILITY or FITNESS FOR A -# PARTICULAR PURPOSE. - -# $Id: Makefile.am,v 1.49 2003/03/17 22:40:57 jm Exp $ - -# Disable automatic dependency tracking if using other tools than gcc and gmake -#AUTOMAKE_OPTIONS = no-dependencies - - -SHELL = @SHELL@ - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ -VPATH = @srcdir@ -prefix = @prefix@ -exec_prefix = @exec_prefix@ - -bindir = @bindir@ -sbindir = @sbindir@ -libexecdir = @libexecdir@ -datadir = @datadir@ -sysconfdir = @sysconfdir@ -sharedstatedir = @sharedstatedir@ -localstatedir = @localstatedir@ -libdir = @libdir@ -infodir = @infodir@ -mandir = @mandir@ -includedir = @includedir@ -oldincludedir = /usr/include - -DESTDIR = - -pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ -pkgincludedir = $(includedir)/@PACKAGE@ - -top_builddir = .. - -ACLOCAL = @ACLOCAL@ -AUTOCONF = @AUTOCONF@ -AUTOMAKE = @AUTOMAKE@ -AUTOHEADER = @AUTOHEADER@ - -INSTALL = @INSTALL@ -INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) -INSTALL_DATA = @INSTALL_DATA@ -INSTALL_SCRIPT = @INSTALL_SCRIPT@ -transform = @program_transform_name@ - -NORMAL_INSTALL = : -PRE_INSTALL = : -POST_INSTALL = : -NORMAL_UNINSTALL = : -PRE_UNINSTALL = : -POST_UNINSTALL = : -host_alias = @host_alias@ -host_triplet = @host@ -AS = @AS@ -CC = @CC@ -DLLTOOL = @DLLTOOL@ -ECHO = @ECHO@ -EXEEXT = @EXEEXT@ -LIBTOOL = @LIBTOOL@ -LN_S = @LN_S@ -MAINT = @MAINT@ -MAKEINFO = @MAKEINFO@ -OBJDUMP = @OBJDUMP@ -OBJEXT = @OBJEXT@ -OGG_INCLUDES = @OGG_INCLUDES@ -OGG_LDFLAGS = @OGG_LDFLAGS@ -OGG_LIBS = @OGG_LIBS@ -PACKAGE = @PACKAGE@ -RANLIB = @RANLIB@ -SPEEX_LT_AGE = @SPEEX_LT_AGE@ -SPEEX_LT_CURRENT = @SPEEX_LT_CURRENT@ -SPEEX_LT_REVISION = @SPEEX_LT_REVISION@ -STRIP = @STRIP@ -VERSION = @VERSION@ -src = @src@ - -lib_LTLIBRARIES = libspeex.la - -# Sources for compilation in the library -libspeex_la_SOURCES = nb_celp.c sb_celp.c lpc.c ltp.c lsp.c quant_lsp.c lsp_tables_nb.c gain_table.c gain_table_lbr.c cb_search.c filters.c bits.c modes.c vq.c high_lsp_tables.c vbr.c hexc_table.c exc_5_256_table.c exc_5_64_table.c exc_8_128_table.c exc_10_32_table.c exc_10_16_table.c exc_20_32_table.c hexc_10_32_table.c misc.c speex_header.c speex_callbacks.c math_approx.c stereo.c - - -include_HEADERS = speex.h speex_bits.h speex_header.h speex_callbacks.h speex_stereo.h - - -noinst_HEADERS = lsp.h nb_celp.h lpc.h ltp.h quant_lsp.h cb_search.h filters.h stack_alloc.h vq.h modes.h sb_celp.h vbr.h misc.h ltp_sse.h filters_sse.h math_approx.h - - -libspeex_la_LDFLAGS = -version-info @SPEEX_LT_CURRENT@:@SPEEX_LT_REVISION@:@SPEEX_LT_AGE@ - -noinst_PROGRAMS = testenc testenc_wb testenc_uwb - -testenc_SOURCES = testenc.c -testenc_LDADD = libspeex.la - -testenc_wb_SOURCES = testenc_wb.c -testenc_wb_LDADD = libspeex.la - -testenc_uwb_SOURCES = testenc_uwb.c -testenc_uwb_LDADD = libspeex.la -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_CLEAN_FILES = -LTLIBRARIES = $(lib_LTLIBRARIES) - - -DEFS = @DEFS@ -I. -I$(srcdir) -CPPFLAGS = @CPPFLAGS@ -LDFLAGS = @LDFLAGS@ -LIBS = @LIBS@ -libspeex_la_LIBADD = -libspeex_la_OBJECTS = nb_celp.lo sb_celp.lo lpc.lo ltp.lo lsp.lo \ -quant_lsp.lo lsp_tables_nb.lo gain_table.lo gain_table_lbr.lo \ -cb_search.lo filters.lo bits.lo modes.lo vq.lo high_lsp_tables.lo \ -vbr.lo hexc_table.lo exc_5_256_table.lo exc_5_64_table.lo \ -exc_8_128_table.lo exc_10_32_table.lo exc_10_16_table.lo \ -exc_20_32_table.lo hexc_10_32_table.lo misc.lo speex_header.lo \ -speex_callbacks.lo math_approx.lo stereo.lo -noinst_PROGRAMS = testenc$(EXEEXT) testenc_wb$(EXEEXT) \ -testenc_uwb$(EXEEXT) -PROGRAMS = $(noinst_PROGRAMS) - -testenc_OBJECTS = testenc.$(OBJEXT) -testenc_DEPENDENCIES = libspeex.la -testenc_LDFLAGS = -testenc_wb_OBJECTS = testenc_wb.$(OBJEXT) -testenc_wb_DEPENDENCIES = libspeex.la -testenc_wb_LDFLAGS = -testenc_uwb_OBJECTS = testenc_uwb.$(OBJEXT) -testenc_uwb_DEPENDENCIES = libspeex.la -testenc_uwb_LDFLAGS = -CFLAGS = @CFLAGS@ -COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -CCLD = $(CC) -LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ -HEADERS = $(include_HEADERS) $(noinst_HEADERS) - -DIST_COMMON = Makefile.am Makefile.in - - -DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) - -TAR = gtar -GZIP_ENV = --best -SOURCES = $(libspeex_la_SOURCES) $(testenc_SOURCES) $(testenc_wb_SOURCES) $(testenc_uwb_SOURCES) -OBJECTS = $(libspeex_la_OBJECTS) $(testenc_OBJECTS) $(testenc_wb_OBJECTS) $(testenc_uwb_OBJECTS) - -all: all-redirect -.SUFFIXES: -.SUFFIXES: .S .c .lo .o .obj .s -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) - cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps libspeex/Makefile - -Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status - cd $(top_builddir) \ - && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status - - -mostlyclean-libLTLIBRARIES: - -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - -distclean-libLTLIBRARIES: - -maintainer-clean-libLTLIBRARIES: - -install-libLTLIBRARIES: $(lib_LTLIBRARIES) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(libdir) - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - if test -f $$p; then \ - echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \ - $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \ - else :; fi; \ - done - -uninstall-libLTLIBRARIES: - @$(NORMAL_UNINSTALL) - list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \ - done - -.c.o: - $(COMPILE) -c $< - -# FIXME: We should only use cygpath when building on Windows, -# and only if it is available. -.c.obj: - $(COMPILE) -c `cygpath -w $<` - -.s.o: - $(COMPILE) -c $< - -.S.o: - $(COMPILE) -c $< - -mostlyclean-compile: - -rm -f *.o core *.core - -rm -f *.$(OBJEXT) - -clean-compile: - -distclean-compile: - -rm -f *.tab.c - -maintainer-clean-compile: - -.c.lo: - $(LIBTOOL) --mode=compile $(COMPILE) -c $< - -.s.lo: - $(LIBTOOL) --mode=compile $(COMPILE) -c $< - -.S.lo: - $(LIBTOOL) --mode=compile $(COMPILE) -c $< - -mostlyclean-libtool: - -rm -f *.lo - -clean-libtool: - -rm -rf .libs _libs - -distclean-libtool: - -maintainer-clean-libtool: - -libspeex.la: $(libspeex_la_OBJECTS) $(libspeex_la_DEPENDENCIES) - $(LINK) -rpath $(libdir) $(libspeex_la_LDFLAGS) $(libspeex_la_OBJECTS) $(libspeex_la_LIBADD) $(LIBS) - -mostlyclean-noinstPROGRAMS: - -clean-noinstPROGRAMS: - -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS) - -distclean-noinstPROGRAMS: - -maintainer-clean-noinstPROGRAMS: - -testenc$(EXEEXT): $(testenc_OBJECTS) $(testenc_DEPENDENCIES) - @rm -f testenc$(EXEEXT) - $(LINK) $(testenc_LDFLAGS) $(testenc_OBJECTS) $(testenc_LDADD) $(LIBS) - -testenc_wb$(EXEEXT): $(testenc_wb_OBJECTS) $(testenc_wb_DEPENDENCIES) - @rm -f testenc_wb$(EXEEXT) - $(LINK) $(testenc_wb_LDFLAGS) $(testenc_wb_OBJECTS) $(testenc_wb_LDADD) $(LIBS) - -testenc_uwb$(EXEEXT): $(testenc_uwb_OBJECTS) $(testenc_uwb_DEPENDENCIES) - @rm -f testenc_uwb$(EXEEXT) - $(LINK) $(testenc_uwb_LDFLAGS) $(testenc_uwb_OBJECTS) $(testenc_uwb_LDADD) $(LIBS) - -install-includeHEADERS: $(include_HEADERS) - @$(NORMAL_INSTALL) - $(mkinstalldirs) $(DESTDIR)$(includedir) - @list='$(include_HEADERS)'; for p in $$list; do \ - if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \ - echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \ - $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \ - done - -uninstall-includeHEADERS: - @$(NORMAL_UNINSTALL) - list='$(include_HEADERS)'; for p in $$list; do \ - rm -f $(DESTDIR)$(includedir)/$$p; \ - done - -tags: TAGS - -ID: $(HEADERS) $(SOURCES) $(LISP) - list='$(SOURCES) $(HEADERS)'; \ - unique=`for i in $$list; do echo $$i; done | \ - awk ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - here=`pwd` && cd $(srcdir) \ - && mkid -f$$here/ID $$unique $(LISP) - -TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) - tags=; \ - here=`pwd`; \ - list='$(SOURCES) $(HEADERS)'; \ - unique=`for i in $$list; do echo $$i; done | \ - awk ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ - || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) - -mostlyclean-tags: - -clean-tags: - -distclean-tags: - -rm -f TAGS ID - -maintainer-clean-tags: - -distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) - -subdir = libspeex - -distdir: $(DISTFILES) - @for file in $(DISTFILES); do \ - d=$(srcdir); \ - if test -d $$d/$$file; then \ - cp -pr $$d/$$file $(distdir)/$$file; \ - else \ - test -f $(distdir)/$$file \ - || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ - || cp -p $$d/$$file $(distdir)/$$file || :; \ - fi; \ - done -bits.lo bits.o : bits.c speex_bits.h misc.h -cb_search.lo cb_search.o : cb_search.c cb_search.h speex_bits.h \ - filters.h stack_alloc.h vq.h misc.h -exc_10_16_table.lo exc_10_16_table.o : exc_10_16_table.c -exc_10_32_table.lo exc_10_32_table.o : exc_10_32_table.c -exc_20_32_table.lo exc_20_32_table.o : exc_20_32_table.c -exc_5_256_table.lo exc_5_256_table.o : exc_5_256_table.c -exc_5_64_table.lo exc_5_64_table.o : exc_5_64_table.c -exc_8_128_table.lo exc_8_128_table.o : exc_8_128_table.c -filters.lo filters.o : filters.c filters.h stack_alloc.h -gain_table.lo gain_table.o : gain_table.c -gain_table_lbr.lo gain_table_lbr.o : gain_table_lbr.c -hexc_10_32_table.lo hexc_10_32_table.o : hexc_10_32_table.c -hexc_table.lo hexc_table.o : hexc_table.c -high_lsp_tables.lo high_lsp_tables.o : high_lsp_tables.c -lpc.lo lpc.o : lpc.c lpc.h -lsp.lo lsp.o : lsp.c lsp.h stack_alloc.h -lsp_tables_nb.lo lsp_tables_nb.o : lsp_tables_nb.c -ltp.lo ltp.o : ltp.c ltp.h speex_bits.h stack_alloc.h filters.h -math_approx.lo math_approx.o : math_approx.c math_approx.h -misc.lo misc.o : misc.c misc.h -modes.lo modes.o : modes.c modes.h speex.h speex_bits.h ltp.h \ - quant_lsp.h cb_search.h sb_celp.h nb_celp.h speex_callbacks.h \ - vbr.h filters.h misc.h -nb_celp.lo nb_celp.o : nb_celp.c nb_celp.h modes.h speex.h speex_bits.h \ - speex_callbacks.h vbr.h filters.h lpc.h lsp.h ltp.h quant_lsp.h \ - cb_search.h stack_alloc.h vq.h misc.h -quant_lsp.lo quant_lsp.o : quant_lsp.c quant_lsp.h speex_bits.h -sb_celp.lo sb_celp.o : sb_celp.c sb_celp.h modes.h speex.h speex_bits.h \ - nb_celp.h speex_callbacks.h vbr.h filters.h lpc.h lsp.h \ - stack_alloc.h cb_search.h quant_lsp.h vq.h ltp.h misc.h -speex_callbacks.lo speex_callbacks.o : speex_callbacks.c \ - speex_callbacks.h speex.h speex_bits.h misc.h -speex_header.lo speex_header.o : speex_header.c speex_header.h misc.h \ - speex.h speex_bits.h -stereo.lo stereo.o : stereo.c speex_stereo.h speex_bits.h \ - speex_callbacks.h speex.h vq.h -testenc.o: testenc.c speex.h speex_bits.h speex_callbacks.h -testenc_uwb.o: testenc_uwb.c speex.h speex_bits.h -testenc_wb.o: testenc_wb.c speex.h speex_bits.h -vbr.lo vbr.o : vbr.c vbr.h -vq.lo vq.o : vq.c vq.h - -info-am: -info: info-am -dvi-am: -dvi: dvi-am -check-am: all-am -check: check-am -installcheck-am: -installcheck: installcheck-am -install-exec-am: install-libLTLIBRARIES -install-exec: install-exec-am - -install-data-am: install-includeHEADERS -install-data: install-data-am - -install-am: all-am - @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am -install: install-am -uninstall-am: uninstall-libLTLIBRARIES uninstall-includeHEADERS -uninstall: uninstall-am -all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) -all-redirect: all-am -install-strip: - $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install -installdirs: - $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir) - - -mostlyclean-generic: - -clean-generic: - -distclean-generic: - -rm -f Makefile $(CONFIG_CLEAN_FILES) - -rm -f config.cache config.log stamp-h stamp-h[0-9]* - -maintainer-clean-generic: -mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \ - mostlyclean-libtool mostlyclean-noinstPROGRAMS \ - mostlyclean-tags mostlyclean-generic - -mostlyclean: mostlyclean-am - -clean-am: clean-libLTLIBRARIES clean-compile clean-libtool \ - clean-noinstPROGRAMS clean-tags clean-generic \ - mostlyclean-am - -clean: clean-am - -distclean-am: distclean-libLTLIBRARIES distclean-compile \ - distclean-libtool distclean-noinstPROGRAMS \ - distclean-tags distclean-generic clean-am - -rm -f libtool - -distclean: distclean-am - -maintainer-clean-am: maintainer-clean-libLTLIBRARIES \ - maintainer-clean-compile maintainer-clean-libtool \ - maintainer-clean-noinstPROGRAMS maintainer-clean-tags \ - maintainer-clean-generic distclean-am - @echo "This command is intended for maintainers to use;" - @echo "it deletes files that may require special tools to rebuild." - -maintainer-clean: maintainer-clean-am - -.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \ -clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \ -uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \ -distclean-compile clean-compile maintainer-clean-compile \ -mostlyclean-libtool distclean-libtool clean-libtool \ -maintainer-clean-libtool mostlyclean-noinstPROGRAMS \ -distclean-noinstPROGRAMS clean-noinstPROGRAMS \ -maintainer-clean-noinstPROGRAMS uninstall-includeHEADERS \ -install-includeHEADERS tags mostlyclean-tags distclean-tags clean-tags \ -maintainer-clean-tags distdir info-am info dvi-am dvi check check-am \ -installcheck-am installcheck install-exec-am install-exec \ -install-data-am install-data install-am install uninstall-am uninstall \ -all-redirect all-am all installdirs mostlyclean-generic \ -distclean-generic clean-generic maintainer-clean-generic clean \ -mostlyclean distclean maintainer-clean - - -# Tell versions [3.59,3.63) of GNU make to not export all variables. -# Otherwise a system limit (for SysV at least) may be exceeded. -.NOEXPORT: diff --git a/engine/voice_codecs/speex/source/libspeex/bits.c b/engine/voice_codecs/speex/source/libspeex/bits.c deleted file mode 100644 index 68285e04..00000000 --- a/engine/voice_codecs/speex/source/libspeex/bits.c +++ /dev/null @@ -1,352 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: speex_bits.c - - Handles bit packing/unpacking - - 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. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - 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 FOUNDATION 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. - -*/ - -#include "speex_bits.h" -#include "misc.h" - -void speex_bits_init(SpeexBits *bits) -{ - int i; - bits->bytes = (char*)speex_alloc(MAX_BYTES_PER_FRAME); - bits->buf_size = MAX_BYTES_PER_FRAME; - - for (i=0;ibuf_size;i++) - bits->bytes[i]=0; - bits->nbBits=0; - bits->bytePtr=0; - bits->bitPtr=0; - bits->owner=1; - bits->overflow=0; -} - -void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size) -{ - int i; - bits->bytes = (char*)buff; - bits->buf_size = buf_size; - - for (i=0;ibytes[i]=0; - bits->nbBits=0; - bits->bytePtr=0; - bits->bitPtr=0; - bits->owner=0; - bits->overflow=0; -} - -void speex_bits_destroy(SpeexBits *bits) -{ - if (bits->owner) - speex_free(bits->bytes); - /* Will do something once the allocation is dynamic */ -} - -void speex_bits_reset(SpeexBits *bits) -{ - int i; - for (i=0;ibuf_size;i++) - bits->bytes[i]=0; - bits->nbBits=0; - bits->bytePtr=0; - bits->bitPtr=0; - bits->overflow=0; -} - -void speex_bits_rewind(SpeexBits *bits) -{ - bits->bytePtr=0; - bits->bitPtr=0; - bits->overflow=0; -} - -void speex_bits_read_from(SpeexBits *bits, char *bytes, int len) -{ - int i; - if (len > bits->buf_size) - { - speex_warning_int("Packet if larger than allocated buffer: ", len); - if (bits->owner) - { - char *tmp = (char*)speex_realloc(bits->bytes, len); - if (tmp) - { - bits->buf_size=len; - bits->bytes=tmp; - } else { - len=bits->buf_size; - speex_warning("Could not resize input buffer: truncating input"); - } - } else { - speex_warning("Do not own input buffer: truncating input"); - len=bits->buf_size; - } - } - for (i=0;ibytes[i]=bytes[i]; - bits->nbBits=len<<3; - bits->bytePtr=0; - bits->bitPtr=0; - bits->overflow=0; -} - -static void speex_bits_flush(SpeexBits *bits) -{ - int i; - if (bits->bytePtr>0) - { - for (i=bits->bytePtr;i<((bits->nbBits+7)>>3);i++) - bits->bytes[i-bits->bytePtr]=bits->bytes[i]; - } - bits->nbBits -= bits->bytePtr<<3; - bits->bytePtr=0; -} - -void speex_bits_read_whole_bytes(SpeexBits *bits, char *bytes, int len) -{ - int i,pos; - - if ((bits->nbBits>>3)+len+1 > bits->buf_size) - { - speex_warning_int("Packet if larger than allocated buffer: ", len); - if (bits->owner) - { - char *tmp = (char*)speex_realloc(bits->bytes, (bits->nbBits>>3)+len+1); - if (tmp) - { - bits->buf_size=(bits->nbBits>>3)+len+1; - bits->bytes=tmp; - } else { - len=bits->buf_size-(bits->nbBits>>3)-1; - speex_warning("Could not resize input buffer: truncating input"); - } - } else { - speex_warning("Do not own input buffer: truncating input"); - len=bits->buf_size; - } - } - - speex_bits_flush(bits); - pos=bits->nbBits>>3; - for (i=0;ibytes[pos+i]=bytes[i]; - bits->nbBits+=len<<3; -} - -int speex_bits_write(SpeexBits *bits, char *bytes, int max_len) -{ - int i; - if (max_len > ((bits->nbBits+7)>>3)) - max_len = ((bits->nbBits+7)>>3); - for (i=0;ibytes[i]; - return max_len; -} - -int speex_bits_write_whole_bytes(SpeexBits *bits, char *bytes, int max_len) -{ - int i; - if (max_len > ((bits->nbBits)>>3)) - max_len = ((bits->nbBits)>>3); - for (i=0;ibytes[i]; - - if (bits->bitPtr>0) - bits->bytes[0]=bits->bytes[max_len]; - else - bits->bytes[0]=0; - for (i=1;i<((bits->nbBits)>>3)+1;i++) - bits->bytes[i]=0; - bits->bytePtr=0; - bits->nbBits &= 7; - return max_len; -} - - -void speex_bits_pack(SpeexBits *bits, int data, int nbBits) -{ - int i; - unsigned int d=data; - - if (bits->bytePtr+((nbBits+bits->bitPtr)>>3) >= bits->buf_size) - { - speex_warning("Buffer too small to pack bits"); - if (bits->owner) - { - char *tmp = (char*)speex_realloc(bits->bytes, ((bits->buf_size+5)*3)>>1); - if (tmp) - { - for (i=bits->buf_size;i<(((bits->buf_size+5)*3)>>1);i++) - tmp[i]=0; - bits->buf_size=((bits->buf_size+5)*3)>>1; - bits->bytes=tmp; - } else { - speex_warning("Could not resize input buffer: not packing"); - return; - } - } else { - speex_warning("Do not own input buffer: not packing"); - return; - } - } - - while(nbBits) - { - int bit; - bit = (d>>(nbBits-1))&1; - bits->bytes[bits->bytePtr] |= bit<<(7-bits->bitPtr); - bits->bitPtr++; - - if (bits->bitPtr==8) - { - bits->bitPtr=0; - bits->bytePtr++; - } - bits->nbBits++; - nbBits--; - } -} - -int speex_bits_unpack_signed(SpeexBits *bits, int nbBits) -{ - unsigned int d=speex_bits_unpack_unsigned(bits,nbBits); - /* If number is negative */ - if (d>>(nbBits-1)) - { - d |= (-1)<bytePtr<<3)+bits->bitPtr+nbBits>bits->nbBits) - bits->overflow=1; - if (bits->overflow) - return 0; - while(nbBits) - { - d<<=1; - d |= (bits->bytes[bits->bytePtr]>>(7-bits->bitPtr))&1; - bits->bitPtr++; - if (bits->bitPtr==8) - { - bits->bitPtr=0; - bits->bytePtr++; - } - nbBits--; - } - return d; -} - -unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits) -{ - unsigned int d=0; - int bitPtr, bytePtr; - char *bytes; - - if ((bits->bytePtr<<3)+bits->bitPtr+nbBits>bits->nbBits) - bits->overflow=1; - if (bits->overflow) - return 0; - - bitPtr=bits->bitPtr; - bytePtr=bits->bytePtr; - bytes = bits->bytes; - while(nbBits) - { - d<<=1; - d |= (bytes[bytePtr]>>(7-bitPtr))&1; - bitPtr++; - if (bitPtr==8) - { - bitPtr=0; - bytePtr++; - } - nbBits--; - } - return d; -} - -int speex_bits_peek(SpeexBits *bits) -{ - if ((bits->bytePtr<<3)+bits->bitPtr+1>bits->nbBits) - bits->overflow=1; - if (bits->overflow) - return 0; - return (bits->bytes[bits->bytePtr]>>(7-bits->bitPtr))&1; -} - -void speex_bits_advance(SpeexBits *bits, int n) -{ - int nbytes, nbits; - - if ((bits->bytePtr<<3)+bits->bitPtr+n>bits->nbBits) - bits->overflow=1; - if (bits->overflow) - return; - - nbytes = n >> 3; - nbits = n & 7; - - bits->bytePtr += nbytes; - bits->bitPtr += nbits; - - if (bits->bitPtr>7) - { - bits->bitPtr-=8; - bits->bytePtr++; - } -} - -int speex_bits_remaining(SpeexBits *bits) -{ - if (bits->overflow) - return -1; - else - return bits->nbBits-((bits->bytePtr<<3)+bits->bitPtr); -} - -int speex_bits_nbytes(SpeexBits *bits) -{ - return ((bits->nbBits+7)>>3); -} - -void speex_bits_insert_terminator(SpeexBits *bits) -{ - if (bits->bitPtr<7) - speex_bits_pack(bits, 0, 1); - while (bits->bitPtr<7) - speex_bits_pack(bits, 1, 1); -} diff --git a/engine/voice_codecs/speex/source/libspeex/cb_search.c b/engine/voice_codecs/speex/source/libspeex/cb_search.c deleted file mode 100644 index 785bb49b..00000000 --- a/engine/voice_codecs/speex/source/libspeex/cb_search.c +++ /dev/null @@ -1,387 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: cb_search.c - - 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. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - 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 FOUNDATION 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. -*/ - - -#include "cb_search.h" -#include "filters.h" -#include "stack_alloc.h" -#include "vq.h" -#include "misc.h" - -void split_cb_search_shape_sign( -float target[], /* target vector */ -float ak[], /* LPCs for this subframe */ -float awk1[], /* Weighted LPCs for this subframe */ -float awk2[], /* Weighted LPCs for this subframe */ -void *par, /* Codebook/search parameters*/ -int p, /* number of LPC coeffs */ -int nsf, /* number of samples in subframe */ -float *exc, -float *r, -SpeexBits *bits, -char *stack, -int complexity -) -{ - int i,j,k,m,n,q; - float *resp; - float *t, *e, *E, *r2; - float *tmp; - float *ndist, *odist; - int *itmp; - float **ot, **nt; - int **nind, **oind; - int *ind; - signed char *shape_cb; - int shape_cb_size, subvect_size, nb_subvect; - split_cb_params *params; - int N=2; - int *best_index; - float *best_dist; - int have_sign; - - N=complexity; - if (N>10) - N=10; - - ot=PUSH(stack, N, float*); - nt=PUSH(stack, N, float*); - oind=PUSH(stack, N, int*); - nind=PUSH(stack, N, int*); - - params = (split_cb_params *) par; - subvect_size = params->subvect_size; - nb_subvect = params->nb_subvect; - shape_cb_size = 1<shape_bits; - shape_cb = params->shape_cb; - have_sign = params->have_sign; - resp = PUSH(stack, shape_cb_size*subvect_size, float); - t = PUSH(stack, nsf, float); - e = PUSH(stack, nsf, float); - r2 = PUSH(stack, nsf, float); - E = PUSH(stack, shape_cb_size, float); - ind = PUSH(stack, nb_subvect, int); - - tmp = PUSH(stack, 2*N*nsf, float); - for (i=0;i=shape_cb_size) - { - sign=-1; - rind-=shape_cb_size; - } - res = resp+rind*subvect_size; - if (sign>0) - for (m=0;m=shape_cb_size) - { - sign=-1; - rind-=shape_cb_size; - } - - g=sign*0.03125*shape_cb[rind*subvect_size+m]; - q=subvect_size-m; - for (n=subvect_size*(i+1);nm;n--) - { - for (q=(i+1)*subvect_size;qshape_bits+have_sign); - } - - /* Put everything back together */ - for (i=0;i=shape_cb_size) - { - sign=-1; - rind-=shape_cb_size; - } - - for (j=0;jsubvect_size; - nb_subvect = params->nb_subvect; - shape_cb_size = 1<shape_bits; - shape_cb = params->shape_cb; - have_sign = params->have_sign; - - ind = PUSH(stack, nb_subvect, int); - signs = PUSH(stack, nb_subvect, int); - - /* Decode codewords and gains */ - for (i=0;ishape_bits); - } - /* Compute decoded excitation */ - for (i=0;i - - -void bw_lpc(float gamma, float *lpc_in, float *lpc_out, int order) -{ - int i; - float tmp=1; - for (i=0;i>1; - for (i=0;ilast_pitch=0; - mem->last_pitch_gain[0]=mem->last_pitch_gain[1]=mem->last_pitch_gain[2]=0; - mem->smooth_gain=1; -} - -void comb_filter( -float *exc, /*decoded excitation*/ -float *new_exc, /*enhanced excitation*/ -float *ak, /*LPC filter coefs*/ -int p, /*LPC order*/ -int nsf, /*sub-frame size*/ -int pitch, /*pitch period*/ -float *pitch_gain, /*pitch gain (3-tap)*/ -float comb_gain, /*gain of comb filter*/ -CombFilterMem *mem -) -{ - int i; - float exc_energy=0, new_exc_energy=0; - float gain; - float step; - float fact; - /*Compute excitation energy prior to enhancement*/ - for (i=0;ilast_pitch_gain[0] + mem->last_pitch_gain[1] + mem->last_pitch_gain[2]); - if (g>1.3) - comb_gain*=1.3/g; - if (g<.5) - comb_gain*=2*g; - } - step = 1.0/nsf; - fact=0; - /*Apply pitch comb-filter (filter out noise between pitch harmonics)*/ - for (i=0;ilast_pitch_gain[0]*exc[i-mem->last_pitch+1] + - mem->last_pitch_gain[1]*exc[i-mem->last_pitch] + - mem->last_pitch_gain[2]*exc[i-mem->last_pitch-1] - ); - } - - mem->last_pitch_gain[0] = pitch_gain[0]; - mem->last_pitch_gain[1] = pitch_gain[1]; - mem->last_pitch_gain[2] = pitch_gain[2]; - mem->last_pitch = pitch; - - /*Gain after enhancement*/ - for (i=0;i1) - gain=1; - - for (i=0;ismooth_gain = .96*mem->smooth_gain + .04*gain; - new_exc[i] *= mem->smooth_gain; - } -} diff --git a/engine/voice_codecs/speex/source/libspeex/filters.h b/engine/voice_codecs/speex/source/libspeex/filters.h deleted file mode 100644 index ad6dc022..00000000 --- a/engine/voice_codecs/speex/source/libspeex/filters.h +++ /dev/null @@ -1,79 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: filters.h - Various analysis/synthesis filters - - 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. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - 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 FOUNDATION 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 FILTERS_H -#define FILTERS_H - - -typedef struct CombFilterMem { - int last_pitch; - float last_pitch_gain[3]; - float smooth_gain; -} CombFilterMem; - - -void qmf_decomp(float *xx, float *aa, float *y1, float *y2, int N, int M, float *mem, char *stack); -void fir_mem_up(float *x, float *a, float *y, int N, int M, float *mem, char *stack); - - -void filter_mem2(float *x, float *num, float *den, float *y, int N, int ord, float *mem); -void fir_mem2(float *x, float *num, float *y, int N, int ord, float *mem); -void iir_mem2(float *x, float *den, float *y, int N, int ord, float *mem); - -/* Apply bandwidth expansion on LPC coef */ -void bw_lpc(float gamma, float *lpc_in, float *lpc_out, int order); - - - -/* FIR filter */ -void fir_decim_mem(float *x, float *a, float *y, int N, int M, float *mem); - -void syn_percep_zero(float *x, float *ak, float *awk1, float *awk2, float *y, int N, int ord, char *stack); - -void residue_percep_zero(float *xx, float *ak, float *awk1, float *awk2, float *y, int N, int ord, char *stack); - -void comp_filter_mem_init (CombFilterMem *mem); - -void comb_filter( -float *exc, /*decoded excitation*/ -float *new_exc, /*enhanced excitation*/ -float *ak, /*LPC filter coefs*/ -int p, /*LPC order*/ -int nsf, /*sub-frame size*/ -int pitch, /*pitch period*/ -float *pitch_gain, /*pitch gain (3-tap)*/ -float comb_gain, /*gain of comb filter*/ -CombFilterMem *mem -); - - -#endif diff --git a/engine/voice_codecs/speex/source/libspeex/filters_sse.h b/engine/voice_codecs/speex/source/libspeex/filters_sse.h deleted file mode 100644 index 3fba6c8d..00000000 --- a/engine/voice_codecs/speex/source/libspeex/filters_sse.h +++ /dev/null @@ -1,289 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: filters.c - Various analysis/synthesis filters - - 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. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - 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 FOUNDATION 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. -*/ - -void filter_mem2(float *x, float *_num, float *_den, float *y, int N, int ord, float *_mem) -{ - float __num[20], __den[20], __mem[20]; - float *num, *den, *mem; - int i; - - num = (float*)(((int)(__num+4))&0xfffffff0)-1; - den = (float*)(((int)(__den+4))&0xfffffff0)-1; - mem = (float*)(((int)(__mem+4))&0xfffffff0)-1; - for (i=0;i<=10;i++) - num[i]=den[i]=0; - for (i=0;i<10;i++) - mem[i]=0; - - for (i=0;i x(n) * x(n-i) for all n - * `--' - * for lags between 0 and lag-1, and x == 0 outside 0...n-1 - */ -void _spx_autocorr( - const float * x, /* in: [0...n-1] samples x */ - float *ac, /* out: [0...lag-1] ac values */ - int lag, int n) -{ - float d; int i; - while (lag--) { - for (i = lag, d = 0; i < n; i++) d += x[i] * x[i-lag]; - ac[lag] = d; - } -} diff --git a/engine/voice_codecs/speex/source/libspeex/lpc.h b/engine/voice_codecs/speex/source/libspeex/lpc.h deleted file mode 100644 index e3f70b5a..00000000 --- a/engine/voice_codecs/speex/source/libspeex/lpc.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: lpc.h - Functions for LPC (Linear Prediction Coefficients) 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. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - 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 FOUNDATION 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 LPC_H -#define LPC_H - -void _spx_autocorr( - const float * x, /* in: [0...n-1] samples x */ - float *ac, /* out: [0...lag-1] ac values */ - int lag, int n); - -float /* returns minimum mean square error */ -wld( - float * lpc, /* [0...p-1] LPC coefficients */ - const float * ac, /* in: [0...p] autocorrelation values */ - float * ref, /* out: [0...p-1] reflection coef's */ - int p - ); - - -#endif diff --git a/engine/voice_codecs/speex/source/libspeex/lsp.c b/engine/voice_codecs/speex/source/libspeex/lsp.c deleted file mode 100644 index 1af762cd..00000000 --- a/engine/voice_codecs/speex/source/libspeex/lsp.c +++ /dev/null @@ -1,328 +0,0 @@ -/*---------------------------------------------------------------------------*\ -Original copyright - FILE........: AKSLSPD.C - TYPE........: Turbo C - COMPANY.....: Voicetronix - AUTHOR......: David Rowe - DATE CREATED: 24/2/93 - -Modified by Jean-Marc Valin - - This file contains functions for converting Linear Prediction - Coefficients (LPC) to Line Spectral Pair (LSP) and back. Note that the - LSP coefficients are not in radians format but in the x domain of the - unit circle. - - Speex License: - - 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. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - 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 FOUNDATION 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. -*/ - -#include -#include "lsp.h" -#include "stack_alloc.h" - - -#ifndef M_PI -#define M_PI 3.14159265358979323846 /* pi */ -#endif - -#ifndef NULL -#define NULL 0 -#endif - -/*---------------------------------------------------------------------------*\ - - FUNCTION....: cheb_poly_eva() - - AUTHOR......: David Rowe - DATE CREATED: 24/2/93 - - This function evaluates a series of Chebyshev polynomials - -\*---------------------------------------------------------------------------*/ - - - -static float cheb_poly_eva(float *coef,float x,int m,char *stack) -/* float coef[] coefficients of the polynomial to be evaluated */ -/* float x the point where polynomial is to be evaluated */ -/* int m order of the polynomial */ -{ - int i; - float *T,sum; - int m2=m>>1; - - /* Allocate memory for Chebyshev series formulation */ - T=PUSH(stack, m2+1, float); - - /* Initialise values */ - T[0]=1; - T[1]=x; - - /* Evaluate Chebyshev series formulation using iterative approach */ - /* Evaluate polynomial and return value also free memory space */ - sum = coef[m2] + coef[m2-1]*x; - x *= 2; - for(i=2;i<=m2;i++) - { - T[i] = x*T[i-1] - T[i-2]; - sum += coef[m2-i] * T[i]; - } - - return sum; -} - - -/*---------------------------------------------------------------------------*\ - - FUNCTION....: lpc_to_lsp() - - AUTHOR......: David Rowe - DATE CREATED: 24/2/93 - - This function converts LPC coefficients to LSP - coefficients. - -\*---------------------------------------------------------------------------*/ - - -int lpc_to_lsp (float *a,int lpcrdr,float *freq,int nb,float delta, char *stack) -/* float *a lpc coefficients */ -/* int lpcrdr order of LPC coefficients (10) */ -/* float *freq LSP frequencies in the x domain */ -/* int nb number of sub-intervals (4) */ -/* float delta grid spacing interval (0.02) */ - - -{ - - float psuml,psumr,psumm,temp_xr,xl,xr,xm=0; - float temp_psumr/*,temp_qsumr*/; - int i,j,m,flag,k; - float *Q; /* ptrs for memory allocation */ - float *P; - float *px; /* ptrs of respective P'(z) & Q'(z) */ - float *qx; - float *p; - float *q; - float *pt; /* ptr used for cheb_poly_eval() - whether P' or Q' */ - int roots=0; /* DR 8/2/94: number of roots found */ - flag = 1; /* program is searching for a root when, - 1 else has found one */ - m = lpcrdr/2; /* order of P'(z) & Q'(z) polynomials */ - - - /* Allocate memory space for polynomials */ - Q = PUSH(stack, (m+1), float); - P = PUSH(stack, (m+1), float); - - /* determine P'(z)'s and Q'(z)'s coefficients where - P'(z) = P(z)/(1 + z^(-1)) and Q'(z) = Q(z)/(1-z^(-1)) */ - - px = P; /* initialise ptrs */ - qx = Q; - p = px; - q = qx; - *px++ = 1.0; - *qx++ = 1.0; - for(i=1;i<=m;i++){ - *px++ = a[i]+a[lpcrdr+1-i]-*p++; - *qx++ = a[i]-a[lpcrdr+1-i]+*q++; - } - px = P; - qx = Q; - for(i=0;i= -1.0)){ - float dd; - /* Modified by JMV to provide smaller steps around x=+-1 */ - dd=(delta*(1-.9*xl*xl)); - if (fabs(psuml)<.2) - dd *= .5; - - xr = xl - dd; /* interval spacing */ - psumr = cheb_poly_eva(pt,xr,lpcrdr,stack);/* poly(xl-delta_x) */ - temp_psumr = psumr; - temp_xr = xr; - - /* if no sign change increment xr and re-evaluate poly(xr). Repeat til - sign change. - if a sign change has occurred the interval is bisected and then - checked again for a sign change which determines in which - interval the zero lies in. - If there is no sign change between poly(xm) and poly(xl) set interval - between xm and xr else set interval between xl and xr and repeat till - root is located within the specified limits */ - - if((psumr*psuml)<0.0){ - roots++; - - psumm=psuml; - for(k=0;k<=nb;k++){ - xm = (xl+xr)/2; /* bisect the interval */ - psumm=cheb_poly_eva(pt,xm,lpcrdr,stack); - if(psumm*psuml>0.){ - psuml=psumm; - xl=xm; - } - else{ - psumr=psumm; - xr=xm; - } - } - - /* once zero is found, reset initial interval to xr */ - freq[j] = (xm); - xl = xm; - flag = 0; /* reset flag for next search */ - } - else{ - psuml=temp_psumr; - xl=temp_xr; - } - } - } - return(roots); -} - - -/*---------------------------------------------------------------------------*\ - - FUNCTION....: lsp_to_lpc() - - AUTHOR......: David Rowe - DATE CREATED: 24/2/93 - - lsp_to_lpc: This function converts LSP coefficients to LPC - coefficients. - -\*---------------------------------------------------------------------------*/ - - -void lsp_to_lpc(float *freq,float *ak,int lpcrdr, char *stack) -/* float *freq array of LSP frequencies in the x domain */ -/* float *ak array of LPC coefficients */ -/* int lpcrdr order of LPC coefficients */ - - -{ - int i,j; - float xout1,xout2,xin1,xin2; - float *Wp; - float *pw,*n1,*n2,*n3,*n4=NULL; - int m = lpcrdr/2; - - Wp = PUSH(stack, 4*m+2, float); - pw = Wp; - - /* initialise contents of array */ - - for(i=0;i<=4*m+1;i++){ /* set contents of buffer to 0 */ - *pw++ = 0.0; - } - - /* Set pointers up */ - - pw = Wp; - xin1 = 1.0; - xin2 = 1.0; - - /* reconstruct P(z) and Q(z) by cascading second order - polynomials in form 1 - 2xz(-1) +z(-2), where x is the - LSP coefficient */ - - for(j=0;j<=lpcrdr;j++){ - int i2=0; - for(i=0;iM_PI-margin) - lsp[len-1]=M_PI-margin; - for (i=1;ilsp[i+1]-margin) - lsp[i]= .5* (lsp[i] + lsp[i+1]-margin); - } -} diff --git a/engine/voice_codecs/speex/source/libspeex/lsp.h b/engine/voice_codecs/speex/source/libspeex/lsp.h deleted file mode 100644 index 25404954..00000000 --- a/engine/voice_codecs/speex/source/libspeex/lsp.h +++ /dev/null @@ -1,57 +0,0 @@ -/*---------------------------------------------------------------------------*\ -Original Copyright - FILE........: AK2LSPD.H - TYPE........: Turbo C header file - COMPANY.....: Voicetronix - AUTHOR......: James Whitehall - DATE CREATED: 21/11/95 - -Modified by Jean-Marc Valin - - This file contains functions for converting Linear Prediction - Coefficients (LPC) to Line Spectral Pair (LSP) and back. Note that the - LSP coefficients are not in radians format but in the x domain of the - unit circle. - -\*---------------------------------------------------------------------------*/ -/* Speex License: - - 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. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - 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 FOUNDATION 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 __AK2LSPD__ -#define __AK2LSPD__ - -int lpc_to_lsp (float *a, int lpcrdr, float *freq, int nb, float delta, char *stack); -void lsp_to_lpc(float *freq, float *ak, int lpcrdr, char *stack); - -/*Added by JMV*/ -void lsp_enforce_margin(float *lsp, int len, float margin); - - -#endif /* __AK2LSPD__ */ diff --git a/engine/voice_codecs/speex/source/libspeex/lsp_tables_nb.c b/engine/voice_codecs/speex/source/libspeex/lsp_tables_nb.c deleted file mode 100644 index a68ce994..00000000 --- a/engine/voice_codecs/speex/source/libspeex/lsp_tables_nb.c +++ /dev/null @@ -1,360 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: lsp_tables_nb.c - Codebooks for LSPs in narrowband CELP mode - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. 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. - - 3. The name of the author may not be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. -*/ - -signed char cdbk_nb[640]={ -30,19,38,34,40,32,46,43,58,43, -5,-18,-25,-40,-33,-55,-52,20,34,28, --20,-63,-97,-92,61,53,47,49,53,75, --14,-53,-77,-79,0,-3,-5,19,22,26, --9,-53,-55,66,90,72,85,68,74,52, --4,-41,-58,-31,-18,-31,27,32,30,18, -24,3,8,5,-12,-3,26,28,74,63, --2,-39,-67,-77,-106,-74,59,59,73,65, -44,40,71,72,82,83,98,88,89,60, --6,-31,-47,-48,-13,-39,-9,7,2,79, --1,-39,-60,-17,87,81,65,50,45,19, --21,-67,-91,-87,-41,-50,7,18,39,74, -10,-31,-28,39,24,13,23,5,56,45, -29,10,-5,-13,-11,-35,-18,-8,-10,-8, --25,-71,-77,-21,2,16,50,63,87,87, -5,-32,-40,-51,-68,0,12,6,54,34, -5,-12,32,52,68,64,69,59,65,45, -14,-16,-31,-40,-65,-67,41,49,47,37, --11,-52,-75,-84,-4,57,48,42,42,33, --11,-51,-68,-6,13,0,8,-8,26,32, --23,-53,0,36,56,76,97,105,111,97, --1,-28,-39,-40,-43,-54,-44,-40,-18,35, -16,-20,-19,-28,-42,29,47,38,74,45, -3,-29,-48,-62,-80,-104,-33,56,59,59, -10,17,46,72,84,101,117,123,123,106, --7,-33,-49,-51,-70,-67,-27,-31,70,67, --16,-62,-85,-20,82,71,86,80,85,74, --19,-58,-75,-45,-29,-33,-18,-25,45,57, --12,-42,-5,12,28,36,52,64,81,82, -13,-9,-27,-28,22,3,2,22,26,6, --6,-44,-51,2,15,10,48,43,49,34, --19,-62,-84,-89,-102,-24,8,17,61,68, -39,24,23,19,16,-5,12,15,27,15, --8,-44,-49,-60,-18,-32,-28,52,54,62, --8,-48,-77,-70,66,101,83,63,61,37, --12,-50,-75,-64,33,17,13,25,15,77, -1,-42,-29,72,64,46,49,31,61,44, --8,-47,-54,-46,-30,19,20,-1,-16,0, -16,-12,-18,-9,-26,-27,-10,-22,53,45, --10,-47,-75,-82,-105,-109,8,25,49,77, -50,65,114,117,124,118,115,96,90,61, --9,-45,-63,-60,-75,-57,8,11,20,29, -0,-35,-49,-43,40,47,35,40,55,38, --24,-76,-103,-112,-27,3,23,34,52,75, -8,-29,-43,12,63,38,35,29,24,8, -25,11,1,-15,-18,-43,-7,37,40,21, --20,-56,-19,-19,-4,-2,11,29,51,63, --2,-44,-62,-75,-89,30,57,51,74,51, -50,46,68,64,65,52,63,55,65,43, -18,-9,-26,-35,-55,-69,3,6,8,17, --15,-61,-86,-97,1,86,93,74,78,67, --1,-38,-66,-48,48,39,29,25,17,-1, -13,13,29,39,50,51,69,82,97,98, --2,-36,-46,-27,-16,-30,-13,-4,-7,-4, -25,-5,-11,-6,-25,-21,33,12,31,29, --8,-38,-52,-63,-68,-89,-33,-1,10,74, --2,-15,59,91,105,105,101,87,84,62, --7,-33,-50,-35,-54,-47,25,17,82,81, --13,-56,-83,21,58,31,42,25,72,65, --24,-66,-91,-56,9,-2,21,10,69,75, -2,-24,11,22,25,28,38,34,48,33, -7,-29,-26,17,15,-1,14,0,-2,0, --6,-41,-67,6,-2,-9,19,2,85,74, --22,-67,-84,-71,-50,3,11,-9,2,62}; - -signed char cdbk_nb_low1[320]={ --34,-52,-15,45,2, -23,21,52,24,-33, --9,-1,9,-44,-41, --13,-17,44,22,-17, --6,-4,-1,22,38, -26,16,2,50,27, --35,-34,-9,-41,6, -0,-16,-34,51,8, --14,-31,-49,15,-33, -45,49,33,-11,-37, --62,-54,45,11,-5, --72,11,-1,-12,-11, -24,27,-11,-43,46, -43,33,-12,-9,-1, -1,-4,-23,-57,-71, -11,8,16,17,-8, --20,-31,-41,53,48, --16,3,65,-24,-8, --23,-32,-37,-32,-49, --10,-17,6,38,5, --9,-17,-46,8,52, -3,6,45,40,39, --7,-6,-34,-74,31, -8,1,-16,43,68, --11,-19,-31,4,6, -0,-6,-17,-16,-38, --16,-30,2,9,-39, --16,-1,43,-10,48, -3,3,-16,-31,-3, -62,68,43,13,3, --10,8,20,-56,12, -12,-2,-18,22,-15, --40,-36,1,7,41, -0,1,46,-6,-62, --4,-12,-2,-11,-83, --13,-2,91,33,-10, -0,4,-11,-16,79, -32,37,14,9,51, --21,-28,-56,-34,0, -21,9,-26,11,28, --42,-54,-23,-2,-15, -31,30,8,-39,-66, --39,-36,31,-28,-40, --46,35,40,22,24, -33,48,23,-34,14, -40,32,17,27,-3, -25,26,-13,-61,-17, -11,4,31,60,-6, --26,-41,-64,13,16, --26,54,31,-11,-23, --9,-11,-34,-71,-21, --34,-35,55,50,29, --22,-27,-50,-38,57, -33,42,57,48,26, -11,0,-49,-31,26, --4,-14,5,78,37, -17,0,-49,-12,-23, -26,14,2,2,-43, --17,-12,10,-8,-4, -8,18,12,-6,20, --12,-6,-13,-25,34, -15,40,49,7,8, -13,20,20,-19,-22, --2,-8,2,51,-51}; - -signed char cdbk_nb_low2[320]={ --6,53,-21,-24,4, -26,17,-4,-37,25, -17,-36,-13,31,3, --6,27,15,-10,31, -28,26,-10,-10,-40, -16,-7,15,13,41, --9,0,-4,50,-6, --7,14,38,22,0, --48,2,1,-13,-19, -32,-3,-60,11,-17, --1,-24,-34,-1,35, --5,-27,28,44,13, -25,15,42,-11,15, -51,35,-36,20,8, --4,-12,-29,19,-47, -49,-15,-4,16,-29, --39,14,-30,4,25, --9,-5,-51,-14,-3, --40,-32,38,5,-9, --8,-4,-1,-22,71, --3,14,26,-18,-22, -24,-41,-25,-24,6, -23,19,-10,39,-26, --27,65,45,2,-7, --26,-8,22,-12,16, -15,16,-35,-5,33, --21,-8,0,23,33, -34,6,21,36,6, --7,-22,8,-37,-14, -31,38,11,-4,-3, --39,-32,-8,32,-23, --6,-12,16,20,-28, --4,23,13,-52,-1, -22,6,-33,-40,-6, -4,-62,13,5,-26, -35,39,11,2,57, --11,9,-20,-28,-33, -52,-5,-6,-2,22, --14,-16,-48,35,1, --58,20,13,33,-1, --74,56,-18,-22,-31, -12,6,-14,4,-2, --9,-47,10,-3,29, --17,-5,61,14,47, --12,2,72,-39,-17, -92,64,-53,-51,-15, --30,-38,-41,-29,-28, -27,9,36,9,-35, --42,81,-21,20,25, --16,-5,-17,-35,21, -15,-28,48,2,-2, -9,-19,29,-40,30, --18,-18,18,-16,-57, -15,-20,-12,-15,-37, --15,33,-39,21,-22, --13,35,11,13,-38, --63,29,23,-27,32, -18,3,-26,42,33, --64,-66,-17,16,56, -2,36,3,31,21, --41,-39,8,-57,14, -37,-2,19,-36,-19, --23,-29,-16,1,-3, --8,-10,31,64,-65}; - -signed char cdbk_nb_high1[320]={ --26,-8,29,21,4, -19,-39,33,-7,-36, -56,54,48,40,29, --4,-24,-42,-66,-43, --60,19,-2,37,41, --10,-37,-60,-64,18, --22,77,73,40,25, -4,19,-19,-66,-2, -11,5,21,14,26, --25,-86,-4,18,1, -26,-37,10,37,-1, -24,-12,-59,-11,20, --6,34,-16,-16,42, -19,-28,-51,53,32, -4,10,62,21,-12, --34,27,4,-48,-48, --50,-49,31,-7,-21, --42,-25,-4,-43,-22, -59,2,27,12,-9, --6,-16,-8,-32,-58, --16,-29,-5,41,23, --30,-33,-46,-13,-10, --38,52,52,1,-17, --9,10,26,-25,-6, -33,-20,53,55,25, --32,-5,-42,23,21, -66,5,-28,20,9, -75,29,-7,-42,-39, -15,3,-23,21,6, -11,1,-29,14,63, -10,54,26,-24,-51, --49,7,-23,-51,15, --66,1,60,25,10, -0,-30,-4,-15,17, -19,59,40,4,-5, -33,6,-22,-58,-70, --5,23,-6,60,44, --29,-16,-47,-29,52, --19,50,28,16,35, -31,36,0,-21,6, -21,27,22,42,7, --66,-40,-8,7,19, -46,0,-4,60,36, -45,-7,-29,-6,-32, --39,2,6,-9,33, -20,-51,-34,18,-6, -19,6,11,5,-19, --29,-2,42,-11,-45, --21,-55,57,37,2, --14,-67,-16,-27,-38, -69,48,19,2,-17, -20,-20,-16,-34,-17, --25,-61,10,73,45, -16,-40,-64,-17,-29, --22,56,17,-39,8, --11,8,-25,-18,-13, --19,8,54,57,36, --17,-26,-4,6,-21, -40,42,-4,20,31, -53,10,-34,-53,31, --17,35,0,15,-6, --20,-63,-73,22,25, -29,17,8,-29,-39, --69,18,15,-15,-5}; - -signed char cdbk_nb_high2[320]={ -11,47,16,-9,-46, --32,26,-64,34,-5, -38,-7,47,20,2, --73,-99,-3,-45,20, -70,-52,15,-6,-7, --82,31,21,47,51, -39,-3,9,0,-41, --7,-15,-54,2,0, -27,-31,9,-45,-22, --38,-24,-24,8,-33, -23,5,50,-36,-17, --18,-51,-2,13,19, -43,12,-15,-12,61, -38,38,7,13,0, -6,-1,3,62,9, -27,22,-33,38,-35, --9,30,-43,-9,-32, --1,4,-4,1,-5, --11,-8,38,31,11, --10,-42,-21,-37,1, -43,15,-13,-35,-19, --18,15,23,-26,59, -1,-21,53,8,-41, --50,-14,-28,4,21, -25,-28,-40,5,-40, --41,4,51,-33,-8, --8,1,17,-60,12, -25,-41,17,34,43, -19,45,7,-37,24, --15,56,-2,35,-10, -48,4,-47,-2,5, --5,-54,5,-3,-33, --10,30,-2,-44,-24, --38,9,-9,42,4, -6,-56,44,-16,9, --40,-26,18,-20,10, -28,-41,-21,-4,13, --18,32,-30,-3,37, -15,22,28,50,-40, -3,-29,-64,7,51, --19,-11,17,-27,-40, --64,24,-12,-7,-27, -3,37,48,-1,2, --9,-38,-34,46,1, -27,-6,19,-13,26, -10,34,20,25,40, -50,-6,-7,30,9, --24,0,-23,71,-61, -22,58,-34,-4,2, --49,-33,25,30,-8, --6,-16,77,2,38, --8,-35,-6,-30,56, -78,31,33,-20,13, --39,20,22,4,21, --8,4,-6,10,-83, --41,9,-25,-43,15, --7,-12,-34,-39,-37, --33,19,30,16,-33, -42,-25,25,-68,44, --15,-11,-4,23,50, -14,4,-39,-43,20, --30,60,9,-20,7, -16,19,-33,37,29, -16,-35,7,38,-27}; diff --git a/engine/voice_codecs/speex/source/libspeex/ltp.c b/engine/voice_codecs/speex/source/libspeex/ltp.c deleted file mode 100644 index f95d2152..00000000 --- a/engine/voice_codecs/speex/source/libspeex/ltp.c +++ /dev/null @@ -1,548 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: ltp.c - Long-Term Prediction functions - - 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. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - 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 FOUNDATION 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. -*/ - -#include -#include "ltp.h" -#include "stack_alloc.h" -#include "filters.h" -#include "speex_bits.h" - -#ifdef _USE_SSE -#include "ltp_sse.h" -#else -static float inner_prod(float *x, float *y, int len) -{ - int i; - float sum1=0,sum2=0,sum3=0,sum4=0; - for (i=0;ibest_score[N-1]) - { - float g1, g; - g1 = corr[i-start]/(energy[i-start]+10); - g = sqrt(g1*corr[i-start]/(e0+10)); - if (g>g1) - g=g1; - if (g<0) - g=0; - for (j=0;j best_score[j]) - { - for (k=N-1;k>j;k--) - { - best_score[k]=best_score[k-1]; - pitch[k]=pitch[k-1]; - gain[k] = gain[k-1]; - } - best_score[j]=score[i-start]; - pitch[j]=i; - gain[j]=g; - break; - } - } - } - } - -} - - - - -/** Finds the best quantized 3-tap pitch predictor by analysis by synthesis */ -float pitch_gain_search_3tap( -float target[], /* Target vector */ -float ak[], /* LPCs for this subframe */ -float awk1[], /* Weighted LPCs #1 for this subframe */ -float awk2[], /* Weighted LPCs #2 for this subframe */ -float exc[], /* Excitation */ -void *par, -int pitch, /* Pitch value */ -int p, /* Number of LPC coeffs */ -int nsf, /* Number of samples in subframe */ -SpeexBits *bits, -char *stack, -float *exc2, -float *r, -int *cdbk_index -) -{ - int i,j; - float *tmp, *tmp2; - float *x[3]; - float *e[3]; - float corr[3]; - float A[3][3]; - float gain[3]; - int gain_cdbk_size; - signed char *gain_cdbk; - float err1,err2; - - ltp_params *params; - params = (ltp_params*) par; - gain_cdbk=params->gain_cdbk; - gain_cdbk_size=1<gain_bits; - tmp = PUSH(stack, 3*nsf, float); - tmp2 = PUSH(stack, 3*nsf, float); - - x[0]=tmp; - x[1]=tmp+nsf; - x[2]=tmp+2*nsf; - - e[0]=tmp2; - e[1]=tmp2+nsf; - e[2]=tmp2+2*nsf; - - for (i=2;i>=0;i--) - { - int pp=pitch+1-i; - for (j=0;j0) - tot+=ptr[0]; - if (ptr[2]>0) - tot+=ptr[2]; - if (tot>1) - continue; - } - - if (sum>best_sum || i==0) - { - best_sum=sum; - best_cdbk=i; - } - } - gain[0] = 0.015625*gain_cdbk[best_cdbk*3] + .5; - gain[1] = 0.015625*gain_cdbk[best_cdbk*3+1]+ .5; - gain[2] = 0.015625*gain_cdbk[best_cdbk*3+2]+ .5; - - *cdbk_index=best_cdbk; - } - - for (i=0;i10) - N=10; - - nbest=PUSH(stack, N, int); - gains = PUSH(stack, N, float); - params = (ltp_params*) par; - - if (N==0 || endpitch_bits); - speex_bits_pack(bits, 0, params->gain_bits); - for (i=0;iend-start+1) - N=end-start+1; - open_loop_nbest_pitch(sw, start, end, nsf, nbest, gains, N, stack); - for (i=0;ipitch_bits); - speex_bits_pack(bits, best_gain_index, params->gain_bits); - /*printf ("encode pitch: %d %d\n", best_pitch, best_gain_index);*/ - for (i=0;igain_cdbk; - - pitch = speex_bits_unpack_unsigned(bits, params->pitch_bits); - pitch += start; - gain_index = speex_bits_unpack_unsigned(bits, params->gain_bits); - /*printf ("decode pitch: %d %d\n", pitch, gain_index);*/ - gain[0] = 0.015625*gain_cdbk[gain_index*3]+.5; - gain[1] = 0.015625*gain_cdbk[gain_index*3+1]+.5; - gain[2] = 0.015625*gain_cdbk[gain_index*3+2]+.5; - - if (count_lost && pitch > subframe_offset) - { - float gain_sum; - - if (1) { - float tmp = count_lost < 4 ? last_pitch_gain : 0.4 * last_pitch_gain; - if (tmp>.95) - tmp=.95; - gain_sum = fabs(gain[1]); - if (gain[0]>0) - gain_sum += gain[0]; - else - gain_sum -= .5*gain[0]; - if (gain[2]>0) - gain_sum += gain[2]; - else - gain_sum -= .5*gain[2]; - if (gain_sum > tmp) { - float fact = tmp/gain_sum; - for (i=0;i<3;i++) - gain[i]*=fact; - - } - - } - - if (0) { - gain_sum = fabs(gain[0])+fabs(gain[1])+fabs(gain[2]); - if (gain_sum>.95) { - float fact = .95/gain_sum; - for (i=0;i<3;i++) - gain[i]*=fact; - } - } - } - - *pitch_val = pitch; - /**gain_val = gain[0]+gain[1]+gain[2];*/ - gain_val[0]=gain[0]; - gain_val[1]=gain[1]; - gain_val[2]=gain[2]; - - { - float *e[3]; - float *tmp2; - tmp2=PUSH(stack, 3*nsf, float); - e[0]=tmp2; - e[1]=tmp2+nsf; - e[2]=tmp2+2*nsf; - - for (i=0;i<3;i++) - { - int j; - int pp=pitch+1-i; -#if 0 - for (j=0;jpp) - tmp1=pp; - for (j=0;jpp+pitch) - tmp3=pp+pitch; - for (j=tmp1;j.99) - pitch_coef=.99; - for (i=0;i.99) - pitch_coef=.99; - for (i=0;i -#include "math_approx.h" - -#ifdef SLOW_TRIG - -float cos_sin[102] = { - 1.00000000, 0.00000000, - 0.99804751, 0.06245932, - 0.99219767, 0.12467473, - 0.98247331, 0.18640330, - 0.96891242, 0.24740396, - 0.95156795, 0.30743851, - 0.93050762, 0.36627253, - 0.90581368, 0.42367626, - 0.87758256, 0.47942554, - 0.84592450, 0.53330267, - 0.81096312, 0.58509727, - 0.77283495, 0.63460708, - 0.73168887, 0.68163876, - 0.68768556, 0.72600866, - 0.64099686, 0.76754350, - 0.59180508, 0.80608111, - 0.54030231, 0.84147098, - 0.48668967, 0.87357494, - 0.43117652, 0.90226759, - 0.37397963, 0.92743692, - 0.31532236, 0.94898462, - 0.25543377, 0.96682656, - 0.19454771, 0.98089306, - 0.13290194, 0.99112919, - 0.07073720, 0.99749499, - 0.00829623, 0.99996559, - -0.05417714, 0.99853134, - -0.11643894, 0.99319785, - -0.17824606, 0.98398595, - -0.23935712, 0.97093160, - -0.29953351, 0.95408578, - -0.35854022, 0.93351428, - -0.41614684, 0.90929743, - -0.47212841, 0.88152979, - -0.52626633, 0.85031979, - -0.57834920, 0.81578931, - -0.62817362, 0.77807320, - -0.67554504, 0.73731872, - -0.72027847, 0.69368503, - -0.76219923, 0.64734252, - -0.80114362, 0.59847214, - -0.83695955, 0.54726475, - -0.86950718, 0.49392030, - -0.89865940, 0.43864710, - -0.92430238, 0.38166099, - -0.94633597, 0.32318451, - -0.96467415, 0.26344599, - -0.97924529, 0.20267873, - -0.98999250, 0.14112001, - -0.99687381, 0.07901022, - -0.99986235, 0.01659189 -}; - -float speex_cos(float x) -{ - int ind; - float delta; - ind = (int)floor(x*16+.5); - delta = x-0.062500*ind; - ind <<= 1; - return cos_sin[ind] - delta*(cos_sin[ind+1] + - .5*delta*(cos_sin[ind] - - .3333333*delta*cos_sin[ind+1])); -} - -#endif - diff --git a/engine/voice_codecs/speex/source/libspeex/math_approx.h b/engine/voice_codecs/speex/source/libspeex/math_approx.h deleted file mode 100644 index c917ffd7..00000000 --- a/engine/voice_codecs/speex/source/libspeex/math_approx.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: math_approx.c - Various math approximation functions for Speex - - 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. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - 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 FOUNDATION 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 MATH_APPROX_H -#define MATH_APPROX_H - -float speex_cos(float x); - - -#endif diff --git a/engine/voice_codecs/speex/source/libspeex/misc.c b/engine/voice_codecs/speex/source/libspeex/misc.c deleted file mode 100644 index f84e0f61..00000000 --- a/engine/voice_codecs/speex/source/libspeex/misc.c +++ /dev/null @@ -1,145 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: mics.c - Various utility routines for Speex - - 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. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - 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 FOUNDATION 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. -*/ - -#include "misc.h" -#include -#include -#include - -#ifndef RELEASE -void print_vec(float *vec, int len, char *name) -{ - int i; - printf ("%s ", name); - for (i=0;i>24; - ret += (i>>8)&0x0000ff00; - ret += (i<<8)&0x00ff0000; - ret += (i<<24); -#endif - return ret; -} - -unsigned int le_int(unsigned int i) -{ - unsigned int ret=i; -#ifdef WORDS_BIGENDIAN - ret = i>>24; - ret += (i>>8)&0x0000ff00; - ret += (i<<8)&0x00ff0000; - ret += (i<<24); -#endif - return ret; -} - -unsigned short be_short(unsigned short s) -{ - unsigned short ret=s; -#ifndef WORDS_BIGENDIAN - ret = s>>8; - ret += s<<8; -#endif - return ret; -} - -unsigned short le_short(unsigned short s) -{ - unsigned short ret=s; -#ifdef WORDS_BIGENDIAN - ret = s>>8; - ret += s<<8; -#endif - return ret; -} - -void *speex_alloc (int size) -{ - return calloc(size,1); -} - -void *speex_realloc (void *ptr, int size) -{ - return realloc(ptr, size); -} - -void speex_free (void *ptr) -{ - free(ptr); -} - -void *speex_move (void *dest, void *src, int n) -{ - return memmove(dest,src,n); -} - -void speex_error(char *str) -{ - fprintf (stderr, "Fatal error: %s\n", str); - exit(1); -} - -void speex_warning(char *str) -{ - fprintf (stderr, "warning: %s\n", str); -} - -void speex_warning_int(char *str, int val) -{ - fprintf (stderr, "warning: %s %d\n", str, val); -} - -void speex_rand_vec(float std, float *data, int len) -{ - int i; - for (i=0;ienc_init(mode); -} - -void *speex_decoder_init(SpeexMode *mode) -{ - return mode->dec_init(mode); -} - -void speex_encoder_destroy(void *state) -{ - (*((SpeexMode**)state))->enc_destroy(state); -} - -int speex_encode(void *state, float *in, SpeexBits *bits) -{ - return (*((SpeexMode**)state))->enc(state, in, bits); -} - -void speex_decoder_destroy(void *state) -{ - (*((SpeexMode**)state))->dec_destroy(state); -} - -int speex_decode(void *state, SpeexBits *bits, float *out) -{ - return (*((SpeexMode**)state))->dec(state, bits, out); -} - - -int speex_encoder_ctl(void *state, int request, void *ptr) -{ - return (*((SpeexMode**)state))->enc_ctl(state, request, ptr); -} - -int speex_decoder_ctl(void *state, int request, void *ptr) -{ - return (*((SpeexMode**)state))->dec_ctl(state, request, ptr); -} - - - -static int nb_mode_query(void *mode, int request, void *ptr) -{ - SpeexNBMode *m = (SpeexNBMode*)mode; - - switch (request) - { - case SPEEX_MODE_FRAME_SIZE: - *((int*)ptr)=m->frameSize; - break; - case SPEEX_SUBMODE_BITS_PER_FRAME: - if (*((int*)ptr)==0) - *((int*)ptr) = NB_SUBMODE_BITS+1; - else if (m->submodes[*((int*)ptr)]==NULL) - *((int*)ptr) = -1; - else - *((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame; - break; - default: - speex_warning_int("Unknown nb_mode_query request: ", request); - return -1; - } - return 0; -} - -static int wb_mode_query(void *mode, int request, void *ptr) -{ - SpeexSBMode *m = (SpeexSBMode*)mode; - - switch (request) - { - case SPEEX_MODE_FRAME_SIZE: - *((int*)ptr)=2*m->frameSize; - break; - case SPEEX_SUBMODE_BITS_PER_FRAME: - if (*((int*)ptr)==0) - *((int*)ptr) = SB_SUBMODE_BITS+1; - else if (m->submodes[*((int*)ptr)]==NULL) - *((int*)ptr) = -1; - else - *((int*)ptr) = m->submodes[*((int*)ptr)]->bits_per_frame; - break; - default: - speex_warning_int("Unknown wb_mode_query request: ", request); - return -1; - } - return 0; -} - - -int speex_mode_query(SpeexMode *mode, int request, void *ptr) -{ - return mode->query(mode->mode, request, ptr); -} diff --git a/engine/voice_codecs/speex/source/libspeex/modes.h b/engine/voice_codecs/speex/source/libspeex/modes.h deleted file mode 100644 index 0a94357c..00000000 --- a/engine/voice_codecs/speex/source/libspeex/modes.h +++ /dev/null @@ -1,146 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin */ -/** - @file modes.h - @brief Describes the different modes of the codec -*/ -/* - 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. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - 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 FOUNDATION 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 MODES_H -#define MODES_H - -#include "speex.h" -#include "speex_bits.h" - - -#define NB_SUBMODES 16 -#define NB_SUBMODE_BITS 4 - -#define SB_SUBMODES 8 -#define SB_SUBMODE_BITS 3 - - -/** Quantizes LSPs */ -typedef void (*lsp_quant_func)(float *, float *, int, SpeexBits *); - -/** Decodes quantized LSPs */ -typedef void (*lsp_unquant_func)(float *, int, SpeexBits *); - - -/** Long-term predictor quantization */ -typedef int (*ltp_quant_func)(float *, float *, float *, float *, - float *, float *, void *, int, int, float, - int, int, SpeexBits*, char *, float *, float *, int); - -/** Long-term un-quantize */ -typedef void (*ltp_unquant_func)(float *, int, int, float, void *, int, int *, - float *, SpeexBits*, char*, int, int, float); - - -/** Innovation quantization function */ -typedef void (*innovation_quant_func)(float *, float *, float *, float *, void *, int, int, - float *, float *, SpeexBits *, char *, int); - -/** Innovation unquantization function */ -typedef void (*innovation_unquant_func)(float *, void *, int, SpeexBits*, char *); - -/** Description of a Speex sub-mode (wither narrowband or wideband */ -typedef struct SpeexSubmode { - int lbr_pitch; /**< Set to -1 for "normal" modes, otherwise encode pitch using a global pitch and allowing a +- lbr_pitch variation (for low not-rates)*/ - int forced_pitch_gain; /**< Use the same (forced) pitch gain for all sub-frames */ - int have_subframe_gain; /**< Number of bits to use as sub-frame innovation gain */ - int double_codebook; /**< Apply innovation quantization twice for higher quality (and higher bit-rate)*/ - /*LSP functions*/ - lsp_quant_func lsp_quant; /**< LSP quantization function */ - lsp_unquant_func lsp_unquant; /**< LSP unquantization function */ - - /*Lont-term predictor functions*/ - ltp_quant_func ltp_quant; /**< Long-term predictor (pitch) quantizer */ - ltp_unquant_func ltp_unquant; /**< Long-term predictor (pitch) un-quantizer */ - void *ltp_params; /**< Pitch parameters (options) */ - - /*Quantization of innovation*/ - innovation_quant_func innovation_quant; /**< Innovation quantization */ - innovation_unquant_func innovation_unquant; /**< Innovation un-quantization */ - void *innovation_params; /**< Innovation quantization parameters*/ - - /*Synthesis filter enhancement*/ - float lpc_enh_k1; /**< Enhancer constant */ - float lpc_enh_k2; /**< Enhancer constant */ - float comb_gain; /**< Gain of enhancer comb filter */ - - int bits_per_frame; /**< Number of bits per frame after encoding*/ -} SpeexSubmode; - -/** Struct defining the encoding/decoding mode*/ -typedef struct SpeexNBMode { - int frameSize; /**< Size of frames used for encoding */ - int subframeSize; /**< Size of sub-frames used for encoding */ - int lpcSize; /**< Order of LPC filter */ - int bufSize; /**< Size of signal buffer to use in encoder */ - int pitchStart; /**< Smallest pitch value allowed */ - int pitchEnd; /**< Largest pitch value allowed */ - - float gamma1; /**< Perceptual filter parameter #1 */ - float gamma2; /**< Perceptual filter parameter #2 */ - float lag_factor; /**< Lag-windowing parameter */ - float lpc_floor; /**< Noise floor for LPC analysis */ - float preemph; /**< Pre-emphasis */ - - SpeexSubmode *submodes[NB_SUBMODES]; /**< Sub-mode data for the mode */ - int defaultSubmode; /**< Default sub-mode to use when encoding */ - int quality_map[11]; /**< Mode corresponding to each quality setting */ -} SpeexNBMode; - - -/** Struct defining the encoding/decoding mode for SB-CELP (wideband) */ -typedef struct SpeexSBMode { - SpeexMode *nb_mode; /**< Embedded narrowband mode */ - int frameSize; /**< Size of frames used for encoding */ - int subframeSize; /**< Size of sub-frames used for encoding */ - int lpcSize; /**< Order of LPC filter */ - int bufSize; /**< Signal buffer size in encoder */ - float gamma1; /**< Perceptual filter parameter #1 */ - float gamma2; /**< Perceptual filter parameter #1 */ - float lag_factor; /**< Lag-windowing parameter */ - float lpc_floor; /**< Noise floor for LPC analysis */ - float preemph; /**< Pre-emphasis */ - float folding_gain; - - SpeexSubmode *submodes[SB_SUBMODES]; /**< Sub-mode data for the mode */ - int defaultSubmode; /**< Default sub-mode to use when encoding */ - int low_quality_map[11]; /**< Mode corresponding to each quality setting */ - int quality_map[11]; /**< Mode corresponding to each quality setting */ - float (*vbr_thresh)[11]; - int nb_modes; -} SpeexSBMode; - - -#endif diff --git a/engine/voice_codecs/speex/source/libspeex/nb_celp.c b/engine/voice_codecs/speex/source/libspeex/nb_celp.c deleted file mode 100644 index 837d2f5d..00000000 --- a/engine/voice_codecs/speex/source/libspeex/nb_celp.c +++ /dev/null @@ -1,1715 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: nb_celp.c - - 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. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - 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 FOUNDATION 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. -*/ - -#include -#include "nb_celp.h" -#include "lpc.h" -#include "lsp.h" -#include "ltp.h" -#include "quant_lsp.h" -#include "cb_search.h" -#include "filters.h" -#include "stack_alloc.h" -#include "vq.h" -#include "speex_bits.h" -#include "vbr.h" -#include "misc.h" -#include "speex_callbacks.h" - -#ifdef SLOW_TRIG -#include "math_approx.h" -#define cos speex_cos -#endif - -#ifndef M_PI -#define M_PI 3.14159265358979323846 /* pi */ -#endif - -#ifndef NULL -#define NULL 0 -#endif - -#define SUBMODE(x) st->submodes[st->submodeID]->x - -float exc_gain_quant_scal3[8]={-2.794750, -1.810660, -1.169850, -0.848119, -0.587190, -0.329818, -0.063266, 0.282826}; - -float exc_gain_quant_scal1[2]={-0.35, 0.05}; - -#define sqr(x) ((x)*(x)) - -void *nb_encoder_init(SpeexMode *m) -{ - EncState *st; - SpeexNBMode *mode; - int i; - - mode=(SpeexNBMode *)m->mode; - st = (EncState*)speex_alloc(sizeof(EncState)+8000*sizeof(float)); - if (!st) - return NULL; - - st->stack = ((char*)st) + sizeof(EncState); - - st->mode=m; - - st->frameSize = mode->frameSize; - st->windowSize = st->frameSize*3/2; - st->nbSubframes=mode->frameSize/mode->subframeSize; - st->subframeSize=mode->subframeSize; - st->lpcSize = mode->lpcSize; - st->bufSize = mode->bufSize; - st->gamma1=mode->gamma1; - st->gamma2=mode->gamma2; - st->min_pitch=mode->pitchStart; - st->max_pitch=mode->pitchEnd; - st->lag_factor=mode->lag_factor; - st->lpc_floor = mode->lpc_floor; - st->preemph = mode->preemph; - - st->submodes=mode->submodes; - st->submodeID=st->submodeSelect=mode->defaultSubmode; - st->pre_mem=0; - st->pre_mem2=0; - st->bounded_pitch = 1; - - /* Allocating input buffer */ - st->inBuf = PUSH(st->stack, st->bufSize, float); - st->frame = st->inBuf + st->bufSize - st->windowSize; - /* Allocating excitation buffer */ - st->excBuf = PUSH(st->stack, st->bufSize, float); - st->exc = st->excBuf + st->bufSize - st->windowSize; - st->swBuf = PUSH(st->stack, st->bufSize, float); - st->sw = st->swBuf + st->bufSize - st->windowSize; - - st->exc2Buf = PUSH(st->stack, st->bufSize, float); - st->exc2 = st->exc2Buf + st->bufSize - st->windowSize; - - st->innov = PUSH(st->stack, st->frameSize, float); - - /* Asymmetric "pseudo-Hamming" window */ - { - int part1, part2; - part1 = st->subframeSize*7/2; - part2 = st->subframeSize*5/2; - st->window = PUSH(st->stack, st->windowSize, float); - for (i=0;iwindow[i]=.54-.46*cos(M_PI*i/part1); - for (i=0;iwindow[part1+i]=.54+.46*cos(M_PI*i/part2); - } - /* Create the window for autocorrelation (lag-windowing) */ - st->lagWindow = PUSH(st->stack, st->lpcSize+1, float); - for (i=0;ilpcSize+1;i++) - st->lagWindow[i]=exp(-.5*sqr(2*M_PI*st->lag_factor*i)); - - st->autocorr = PUSH(st->stack, st->lpcSize+1, float); - - st->buf2 = PUSH(st->stack, st->windowSize, float); - - st->lpc = PUSH(st->stack, st->lpcSize+1, float); - st->interp_lpc = PUSH(st->stack, st->lpcSize+1, float); - st->interp_qlpc = PUSH(st->stack, st->lpcSize+1, float); - st->bw_lpc1 = PUSH(st->stack, st->lpcSize+1, float); - st->bw_lpc2 = PUSH(st->stack, st->lpcSize+1, float); - - st->lsp = PUSH(st->stack, st->lpcSize, float); - st->qlsp = PUSH(st->stack, st->lpcSize, float); - st->old_lsp = PUSH(st->stack, st->lpcSize, float); - st->old_qlsp = PUSH(st->stack, st->lpcSize, float); - st->interp_lsp = PUSH(st->stack, st->lpcSize, float); - st->interp_qlsp = PUSH(st->stack, st->lpcSize, float); - st->rc = PUSH(st->stack, st->lpcSize, float); - st->first = 1; - for (i=0;ilpcSize;i++) - { - st->lsp[i]=(M_PI*((float)(i+1)))/(st->lpcSize+1); - } - - st->mem_sp = PUSH(st->stack, st->lpcSize, float); - st->mem_sw = PUSH(st->stack, st->lpcSize, float); - st->mem_sw_whole = PUSH(st->stack, st->lpcSize, float); - st->mem_exc = PUSH(st->stack, st->lpcSize, float); - - st->pi_gain = PUSH(st->stack, st->nbSubframes, float); - - st->pitch = PUSH(st->stack, st->nbSubframes, int); - - st->vbr = PUSHS(st->stack, VBRState); - vbr_init(st->vbr); - st->vbr_quality = 8; - st->vbr_enabled = 0; - st->vad_enabled = 0; - st->dtx_enabled = 0; - st->abr_enabled = 0; - st->abr_drift = 0; - - st->complexity=2; - st->sampling_rate=8000; - st->dtx_count=0; - - return st; -} - -void nb_encoder_destroy(void *state) -{ - EncState *st=(EncState *)state; - /* Free all allocated memory */ - - vbr_destroy(st->vbr); - - /*Free state memory... should be last*/ - speex_free(st); -} - -int nb_encode(void *state, float *in, SpeexBits *bits) -{ - EncState *st; - int i, sub, roots; - int ol_pitch; - float ol_pitch_coef; - float ol_gain; - float *res, *target, *mem; - char *stack; - float *syn_resp; - float lsp_dist=0; - float *orig; - - st=(EncState *)state; - stack=st->stack; - - /* Copy new data in input buffer */ - speex_move(st->inBuf, st->inBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); - st->inBuf[st->bufSize-st->frameSize] = in[0] - st->preemph*st->pre_mem; - for (i=1;iframeSize;i++) - st->inBuf[st->bufSize-st->frameSize+i] = in[i] - st->preemph*in[i-1]; - st->pre_mem = in[st->frameSize-1]; - - /* Move signals 1 frame towards the past */ - speex_move(st->exc2Buf, st->exc2Buf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); - speex_move(st->excBuf, st->excBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); - speex_move(st->swBuf, st->swBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); - - - /* Window for analysis */ - for (i=0;iwindowSize;i++) - st->buf2[i] = st->frame[i] * st->window[i]; - - /* Compute auto-correlation */ - _spx_autocorr(st->buf2, st->autocorr, st->lpcSize+1, st->windowSize); - - st->autocorr[0] += 10; /* prevents NANs */ - st->autocorr[0] *= st->lpc_floor; /* Noise floor in auto-correlation domain */ - - /* Lag windowing: equivalent to filtering in the power-spectrum domain */ - for (i=0;ilpcSize+1;i++) - st->autocorr[i] *= st->lagWindow[i]; - - /* Levinson-Durbin */ - wld(st->lpc+1, st->autocorr, st->rc, st->lpcSize); - st->lpc[0]=1; - - /* LPC to LSPs (x-domain) transform */ - roots=lpc_to_lsp (st->lpc, st->lpcSize, st->lsp, 15, 0.2, stack); - /* Check if we found all the roots */ - if (roots==st->lpcSize) - { - /* LSP x-domain to angle domain*/ - for (i=0;ilpcSize;i++) - st->lsp[i] = acos(st->lsp[i]); - } else { - /* Search again if we can afford it */ - if (st->complexity>1) - roots = lpc_to_lsp (st->lpc, st->lpcSize, st->lsp, 11, 0.05, stack); - if (roots==st->lpcSize) - { - /* LSP x-domain to angle domain*/ - for (i=0;ilpcSize;i++) - st->lsp[i] = acos(st->lsp[i]); - } else { - /*If we can't find all LSP's, do some damage control and use previous filter*/ - for (i=0;ilpcSize;i++) - { - st->lsp[i]=st->old_lsp[i]; - } - } - } - - - lsp_dist=0; - for (i=0;ilpcSize;i++) - lsp_dist += (st->old_lsp[i] - st->lsp[i])*(st->old_lsp[i] - st->lsp[i]); - - /* Whole frame analysis (open-loop estimation of pitch and excitation gain) */ - { - if (st->first) - for (i=0;ilpcSize;i++) - st->interp_lsp[i] = st->lsp[i]; - else - for (i=0;ilpcSize;i++) - st->interp_lsp[i] = .375*st->old_lsp[i] + .625*st->lsp[i]; - - lsp_enforce_margin(st->interp_lsp, st->lpcSize, .002); - - /* Compute interpolated LPCs (unquantized) for whole frame*/ - for (i=0;ilpcSize;i++) - st->interp_lsp[i] = cos(st->interp_lsp[i]); - lsp_to_lpc(st->interp_lsp, st->interp_lpc, st->lpcSize,stack); - - - /*Open-loop pitch*/ - if (!st->submodes[st->submodeID] || st->vbr_enabled || st->vad_enabled || SUBMODE(forced_pitch_gain) || - SUBMODE(lbr_pitch) != -1) - { - int nol_pitch[6]; - float nol_pitch_coef[6]; - - bw_lpc(st->gamma1, st->interp_lpc, st->bw_lpc1, st->lpcSize); - bw_lpc(st->gamma2, st->interp_lpc, st->bw_lpc2, st->lpcSize); - - filter_mem2(st->frame, st->bw_lpc1, st->bw_lpc2, st->sw, st->frameSize, st->lpcSize, st->mem_sw_whole); - - open_loop_nbest_pitch(st->sw, st->min_pitch, st->max_pitch, st->frameSize, - nol_pitch, nol_pitch_coef, 6, stack); - ol_pitch=nol_pitch[0]; - ol_pitch_coef = nol_pitch_coef[0]; - /*Try to remove pitch multiples*/ - for (i=1;i<6;i++) - { - if ((nol_pitch_coef[i]>.85*ol_pitch_coef) && - (fabs(nol_pitch[i]-ol_pitch/2.0)<=1 || fabs(nol_pitch[i]-ol_pitch/3.0)<=1 || - fabs(nol_pitch[i]-ol_pitch/4.0)<=1 || fabs(nol_pitch[i]-ol_pitch/5.0)<=1)) - { - /*ol_pitch_coef=nol_pitch_coef[i];*/ - ol_pitch = nol_pitch[i]; - } - } - /*if (ol_pitch>50) - ol_pitch/=2;*/ - /*ol_pitch_coef = sqrt(ol_pitch_coef);*/ - } else { - ol_pitch=0; - ol_pitch_coef=0; - } - /*Compute "real" excitation*/ - fir_mem2(st->frame, st->interp_lpc, st->exc, st->frameSize, st->lpcSize, st->mem_exc); - - /* Compute open-loop excitation gain */ - ol_gain=0; - for (i=0;iframeSize;i++) - ol_gain += st->exc[i]*st->exc[i]; - - ol_gain=sqrt(1+ol_gain/st->frameSize); - } - - /*VBR stuff*/ - if (st->vbr && (st->vbr_enabled||st->vad_enabled)) - { - - if (st->abr_enabled) - { - float qual_change=0; - if (st->abr_drift2 * st->abr_drift > 0) - { - /* Only adapt if long-term and short-term drift are the same sign */ - qual_change = -.00001*st->abr_drift/(1+st->abr_count); - if (qual_change>.05) - qual_change=.05; - if (qual_change<-.05) - qual_change=-.05; - } - st->vbr_quality += qual_change; - if (st->vbr_quality>10) - st->vbr_quality=10; - if (st->vbr_quality<0) - st->vbr_quality=0; - } - - st->relative_quality = vbr_analysis(st->vbr, in, st->frameSize, ol_pitch, ol_pitch_coef); - /*if (delta_qual<0)*/ - /* delta_qual*=.1*(3+st->vbr_quality);*/ - if (st->vbr_enabled) - { - int mode; - int choice=0; - float min_diff=100; - mode = 8; - while (mode) - { - int v1; - float thresh; - v1=(int)floor(st->vbr_quality); - if (v1==10) - thresh = vbr_nb_thresh[mode][v1]; - else - thresh = (st->vbr_quality-v1)*vbr_nb_thresh[mode][v1+1] + (1+v1-st->vbr_quality)*vbr_nb_thresh[mode][v1]; - if (st->relative_quality > thresh && - st->relative_quality-threshrelative_quality-thresh; - } - mode--; - } - mode=choice; - if (mode==0) - { - if (st->dtx_count==0 || lsp_dist>.05 || !st->dtx_enabled || st->dtx_count>20) - { - mode=1; - st->dtx_count=1; - } else { - mode=0; - st->dtx_count++; - } - } else { - st->dtx_count=0; - } - - speex_encoder_ctl(state, SPEEX_SET_MODE, &mode); - - if (st->abr_enabled) - { - int bitrate; - speex_encoder_ctl(state, SPEEX_GET_BITRATE, &bitrate); - st->abr_drift+=(bitrate-st->abr_enabled); - st->abr_drift2 = .95*st->abr_drift2 + .05*(bitrate-st->abr_enabled); - st->abr_count += 1.0; - } - - } else { - /*VAD only case*/ - int mode; - if (st->relative_quality<2) - { - if (st->dtx_count==0 || lsp_dist>.05 || !st->dtx_enabled || st->dtx_count>20) - { - st->dtx_count=1; - mode=1; - } else { - mode=0; - st->dtx_count++; - } - } else { - st->dtx_count = 0; - mode=st->submodeSelect; - } - /*speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);*/ - st->submodeID=mode; - } - } else { - st->relative_quality = -1; - } - - /* First, transmit a zero for narrowband */ - speex_bits_pack(bits, 0, 1); - - /* Transmit the sub-mode we use for this frame */ - speex_bits_pack(bits, st->submodeID, NB_SUBMODE_BITS); - - - /* If null mode (no transmission), just set a couple things to zero*/ - if (st->submodes[st->submodeID] == NULL) - { - for (i=0;iframeSize;i++) - st->exc[i]=st->exc2[i]=st->sw[i]=0; - - for (i=0;ilpcSize;i++) - st->mem_sw[i]=0; - st->first=1; - st->bounded_pitch = 1; - - /* Final signal synthesis from excitation */ - iir_mem2(st->exc, st->interp_qlpc, st->frame, st->frameSize, st->lpcSize, st->mem_sp); - - in[0] = st->frame[0] + st->preemph*st->pre_mem2; - for (i=1;iframeSize;i++) - in[i]=st->frame[i] + st->preemph*in[i-1]; - st->pre_mem2=in[st->frameSize-1]; - - return 0; - - } - - /* LSP Quantization */ - if (st->first) - { - for (i=0;ilpcSize;i++) - st->old_lsp[i] = st->lsp[i]; - } - - - /*Quantize LSPs*/ -#if 1 /*0 for unquantized*/ - SUBMODE(lsp_quant)(st->lsp, st->qlsp, st->lpcSize, bits); -#else - for (i=0;ilpcSize;i++) - st->qlsp[i]=st->lsp[i]; -#endif - - /*If we use low bit-rate pitch mode, transmit open-loop pitch*/ - if (SUBMODE(lbr_pitch)!=-1) - { - speex_bits_pack(bits, ol_pitch-st->min_pitch, 7); - } - - if (SUBMODE(forced_pitch_gain)) - { - int quant; - quant = (int)floor(.5+15*ol_pitch_coef); - if (quant>15) - quant=15; - if (quant<0) - quant=0; - speex_bits_pack(bits, quant, 4); - ol_pitch_coef=0.066667*quant; - } - - - /*Quantize and transmit open-loop excitation gain*/ - { - int qe = (int)(floor(3.5*log(ol_gain))); - if (qe<0) - qe=0; - if (qe>31) - qe=31; - ol_gain = exp(qe/3.5); - speex_bits_pack(bits, qe, 5); - } - - /* Special case for first frame */ - if (st->first) - { - for (i=0;ilpcSize;i++) - st->old_qlsp[i] = st->qlsp[i]; - } - - /* Filter response */ - res = PUSH(stack, st->subframeSize, float); - /* Target signal */ - target = PUSH(stack, st->subframeSize, float); - syn_resp = PUSH(stack, st->subframeSize, float); - mem = PUSH(stack, st->lpcSize, float); - orig = PUSH(stack, st->frameSize, float); - for (i=0;iframeSize;i++) - orig[i]=st->frame[i]; - - /* Loop on sub-frames */ - for (sub=0;subnbSubframes;sub++) - { - float tmp; - int offset; - float *sp, *sw, *exc, *exc2; - int pitch; - - /* Offset relative to start of frame */ - offset = st->subframeSize*sub; - /* Original signal */ - sp=st->frame+offset; - /* Excitation */ - exc=st->exc+offset; - /* Weighted signal */ - sw=st->sw+offset; - - exc2=st->exc2+offset; - - - /* LSP interpolation (quantized and unquantized) */ - tmp = (1.0 + sub)/st->nbSubframes; - for (i=0;ilpcSize;i++) - st->interp_lsp[i] = (1-tmp)*st->old_lsp[i] + tmp*st->lsp[i]; - for (i=0;ilpcSize;i++) - st->interp_qlsp[i] = (1-tmp)*st->old_qlsp[i] + tmp*st->qlsp[i]; - - /* Make sure the filters are stable */ - lsp_enforce_margin(st->interp_lsp, st->lpcSize, .002); - lsp_enforce_margin(st->interp_qlsp, st->lpcSize, .002); - - /* Compute interpolated LPCs (quantized and unquantized) */ - for (i=0;ilpcSize;i++) - st->interp_lsp[i] = cos(st->interp_lsp[i]); - lsp_to_lpc(st->interp_lsp, st->interp_lpc, st->lpcSize,stack); - - for (i=0;ilpcSize;i++) - st->interp_qlsp[i] = cos(st->interp_qlsp[i]); - lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack); - - /* Compute analysis filter gain at w=pi (for use in SB-CELP) */ - tmp=1; - st->pi_gain[sub]=0; - for (i=0;i<=st->lpcSize;i++) - { - st->pi_gain[sub] += tmp*st->interp_qlpc[i]; - tmp = -tmp; - } - - /* Compute bandwidth-expanded (unquantized) LPCs for perceptual weighting */ - bw_lpc(st->gamma1, st->interp_lpc, st->bw_lpc1, st->lpcSize); - if (st->gamma2>=0) - bw_lpc(st->gamma2, st->interp_lpc, st->bw_lpc2, st->lpcSize); - else - { - st->bw_lpc2[0]=1; - st->bw_lpc2[1]=-st->preemph; - for (i=2;i<=st->lpcSize;i++) - st->bw_lpc2[i]=0; - } - - /* Compute impulse response of A(z/g1) / ( A(z)*A(z/g2) )*/ - for (i=0;isubframeSize;i++) - exc[i]=0; - exc[0]=1; - syn_percep_zero(exc, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, syn_resp, st->subframeSize, st->lpcSize, stack); - - /* Reset excitation */ - for (i=0;isubframeSize;i++) - exc[i]=0; - for (i=0;isubframeSize;i++) - exc2[i]=0; - - /* Compute zero response of A(z/g1) / ( A(z/g2) * A(z) ) */ - for (i=0;ilpcSize;i++) - mem[i]=st->mem_sp[i]; - iir_mem2(exc, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, mem); - - for (i=0;ilpcSize;i++) - mem[i]=st->mem_sw[i]; - filter_mem2(exc, st->bw_lpc1, st->bw_lpc2, res, st->subframeSize, st->lpcSize, mem); - - /* Compute weighted signal */ - for (i=0;ilpcSize;i++) - mem[i]=st->mem_sw[i]; - filter_mem2(sp, st->bw_lpc1, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, mem); - - /* Compute target signal */ - for (i=0;isubframeSize;i++) - target[i]=sw[i]-res[i]; - - for (i=0;isubframeSize;i++) - exc[i]=exc2[i]=0; - - /* If we have a long-term predictor (otherwise, something's wrong) */ - if (SUBMODE(ltp_quant)) - { - int pit_min, pit_max; - /* Long-term prediction */ - if (SUBMODE(lbr_pitch) != -1) - { - /* Low bit-rate pitch handling */ - int margin; - margin = SUBMODE(lbr_pitch); - if (margin) - { - if (ol_pitch < st->min_pitch+margin-1) - ol_pitch=st->min_pitch+margin-1; - if (ol_pitch > st->max_pitch-margin) - ol_pitch=st->max_pitch-margin; - pit_min = ol_pitch-margin+1; - pit_max = ol_pitch+margin; - } else { - pit_min=pit_max=ol_pitch; - } - } else { - pit_min = st->min_pitch; - pit_max = st->max_pitch; - } - - /* Force pitch to use only the current frame if needed */ - if (st->bounded_pitch && pit_max>offset) - pit_max=offset; - - /* Perform pitch search */ - pitch = SUBMODE(ltp_quant)(target, sw, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, - exc, SUBMODE(ltp_params), pit_min, pit_max, ol_pitch_coef, - st->lpcSize, st->subframeSize, bits, stack, - exc2, syn_resp, st->complexity); - - st->pitch[sub]=pitch; - } else { - speex_error ("No pitch prediction, what's wrong"); - } - - /* Update target for adaptive codebook contribution */ - syn_percep_zero(exc, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, res, st->subframeSize, st->lpcSize, stack); - for (i=0;isubframeSize;i++) - target[i]-=res[i]; - - - /* Quantization of innovation */ - { - float *innov; - float ener=0, ener_1; - - innov = st->innov+sub*st->subframeSize; - for (i=0;isubframeSize;i++) - innov[i]=0; - - residue_percep_zero(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, st->buf2, st->subframeSize, st->lpcSize, stack); - for (i=0;isubframeSize;i++) - ener+=st->buf2[i]*st->buf2[i]; - ener=sqrt(.1+ener/st->subframeSize); - /*for (i=0;isubframeSize;i++) - printf ("%f\n", st->buf2[i]/ener); - */ - - ener /= ol_gain; - - /* Calculate gain correction for the sub-frame (if any) */ - if (SUBMODE(have_subframe_gain)) - { - int qe; - ener=log(ener); - if (SUBMODE(have_subframe_gain)==3) - { - qe = vq_index(&ener, exc_gain_quant_scal3, 1, 8); - speex_bits_pack(bits, qe, 3); - ener=exc_gain_quant_scal3[qe]; - } else { - qe = vq_index(&ener, exc_gain_quant_scal1, 1, 2); - speex_bits_pack(bits, qe, 1); - ener=exc_gain_quant_scal1[qe]; - } - ener=exp(ener); - } else { - ener=1; - } - - ener*=ol_gain; - - /*printf ("%f %f\n", ener, ol_gain);*/ - - ener_1 = 1/ener; - - /* Normalize innovation */ - for (i=0;isubframeSize;i++) - target[i]*=ener_1; - - /* Quantize innovation */ - if (SUBMODE(innovation_quant)) - { - /* Codebook search */ - SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, - SUBMODE(innovation_params), st->lpcSize, st->subframeSize, - innov, syn_resp, bits, stack, st->complexity); - - /* De-normalize innovation and update excitation */ - for (i=0;isubframeSize;i++) - innov[i]*=ener; - for (i=0;isubframeSize;i++) - exc[i] += innov[i]; - } else { - speex_error("No fixed codebook"); - } - - /* In some (rare) modes, we do a second search (more bits) to reduce noise even more */ - if (SUBMODE(double_codebook)) { - char *tmp_stack=stack; - float *innov2 = PUSH(tmp_stack, st->subframeSize, float); - for (i=0;isubframeSize;i++) - innov2[i]=0; - for (i=0;isubframeSize;i++) - target[i]*=2.2; - SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, - SUBMODE(innovation_params), st->lpcSize, st->subframeSize, - innov2, syn_resp, bits, tmp_stack, st->complexity); - for (i=0;isubframeSize;i++) - innov2[i]*=ener*(1/2.2); - for (i=0;isubframeSize;i++) - exc[i] += innov2[i]; - } - - for (i=0;isubframeSize;i++) - target[i]*=ener; - - } - - /*Keep the previous memory*/ - for (i=0;ilpcSize;i++) - mem[i]=st->mem_sp[i]; - /* Final signal synthesis from excitation */ - iir_mem2(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp); - - /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */ - filter_mem2(sp, st->bw_lpc1, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw); - for (i=0;isubframeSize;i++) - exc2[i]=exc[i]; - } - - /* Store the LSPs for interpolation in the next frame */ - if (st->submodeID>=1) - { - for (i=0;ilpcSize;i++) - st->old_lsp[i] = st->lsp[i]; - for (i=0;ilpcSize;i++) - st->old_qlsp[i] = st->qlsp[i]; - } - - if (st->submodeID==1) - { - if (st->dtx_count) - speex_bits_pack(bits, 15, 4); - else - speex_bits_pack(bits, 0, 4); - } - - /* The next frame will not be the first (Duh!) */ - st->first = 0; - - { - float ener=0, err=0; - float snr; - for (i=0;iframeSize;i++) - { - ener+=st->frame[i]*st->frame[i]; - err += (st->frame[i]-orig[i])*(st->frame[i]-orig[i]); - } - snr = 10*log10((ener+1)/(err+1)); - /*printf ("%f %f %f\n", snr, ener, err);*/ - } - - /* Replace input by synthesized speech */ - in[0] = st->frame[0] + st->preemph*st->pre_mem2; - for (i=1;iframeSize;i++) - in[i]=st->frame[i] + st->preemph*in[i-1]; - st->pre_mem2=in[st->frameSize-1]; - - if (SUBMODE(innovation_quant) == noise_codebook_quant || st->submodeID==0) - st->bounded_pitch = 1; - else - st->bounded_pitch = 0; - - return 1; -} - - -void *nb_decoder_init(SpeexMode *m) -{ - DecState *st; - SpeexNBMode *mode; - int i; - - mode=(SpeexNBMode*)m->mode; - st = (DecState *)speex_alloc(sizeof(DecState)+4000*sizeof(float)); - st->mode=m; - - st->stack = ((char*)st) + sizeof(DecState); - - st->first=1; - /* Codec parameters, should eventually have several "modes"*/ - st->frameSize = mode->frameSize; - st->windowSize = st->frameSize*3/2; - st->nbSubframes=mode->frameSize/mode->subframeSize; - st->subframeSize=mode->subframeSize; - st->lpcSize = mode->lpcSize; - st->bufSize = mode->bufSize; - st->gamma1=mode->gamma1; - st->gamma2=mode->gamma2; - st->min_pitch=mode->pitchStart; - st->max_pitch=mode->pitchEnd; - st->preemph = mode->preemph; - - st->submodes=mode->submodes; - st->submodeID=mode->defaultSubmode; - - st->pre_mem=0; - st->lpc_enh_enabled=0; - - - st->inBuf = PUSH(st->stack, st->bufSize, float); - st->frame = st->inBuf + st->bufSize - st->windowSize; - st->excBuf = PUSH(st->stack, st->bufSize, float); - st->exc = st->excBuf + st->bufSize - st->windowSize; - for (i=0;ibufSize;i++) - st->inBuf[i]=0; - for (i=0;ibufSize;i++) - st->excBuf[i]=0; - st->innov = PUSH(st->stack, st->frameSize, float); - - st->interp_qlpc = PUSH(st->stack, st->lpcSize+1, float); - st->qlsp = PUSH(st->stack, st->lpcSize, float); - st->old_qlsp = PUSH(st->stack, st->lpcSize, float); - st->interp_qlsp = PUSH(st->stack, st->lpcSize, float); - st->mem_sp = PUSH(st->stack, 5*st->lpcSize, float); - st->comb_mem = PUSHS(st->stack, CombFilterMem); - comp_filter_mem_init (st->comb_mem); - - st->pi_gain = PUSH(st->stack, st->nbSubframes, float); - st->last_pitch = 40; - st->count_lost=0; - st->pitch_gain_buf[0] = st->pitch_gain_buf[1] = st->pitch_gain_buf[2] = 0; - st->pitch_gain_buf_idx = 0; - - st->sampling_rate=8000; - st->last_ol_gain = 0; - - st->user_callback.func = &speex_default_user_handler; - st->user_callback.data = NULL; - for (i=0;i<16;i++) - st->speex_callbacks[i].func = NULL; - - st->voc_m1=st->voc_m2=st->voc_mean=0; - st->voc_offset=0; - st->dtx_enabled=0; - return st; -} - -void nb_decoder_destroy(void *state) -{ - DecState *st; - st=(DecState*)state; - - speex_free(state); -} - -#define median3(a, b, c) ((a) < (b) ? ((b) < (c) ? (b) : ((a) < (c) ? (c) : (a))) : ((c) < (b) ? (b) : ((c) < (a) ? (c) : (a)))) - -static void nb_decode_lost(DecState *st, float *out, char *stack) -{ - int i, sub; - float *awk1, *awk2, *awk3; - float pitch_gain, fact, gain_med; - - fact = exp(-.04*st->count_lost*st->count_lost); - gain_med = median3(st->pitch_gain_buf[0], st->pitch_gain_buf[1], st->pitch_gain_buf[2]); - if (gain_med < st->last_pitch_gain) - st->last_pitch_gain = gain_med; - - pitch_gain = st->last_pitch_gain; - if (pitch_gain>.95) - pitch_gain=.95; - - pitch_gain *= fact; - - /* Shift all buffers by one frame */ - speex_move(st->inBuf, st->inBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); - speex_move(st->excBuf, st->excBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); - - awk1=PUSH(stack, (st->lpcSize+1), float); - awk2=PUSH(stack, (st->lpcSize+1), float); - awk3=PUSH(stack, (st->lpcSize+1), float); - - for (sub=0;subnbSubframes;sub++) - { - int offset; - float *sp, *exc; - /* Offset relative to start of frame */ - offset = st->subframeSize*sub; - /* Original signal */ - sp=st->frame+offset; - /* Excitation */ - exc=st->exc+offset; - /* Excitation after post-filter*/ - - /* Calculate perceptually enhanced LPC filter */ - if (st->lpc_enh_enabled) - { - float r=.9; - - float k1,k2,k3; - if (st->submodes[st->submodeID] != NULL) - { - k1=SUBMODE(lpc_enh_k1); - k2=SUBMODE(lpc_enh_k2); - } else { - k1=k2=.7; - } - k3=(1-(1-r*k1)/(1-r*k2))/r; - if (!st->lpc_enh_enabled) - { - k1=k2; - k3=0; - } - bw_lpc(k1, st->interp_qlpc, awk1, st->lpcSize); - bw_lpc(k2, st->interp_qlpc, awk2, st->lpcSize); - bw_lpc(k3, st->interp_qlpc, awk3, st->lpcSize); - } - - /* Make up a plausible excitation */ - /* THIS CAN BE IMPROVED */ - /*if (pitch_gain>.95) - pitch_gain=.95;*/ - { - float innov_gain=0; - for (i=0;iframeSize;i++) - innov_gain += st->innov[i]*st->innov[i]; - innov_gain=sqrt(innov_gain/st->frameSize); - for (i=0;isubframeSize;i++) - { -#if 0 - exc[i] = pitch_gain * exc[i - st->last_pitch] + fact*sqrt(1-pitch_gain)*st->innov[i+offset]; - /*Just so it give the same lost packets as with if 0*/ - /*rand();*/ -#else - /*exc[i]=pitch_gain*exc[i-st->last_pitch] + fact*st->innov[i+offset];*/ - exc[i]=pitch_gain*exc[i-st->last_pitch] + - fact*sqrt(1-pitch_gain)*speex_rand(innov_gain); -#endif - } - } - for (i=0;isubframeSize;i++) - sp[i]=exc[i]; - - /* Signal synthesis */ - if (st->lpc_enh_enabled) - { - filter_mem2(sp, awk2, awk1, sp, st->subframeSize, st->lpcSize, - st->mem_sp+st->lpcSize); - filter_mem2(sp, awk3, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, - st->mem_sp); - } else { - for (i=0;ilpcSize;i++) - st->mem_sp[st->lpcSize+i] = 0; - iir_mem2(sp, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, - st->mem_sp); - } - } - - out[0] = st->frame[0] + st->preemph*st->pre_mem; - for (i=1;iframeSize;i++) - out[i]=st->frame[i] + st->preemph*out[i-1]; - st->pre_mem=out[st->frameSize-1]; - - st->first = 0; - st->count_lost++; - st->pitch_gain_buf[st->pitch_gain_buf_idx++] = pitch_gain; - if (st->pitch_gain_buf_idx > 2) /* rollover */ - st->pitch_gain_buf_idx = 0; -} - -int nb_decode(void *state, SpeexBits *bits, float *out) -{ - DecState *st; - int i, sub; - int pitch; - float pitch_gain[3]; - float ol_gain=0; - int ol_pitch=0; - float ol_pitch_coef=0; - int best_pitch=40; - float best_pitch_gain=0; - int wideband; - int m; - char *stack; - float *awk1, *awk2, *awk3; - float pitch_average=0; - - st=(DecState*)state; - stack=st->stack; - - /* Check if we're in DTX mode*/ - if (!bits && st->dtx_enabled) - { - st->submodeID=0; - } else - { - /* If bits is NULL, consider the packet to be lost (what could we do anyway) */ - if (!bits) - { - nb_decode_lost(st, out, stack); - return 0; - } - - /* Search for next narrowband block (handle requests, skip wideband blocks) */ - do { - wideband = speex_bits_unpack_unsigned(bits, 1); - if (wideband) /* Skip wideband block (for compatibility) */ - { - int submode; - int advance; - advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS); - speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance); - if (advance < 0) - { - speex_warning ("Invalid wideband mode encountered. Corrupted stream?"); - return -2; - } - advance -= (SB_SUBMODE_BITS+1); - speex_bits_advance(bits, advance); - wideband = speex_bits_unpack_unsigned(bits, 1); - if (wideband) - { - advance = submode = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS); - speex_mode_query(&speex_wb_mode, SPEEX_SUBMODE_BITS_PER_FRAME, &advance); - if (advance < 0) - { - speex_warning ("Invalid wideband mode encountered: corrupted stream?"); - return -2; - } - advance -= (SB_SUBMODE_BITS+1); - speex_bits_advance(bits, advance); - wideband = speex_bits_unpack_unsigned(bits, 1); - if (wideband) - { - speex_warning ("More than to wideband layers found: corrupted stream?"); - return -2; - } - - } - } - - /* FIXME: Check for overflow */ - m = speex_bits_unpack_unsigned(bits, 4); - if (m==15) /* We found a terminator */ - { - return -1; - } else if (m==14) /* Speex in-band request */ - { - int ret = speex_inband_handler(bits, st->speex_callbacks, state); - if (ret) - return ret; - } else if (m==13) /* User in-band request */ - { - int ret = st->user_callback.func(bits, state, st->user_callback.data); - if (ret) - return ret; - } else if (m>8) /* Invalid mode */ - { - speex_warning("Invalid mode encountered: corrupted stream?"); - return -2; - } - - } while (m>8); - - /* Get the sub-mode that was used */ - st->submodeID = m; - - } - - /* Shift all buffers by one frame */ - speex_move(st->inBuf, st->inBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); - speex_move(st->excBuf, st->excBuf+st->frameSize, (st->bufSize-st->frameSize)*sizeof(float)); - - /* If null mode (no transmission), just set a couple things to zero*/ - if (st->submodes[st->submodeID] == NULL) - { - float *lpc; - lpc = PUSH(stack,11, float); - bw_lpc(.93, st->interp_qlpc, lpc, 10); - /*for (i=0;iframeSize;i++) - st->exc[i]=0;*/ - { - float innov_gain=0; - float pgain=st->last_pitch_gain; - if (pgain>.6) - pgain=.6; - for (i=0;iframeSize;i++) - innov_gain += st->innov[i]*st->innov[i]; - innov_gain=sqrt(innov_gain/st->frameSize); - for (i=0;iframeSize;i++) - st->exc[i]=0; - speex_rand_vec(innov_gain, st->exc, st->frameSize); - } - - - st->first=1; - - /* Final signal synthesis from excitation */ - iir_mem2(st->exc, lpc, st->frame, st->frameSize, st->lpcSize, st->mem_sp); - - out[0] = st->frame[0] + st->preemph*st->pre_mem; - for (i=1;iframeSize;i++) - out[i]=st->frame[i] + st->preemph*out[i-1]; - st->pre_mem=out[st->frameSize-1]; - st->count_lost=0; - return 0; - } - - /* Unquantize LSPs */ - SUBMODE(lsp_unquant)(st->qlsp, st->lpcSize, bits); - - /*Damp memory if a frame was lost and the LSP changed too much*/ - if (st->count_lost) - { - float lsp_dist=0, fact; - for (i=0;ilpcSize;i++) - lsp_dist += fabs(st->old_qlsp[i] - st->qlsp[i]); - fact = .6*exp(-.2*lsp_dist); - for (i=0;i<2*st->lpcSize;i++) - st->mem_sp[i] *= fact; - } - - - /* Handle first frame and lost-packet case */ - if (st->first || st->count_lost) - { - for (i=0;ilpcSize;i++) - st->old_qlsp[i] = st->qlsp[i]; - } - - /* Get open-loop pitch estimation for low bit-rate pitch coding */ - if (SUBMODE(lbr_pitch)!=-1) - { - ol_pitch = st->min_pitch+speex_bits_unpack_unsigned(bits, 7); - } - - if (SUBMODE(forced_pitch_gain)) - { - int quant; - quant = speex_bits_unpack_unsigned(bits, 4); - ol_pitch_coef=0.066667*quant; - } - - /* Get global excitation gain */ - { - int qe; - qe = speex_bits_unpack_unsigned(bits, 5); - ol_gain = exp(qe/3.5); - } - - awk1=PUSH(stack, st->lpcSize+1, float); - awk2=PUSH(stack, st->lpcSize+1, float); - awk3=PUSH(stack, st->lpcSize+1, float); - - if (st->submodeID==1) - { - int extra; - extra = speex_bits_unpack_unsigned(bits, 4); - - if (extra==15) - st->dtx_enabled=1; - else - st->dtx_enabled=0; - } - if (st->submodeID>1) - st->dtx_enabled=0; - - /*Loop on subframes */ - for (sub=0;subnbSubframes;sub++) - { - int offset; - float *sp, *exc, tmp; - - /* Offset relative to start of frame */ - offset = st->subframeSize*sub; - /* Original signal */ - sp=st->frame+offset; - /* Excitation */ - exc=st->exc+offset; - /* Excitation after post-filter*/ - - /* LSP interpolation (quantized and unquantized) */ - tmp = (1.0 + sub)/st->nbSubframes; - for (i=0;ilpcSize;i++) - st->interp_qlsp[i] = (1-tmp)*st->old_qlsp[i] + tmp*st->qlsp[i]; - - /* Make sure the LSP's are stable */ - lsp_enforce_margin(st->interp_qlsp, st->lpcSize, .002); - - - /* Compute interpolated LPCs (unquantized) */ - for (i=0;ilpcSize;i++) - st->interp_qlsp[i] = cos(st->interp_qlsp[i]); - lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack); - - /* Compute enhanced synthesis filter */ - if (st->lpc_enh_enabled) - { - float r=.9; - - float k1,k2,k3; - k1=SUBMODE(lpc_enh_k1); - k2=SUBMODE(lpc_enh_k2); - k3=(1-(1-r*k1)/(1-r*k2))/r; - if (!st->lpc_enh_enabled) - { - k1=k2; - k3=0; - } - bw_lpc(k1, st->interp_qlpc, awk1, st->lpcSize); - bw_lpc(k2, st->interp_qlpc, awk2, st->lpcSize); - bw_lpc(k3, st->interp_qlpc, awk3, st->lpcSize); - - } - - /* Compute analysis filter at w=pi */ - tmp=1; - st->pi_gain[sub]=0; - for (i=0;i<=st->lpcSize;i++) - { - st->pi_gain[sub] += tmp*st->interp_qlpc[i]; - tmp = -tmp; - } - - /* Reset excitation */ - for (i=0;isubframeSize;i++) - exc[i]=0; - - /*Adaptive codebook contribution*/ - if (SUBMODE(ltp_unquant)) - { - int pit_min, pit_max; - /* Handle pitch constraints if any */ - if (SUBMODE(lbr_pitch) != -1) - { - int margin; - margin = SUBMODE(lbr_pitch); - if (margin) - { -/* GT - need optimization? - if (ol_pitch < st->min_pitch+margin-1) - ol_pitch=st->min_pitch+margin-1; - if (ol_pitch > st->max_pitch-margin) - ol_pitch=st->max_pitch-margin; - pit_min = ol_pitch-margin+1; - pit_max = ol_pitch+margin; -*/ - pit_min = ol_pitch-margin+1; - if (pit_min < st->min_pitch) - pit_min = st->min_pitch; - pit_max = ol_pitch+margin; - if (pit_max > st->max_pitch) - pit_max = st->max_pitch; - } else { - pit_min = pit_max = ol_pitch; - } - } else { - pit_min = st->min_pitch; - pit_max = st->max_pitch; - } - - /* Pitch synthesis */ - SUBMODE(ltp_unquant)(exc, pit_min, pit_max, ol_pitch_coef, SUBMODE(ltp_params), - st->subframeSize, &pitch, &pitch_gain[0], bits, stack, st->count_lost, offset, st->last_pitch_gain); - - /* If we had lost frames, check energy of last received frame */ - if (st->count_lost && ol_gain < st->last_ol_gain) - { - float fact = ol_gain/(st->last_ol_gain+1); - for (i=0;isubframeSize;i++) - exc[i]*=fact; - } - - tmp = fabs(pitch_gain[0]+pitch_gain[1]+pitch_gain[2]); - tmp = fabs(pitch_gain[1]); - if (pitch_gain[0]>0) - tmp += pitch_gain[0]; - else - tmp -= .5*pitch_gain[0]; - if (pitch_gain[2]>0) - tmp += pitch_gain[2]; - else - tmp -= .5*pitch_gain[0]; - - - pitch_average += tmp; - if (tmp>best_pitch_gain) - { - best_pitch = pitch; - best_pitch_gain = tmp; - /* best_pitch_gain = tmp*.9; - if (best_pitch_gain>.85) - best_pitch_gain=.85;*/ - } - } else { - speex_error("No pitch prediction, what's wrong"); - } - - /* Unquantize the innovation */ - { - int q_energy; - float ener; - float *innov; - - innov = st->innov+sub*st->subframeSize; - for (i=0;isubframeSize;i++) - innov[i]=0; - - /* Decode sub-frame gain correction */ - if (SUBMODE(have_subframe_gain)==3) - { - q_energy = speex_bits_unpack_unsigned(bits, 3); - ener = ol_gain*exp(exc_gain_quant_scal3[q_energy]); - } else if (SUBMODE(have_subframe_gain)==1) - { - q_energy = speex_bits_unpack_unsigned(bits, 1); - ener = ol_gain*exp(exc_gain_quant_scal1[q_energy]); - } else { - ener = ol_gain; - } - - if (SUBMODE(innovation_unquant)) - { - /*Fixed codebook contribution*/ - SUBMODE(innovation_unquant)(innov, SUBMODE(innovation_params), st->subframeSize, bits, stack); - } else { - speex_error("No fixed codebook"); - } - - /* De-normalize innovation and update excitation */ - for (i=0;isubframeSize;i++) - innov[i]*=ener; - - /*Vocoder mode*/ - if (st->submodeID==1) - { - float g=ol_pitch_coef; - - - for (i=0;isubframeSize;i++) - exc[i]=0; - while (st->voc_offsetsubframeSize) - { - if (st->voc_offset>=0) - exc[st->voc_offset]=sqrt(1.0*ol_pitch); - st->voc_offset+=ol_pitch; - } - st->voc_offset -= st->subframeSize; - - g=.5+2*(g-.6); - if (g<0) - g=0; - if (g>1) - g=1; - for (i=0;isubframeSize;i++) - { - float exci=exc[i]; - exc[i]=.8*g*exc[i]*ol_gain + .6*g*st->voc_m1*ol_gain + .5*g*innov[i] - .5*g*st->voc_m2 + (1-g)*innov[i]; - st->voc_m1 = exci; - st->voc_m2=innov[i]; - st->voc_mean = .95*st->voc_mean + .05*exc[i]; - exc[i]-=st->voc_mean; - } - } else { - for (i=0;isubframeSize;i++) - exc[i]+=innov[i]; - } - /* Decode second codebook (only for some modes) */ - if (SUBMODE(double_codebook)) - { - char *tmp_stack=stack; - float *innov2 = PUSH(tmp_stack, st->subframeSize, float); - for (i=0;isubframeSize;i++) - innov2[i]=0; - SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize, bits, tmp_stack); - for (i=0;isubframeSize;i++) - innov2[i]*=ener*(1/2.2); - for (i=0;isubframeSize;i++) - exc[i] += innov2[i]; - } - - } - - for (i=0;isubframeSize;i++) - sp[i]=exc[i]; - - /* Signal synthesis */ - if (st->lpc_enh_enabled && SUBMODE(comb_gain)>0) - comb_filter(exc, sp, st->interp_qlpc, st->lpcSize, st->subframeSize, - pitch, pitch_gain, SUBMODE(comb_gain), st->comb_mem); - if (st->lpc_enh_enabled) - { - /* Use enhanced LPC filter */ - filter_mem2(sp, awk2, awk1, sp, st->subframeSize, st->lpcSize, - st->mem_sp+st->lpcSize); - filter_mem2(sp, awk3, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, - st->mem_sp); - } else { - /* Use regular filter */ - for (i=0;ilpcSize;i++) - st->mem_sp[st->lpcSize+i] = 0; - iir_mem2(sp, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, - st->mem_sp); - } - } - - /*Copy output signal*/ - out[0] = st->frame[0] + st->preemph*st->pre_mem; - for (i=1;iframeSize;i++) - out[i]=st->frame[i] + st->preemph*out[i-1]; - st->pre_mem=out[st->frameSize-1]; - - - /* Store the LSPs for interpolation in the next frame */ - for (i=0;ilpcSize;i++) - st->old_qlsp[i] = st->qlsp[i]; - - /* The next frame will not be the first (Duh!) */ - st->first = 0; - st->count_lost=0; - st->last_pitch = best_pitch; - st->last_pitch_gain = .25*pitch_average; - st->pitch_gain_buf[st->pitch_gain_buf_idx++] = st->last_pitch_gain; - if (st->pitch_gain_buf_idx > 2) /* rollover */ - st->pitch_gain_buf_idx = 0; - - st->last_ol_gain = ol_gain; - - return 0; -} - -int nb_encoder_ctl(void *state, int request, void *ptr) -{ - EncState *st; - st=(EncState*)state; - switch(request) - { - case SPEEX_GET_FRAME_SIZE: - (*(int*)ptr) = st->frameSize; - break; - case SPEEX_SET_LOW_MODE: - case SPEEX_SET_MODE: - st->submodeSelect = st->submodeID = (*(int*)ptr); - break; - case SPEEX_GET_LOW_MODE: - case SPEEX_GET_MODE: - (*(int*)ptr) = st->submodeID; - break; - case SPEEX_SET_VBR: - st->vbr_enabled = (*(int*)ptr); - break; - case SPEEX_GET_VBR: - (*(int*)ptr) = st->vbr_enabled; - break; - case SPEEX_SET_VAD: - st->vad_enabled = (*(int*)ptr); - break; - case SPEEX_GET_VAD: - (*(int*)ptr) = st->vad_enabled; - break; - case SPEEX_SET_DTX: - st->dtx_enabled = (*(int*)ptr); - break; - case SPEEX_GET_DTX: - (*(int*)ptr) = st->dtx_enabled; - break; - case SPEEX_SET_ABR: - st->abr_enabled = (*(int*)ptr); - st->vbr_enabled = 1; - { - int i=10, rate, target; - float vbr_qual; - target = (*(int*)ptr); - while (i>=0) - { - speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i); - speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate); - if (rate <= target) - break; - i--; - } - vbr_qual=i; - if (vbr_qual<0) - vbr_qual=0; - speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_qual); - st->abr_count=0; - st->abr_drift=0; - st->abr_drift2=0; - } - - break; - case SPEEX_GET_ABR: - (*(int*)ptr) = st->abr_enabled; - break; - case SPEEX_SET_VBR_QUALITY: - st->vbr_quality = (*(float*)ptr); - break; - case SPEEX_GET_VBR_QUALITY: - (*(float*)ptr) = st->vbr_quality; - break; - case SPEEX_SET_QUALITY: - { - int quality = (*(int*)ptr); - if (quality < 0) - quality = 0; - if (quality > 10) - quality = 10; - st->submodeSelect = st->submodeID = ((SpeexNBMode*)(st->mode->mode))->quality_map[quality]; - } - break; - case SPEEX_SET_COMPLEXITY: - st->complexity = (*(int*)ptr); - if (st->complexity<1) - st->complexity=1; - break; - case SPEEX_GET_COMPLEXITY: - (*(int*)ptr) = st->complexity; - break; - case SPEEX_SET_BITRATE: - { - int i=10, rate, target; - target = (*(int*)ptr); - while (i>=0) - { - speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i); - speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate); - if (rate <= target) - break; - i--; - } - } - break; - case SPEEX_GET_BITRATE: - if (st->submodes[st->submodeID]) - (*(int*)ptr) = st->sampling_rate*SUBMODE(bits_per_frame)/st->frameSize; - else - (*(int*)ptr) = st->sampling_rate*(NB_SUBMODE_BITS+1)/st->frameSize; - break; - case SPEEX_SET_SAMPLING_RATE: - st->sampling_rate = (*(int*)ptr); - break; - case SPEEX_GET_SAMPLING_RATE: - (*(int*)ptr)=st->sampling_rate; - break; - case SPEEX_RESET_STATE: - { - int i; - st->bounded_pitch = 1; - st->first = 1; - for (i=0;ilpcSize;i++) - st->lsp[i]=(M_PI*((float)(i+1)))/(st->lpcSize+1); - for (i=0;ilpcSize;i++) - st->mem_sw[i]=st->mem_sw_whole[i]=st->mem_sp[i]=st->mem_exc[i]=0; - for (i=0;ibufSize;i++) - st->excBuf[i]=st->swBuf[i]=st->inBuf[i]=st->exc2Buf[i]=0; - } - break; - case SPEEX_GET_PI_GAIN: - { - int i; - float *g = (float*)ptr; - for (i=0;inbSubframes;i++) - g[i]=st->pi_gain[i]; - } - break; - case SPEEX_GET_EXC: - { - int i; - float *e = (float*)ptr; - for (i=0;iframeSize;i++) - e[i]=st->exc[i]; - } - break; - case SPEEX_GET_INNOV: - { - int i; - float *e = (float*)ptr; - for (i=0;iframeSize;i++) - e[i]=st->innov[i]; - } - break; - case SPEEX_GET_RELATIVE_QUALITY: - (*(float*)ptr)=st->relative_quality; - break; - default: - speex_warning_int("Unknown nb_ctl request: ", request); - return -1; - } - return 0; -} - -int nb_decoder_ctl(void *state, int request, void *ptr) -{ - DecState *st; - st=(DecState*)state; - switch(request) - { - case SPEEX_GET_LOW_MODE: - case SPEEX_GET_MODE: - (*(int*)ptr) = st->submodeID; - break; - case SPEEX_SET_ENH: - st->lpc_enh_enabled = *((int*)ptr); - break; - case SPEEX_GET_ENH: - *((int*)ptr) = st->lpc_enh_enabled; - break; - case SPEEX_GET_FRAME_SIZE: - (*(int*)ptr) = st->frameSize; - break; - case SPEEX_GET_BITRATE: - if (st->submodes[st->submodeID]) - (*(int*)ptr) = st->sampling_rate*SUBMODE(bits_per_frame)/st->frameSize; - else - (*(int*)ptr) = st->sampling_rate*(NB_SUBMODE_BITS+1)/st->frameSize; - break; - case SPEEX_SET_SAMPLING_RATE: - st->sampling_rate = (*(int*)ptr); - break; - case SPEEX_GET_SAMPLING_RATE: - (*(int*)ptr)=st->sampling_rate; - break; - case SPEEX_SET_HANDLER: - { - SpeexCallback *c = (SpeexCallback*)ptr; - st->speex_callbacks[c->callback_id].func=c->func; - st->speex_callbacks[c->callback_id].data=c->data; - st->speex_callbacks[c->callback_id].callback_id=c->callback_id; - } - break; - case SPEEX_SET_USER_HANDLER: - { - SpeexCallback *c = (SpeexCallback*)ptr; - st->user_callback.func=c->func; - st->user_callback.data=c->data; - st->user_callback.callback_id=c->callback_id; - } - break; - case SPEEX_RESET_STATE: - { - int i; - for (i=0;i<2*st->lpcSize;i++) - st->mem_sp[i]=0; - for (i=0;ibufSize;i++) - st->excBuf[i]=st->inBuf[i]=0; - } - break; - case SPEEX_GET_PI_GAIN: - { - int i; - float *g = (float*)ptr; - for (i=0;inbSubframes;i++) - g[i]=st->pi_gain[i]; - } - break; - case SPEEX_GET_EXC: - { - int i; - float *e = (float*)ptr; - for (i=0;iframeSize;i++) - e[i]=st->exc[i]; - } - break; - case SPEEX_GET_INNOV: - { - int i; - float *e = (float*)ptr; - for (i=0;iframeSize;i++) - e[i]=st->innov[i]; - } - break; - case SPEEX_GET_DTX_STATUS: - *((int*)ptr) = st->dtx_enabled; - break; - default: - speex_warning_int("Unknown nb_ctl request: ", request); - return -1; - } - return 0; -} diff --git a/engine/voice_codecs/speex/source/libspeex/nb_celp.h b/engine/voice_codecs/speex/source/libspeex/nb_celp.h deleted file mode 100644 index 7439f1c7..00000000 --- a/engine/voice_codecs/speex/source/libspeex/nb_celp.h +++ /dev/null @@ -1,202 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin */ -/** - @file nb_celp.h - @brief Narrowband CELP encoder/decoder -*/ -/* - 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. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - 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 FOUNDATION 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 NB_CELP_H -#define NB_CELP_H - -#include "modes.h" -#include "speex_bits.h" -#include "speex_callbacks.h" -#include "vbr.h" -#include "filters.h" - -/**Structure representing the full state of the narrowband encoder*/ -typedef struct EncState { - SpeexMode *mode; /**< Mode corresponding to the state */ - int first; /**< Is this the first frame? */ - int frameSize; /**< Size of frames */ - int subframeSize; /**< Size of sub-frames */ - int nbSubframes; /**< Number of sub-frames */ - int windowSize; /**< Analysis (LPC) window length */ - int lpcSize; /**< LPC order */ - int bufSize; /**< Buffer size */ - int min_pitch; /**< Minimum pitch value allowed */ - int max_pitch; /**< Maximum pitch value allowed */ - - int safe_pitch; /**< Don't use too large values for pitch (in case we lose a packet) */ - int bounded_pitch; /**< Next frame should not rely on previous frames for pitch */ - int ol_pitch; /**< Open-loop pitch */ - int ol_voiced; /**< Open-loop voiced/non-voiced decision */ - int *pitch; - float gamma1; /**< Perceptual filter: A(z/gamma1) */ - float gamma2; /**< Perceptual filter: A(z/gamma2) */ - float lag_factor; /**< Lag windowing Gaussian width */ - float lpc_floor; /**< Noise floor multiplier for A[0] in LPC analysis*/ - float preemph; /**< Pre-emphasis: P(z) = 1 - a*z^-1*/ - float pre_mem; /**< 1-element memory for pre-emphasis */ - float pre_mem2; /**< 1-element memory for pre-emphasis */ - char *stack; /**< Pseudo-stack allocation for temporary memory */ - float *inBuf; /**< Input buffer (original signal) */ - float *frame; /**< Start of original frame */ - float *excBuf; /**< Excitation buffer */ - float *exc; /**< Start of excitation frame */ - float *exc2Buf; /**< "Pitch enhanced" excitation */ - float *exc2; /**< "Pitch enhanced" excitation */ - float *swBuf; /**< Weighted signal buffer */ - float *sw; /**< Start of weighted signal frame */ - float *innov; /**< Innovation for the frame */ - float *window; /**< Temporary (Hanning) window */ - float *buf2; /**< 2nd temporary buffer */ - float *autocorr; /**< auto-correlation */ - float *lagWindow; /**< Window applied to auto-correlation */ - float *lpc; /**< LPCs for current frame */ - float *lsp; /**< LSPs for current frame */ - float *qlsp; /**< Quantized LSPs for current frame */ - float *old_lsp; /**< LSPs for previous frame */ - float *old_qlsp; /**< Quantized LSPs for previous frame */ - float *interp_lsp; /**< Interpolated LSPs */ - float *interp_qlsp; /**< Interpolated quantized LSPs */ - float *interp_lpc; /**< Interpolated LPCs */ - float *interp_qlpc; /**< Interpolated quantized LPCs */ - float *bw_lpc1; /**< LPCs after bandwidth expansion by gamma1 for perceptual weighting*/ - float *bw_lpc2; /**< LPCs after bandwidth expansion by gamma2 for perceptual weighting*/ - float *rc; /**< Reflection coefficients */ - float *mem_sp; /**< Filter memory for signal synthesis */ - float *mem_sw; /**< Filter memory for perceptually-weighted signal */ - float *mem_sw_whole; /**< Filter memory for perceptually-weighted signal (whole frame)*/ - float *mem_exc; /**< Filter memory for excitation (whole frame) */ - float *pi_gain; /**< Gain of LPC filter at theta=pi (fe/2) */ - - VBRState *vbr; /**< State of the VBR data */ - float vbr_quality; /**< Quality setting for VBR encoding */ - float relative_quality; /**< Relative quality that will be needed by VBR */ - int vbr_enabled; /**< 1 for enabling VBR, 0 otherwise */ - int vad_enabled; /**< 1 for enabling VAD, 0 otherwise */ - int dtx_enabled; /**< 1 for enabling DTX, 0 otherwise */ - int dtx_count; /**< Number of consecutive DTX frames */ - int abr_enabled; /**< ABR setting (in bps), 0 if off */ - float abr_drift; - float abr_drift2; - float abr_count; - int complexity; /**< Complexity setting (0-10 from least complex to most complex) */ - int sampling_rate; - - SpeexSubmode **submodes; /**< Sub-mode data */ - int submodeID; /**< Activated sub-mode */ - int submodeSelect; /**< Mode chosen by the user (may differ from submodeID if VAD is on) */ -} EncState; - -/**Structure representing the full state of the narrowband decoder*/ -typedef struct DecState { - SpeexMode *mode; /**< Mode corresponding to the state */ - int first; /**< Is this the first frame? */ - int count_lost; /**< Was the last frame lost? */ - int frameSize; /**< Size of frames */ - int subframeSize; /**< Size of sub-frames */ - int nbSubframes; /**< Number of sub-frames */ - int windowSize; /**< Analysis (LPC) window length */ - int lpcSize; /**< LPC order */ - int bufSize; /**< Buffer size */ - int min_pitch; /**< Minimum pitch value allowed */ - int max_pitch; /**< Maximum pitch value allowed */ - int sampling_rate; - float last_ol_gain; /**< Open-loop gain for previous frame */ - - - float gamma1; /**< Perceptual filter: A(z/gamma1) */ - float gamma2; /**< Perceptual filter: A(z/gamma2) */ - float preemph; /**< Pre-emphasis: P(z) = 1 - a*z^-1*/ - float pre_mem; /**< 1-element memory for pre-emphasis */ - char *stack; /**< Pseudo-stack allocation for temporary memory */ - float *inBuf; /**< Input buffer (original signal) */ - float *frame; /**< Start of original frame */ - float *excBuf; /**< Excitation buffer */ - float *exc; /**< Start of excitation frame */ - float *innov; /**< Innovation for the frame */ - float *qlsp; /**< Quantized LSPs for current frame */ - float *old_qlsp; /**< Quantized LSPs for previous frame */ - float *interp_qlsp; /**< Interpolated quantized LSPs */ - float *interp_qlpc; /**< Interpolated quantized LPCs */ - float *mem_sp; /**< Filter memory for synthesis signal */ - float *pi_gain; /**< Gain of LPC filter at theta=pi (fe/2) */ - int last_pitch; /**< Pitch of last correctly decoded frame */ - float last_pitch_gain; /**< Pitch gain of last correctly decoded frame */ - float pitch_gain_buf[3]; /**< Pitch gain of last decoded frames */ - int pitch_gain_buf_idx; /**< Tail of the buffer */ - - SpeexSubmode **submodes; /**< Sub-mode data */ - int submodeID; /**< Activated sub-mode */ - int lpc_enh_enabled; /**< 1 when LPC enhancer is on, 0 otherwise */ - CombFilterMem *comb_mem; - SpeexCallback speex_callbacks[SPEEX_MAX_CALLBACKS]; - - SpeexCallback user_callback; - - /*Vocoder data*/ - float voc_m1; - float voc_m2; - float voc_mean; - int voc_offset; - - int dtx_enabled; -} DecState; - -/** Initializes encoder state*/ -void *nb_encoder_init(SpeexMode *m); - -/** De-allocates encoder state resources*/ -void nb_encoder_destroy(void *state); - -/** Encodes one frame*/ -int nb_encode(void *state, float *in, SpeexBits *bits); - - -/** Initializes decoder state*/ -void *nb_decoder_init(SpeexMode *m); - -/** De-allocates decoder state resources*/ -void nb_decoder_destroy(void *state); - -/** Decodes one frame*/ -int nb_decode(void *state, SpeexBits *bits, float *out); - -/** ioctl-like function for controlling a narrowband encoder */ -int nb_encoder_ctl(void *state, int request, void *ptr); - -/** ioctl-like function for controlling a narrowband decoder */ -int nb_decoder_ctl(void *state, int request, void *ptr); - - -#endif diff --git a/engine/voice_codecs/speex/source/libspeex/quant_lsp.c b/engine/voice_codecs/speex/source/libspeex/quant_lsp.c deleted file mode 100644 index c9d797e4..00000000 --- a/engine/voice_codecs/speex/source/libspeex/quant_lsp.c +++ /dev/null @@ -1,311 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: quant_lsp.c - LSP vector quantization - - 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. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - 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 FOUNDATION 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. -*/ - -#include "quant_lsp.h" -#include - -extern int lsp_nb_vqid[64]; -static float quant_weight[MAX_LSP_SIZE]; - -/* Note: x is modified*/ -static int lsp_quant(float *x, signed char *cdbk, int nbVec, int nbDim) -{ - int i,j; - float dist, tmp; - float best_dist=0; - int best_id=0; - signed char *ptr=cdbk; - for (i=0;i tmp2 ? tmp1 : tmp2; - } - for (i=0;i tmp2 ? tmp1 : tmp2; - } - - for (i=0;i tmp2 ? tmp1 : tmp2; - } - - for (i=0;i -#include "sb_celp.h" -#include "stdlib.h" -#include "filters.h" -#include "lpc.h" -#include "lsp.h" -#include "stack_alloc.h" -#include "cb_search.h" -#include "quant_lsp.h" -#include "vq.h" -#include "ltp.h" -#include "misc.h" - -#ifndef M_PI -#define M_PI 3.14159265358979323846 /* pi */ -#endif - -#define sqr(x) ((x)*(x)) - -#define SUBMODE(x) st->submodes[st->submodeID]->x - -#define QMF_ORDER 64 -static float h0[64] = { - 3.596189e-05, -0.0001123515, - -0.0001104587, 0.0002790277, - 0.0002298438, -0.0005953563, - -0.0003823631, 0.00113826, - 0.0005308539, -0.001986177, - -0.0006243724, 0.003235877, - 0.0005743159, -0.004989147, - -0.0002584767, 0.007367171, - -0.0004857935, -0.01050689, - 0.001894714, 0.01459396, - -0.004313674, -0.01994365, - 0.00828756, 0.02716055, - -0.01485397, -0.03764973, - 0.026447, 0.05543245, - -0.05095487, -0.09779096, - 0.1382363, 0.4600981, - 0.4600981, 0.1382363, - -0.09779096, -0.05095487, - 0.05543245, 0.026447, - -0.03764973, -0.01485397, - 0.02716055, 0.00828756, - -0.01994365, -0.004313674, - 0.01459396, 0.001894714, - -0.01050689, -0.0004857935, - 0.007367171, -0.0002584767, - -0.004989147, 0.0005743159, - 0.003235877, -0.0006243724, - -0.001986177, 0.0005308539, - 0.00113826, -0.0003823631, - -0.0005953563, 0.0002298438, - 0.0002790277, -0.0001104587, - -0.0001123515, 3.596189e-05 -}; - -static float h1[64] = { - 3.596189e-05, 0.0001123515, - -0.0001104587, -0.0002790277, - 0.0002298438, 0.0005953563, - -0.0003823631, -0.00113826, - 0.0005308539, 0.001986177, - -0.0006243724, -0.003235877, - 0.0005743159, 0.004989147, - -0.0002584767, -0.007367171, - -0.0004857935, 0.01050689, - 0.001894714, -0.01459396, - -0.004313674, 0.01994365, - 0.00828756, -0.02716055, - -0.01485397, 0.03764973, - 0.026447, -0.05543245, - -0.05095487, 0.09779096, - 0.1382363, -0.4600981, - 0.4600981, -0.1382363, - -0.09779096, 0.05095487, - 0.05543245, -0.026447, - -0.03764973, 0.01485397, - 0.02716055, -0.00828756, - -0.01994365, 0.004313674, - 0.01459396, -0.001894714, - -0.01050689, 0.0004857935, - 0.007367171, 0.0002584767, - -0.004989147, -0.0005743159, - 0.003235877, 0.0006243724, - -0.001986177, -0.0005308539, - 0.00113826, 0.0003823631, - -0.0005953563, -0.0002298438, - 0.0002790277, 0.0001104587, - -0.0001123515, -3.596189e-05 -}; - -void *sb_encoder_init(SpeexMode *m) -{ - int i; - SBEncState *st; - SpeexSBMode *mode; - - st = (SBEncState*)speex_alloc(sizeof(SBEncState)+8000*sizeof(float)); - st->mode = m; - mode = (SpeexSBMode*)m->mode; - - st->stack = ((char*)st) + sizeof(SBEncState); - - st->st_low = speex_encoder_init(mode->nb_mode); - st->full_frame_size = 2*mode->frameSize; - st->frame_size = mode->frameSize; - st->subframeSize = mode->subframeSize; - st->nbSubframes = mode->frameSize/mode->subframeSize; - st->windowSize = st->frame_size*3/2; - st->lpcSize=mode->lpcSize; - st->bufSize=mode->bufSize; - - st->submodes=mode->submodes; - st->submodeSelect = st->submodeID=mode->defaultSubmode; - - i=9; - speex_encoder_ctl(st->st_low, SPEEX_SET_QUALITY, &i); - - st->lag_factor = mode->lag_factor; - st->lpc_floor = mode->lpc_floor; - st->gamma1=mode->gamma1; - st->gamma2=mode->gamma2; - st->first=1; - - st->x0d=PUSH(st->stack, st->frame_size, float); - st->x1d=PUSH(st->stack, st->frame_size, float); - st->high=PUSH(st->stack, st->full_frame_size, float); - st->y0=PUSH(st->stack, st->full_frame_size, float); - st->y1=PUSH(st->stack, st->full_frame_size, float); - - st->h0_mem=PUSH(st->stack, QMF_ORDER, float); - st->h1_mem=PUSH(st->stack, QMF_ORDER, float); - st->g0_mem=PUSH(st->stack, QMF_ORDER, float); - st->g1_mem=PUSH(st->stack, QMF_ORDER, float); - - st->buf=PUSH(st->stack, st->windowSize, float); - st->excBuf=PUSH(st->stack, st->bufSize, float); - st->exc = st->excBuf + st->bufSize - st->windowSize; - - st->res=PUSH(st->stack, st->frame_size, float); - st->sw=PUSH(st->stack, st->frame_size, float); - st->target=PUSH(st->stack, st->frame_size, float); - /*Asymmetric "pseudo-Hamming" window*/ - { - int part1, part2; - part1 = st->subframeSize*7/2; - part2 = st->subframeSize*5/2; - st->window = PUSH(st->stack, st->windowSize, float); - for (i=0;iwindow[i]=.54-.46*cos(M_PI*i/part1); - for (i=0;iwindow[part1+i]=.54+.46*cos(M_PI*i/part2); - } - - st->lagWindow = PUSH(st->stack, st->lpcSize+1, float); - for (i=0;ilpcSize+1;i++) - st->lagWindow[i]=exp(-.5*sqr(2*M_PI*st->lag_factor*i)); - - st->rc = PUSH(st->stack, st->lpcSize, float); - st->autocorr = PUSH(st->stack, st->lpcSize+1, float); - st->lpc = PUSH(st->stack, st->lpcSize+1, float); - st->bw_lpc1 = PUSH(st->stack, st->lpcSize+1, float); - st->bw_lpc2 = PUSH(st->stack, st->lpcSize+1, float); - st->lsp = PUSH(st->stack, st->lpcSize, float); - st->qlsp = PUSH(st->stack, st->lpcSize, float); - st->old_lsp = PUSH(st->stack, st->lpcSize, float); - st->old_qlsp = PUSH(st->stack, st->lpcSize, float); - st->interp_lsp = PUSH(st->stack, st->lpcSize, float); - st->interp_qlsp = PUSH(st->stack, st->lpcSize, float); - st->interp_lpc = PUSH(st->stack, st->lpcSize+1, float); - st->interp_qlpc = PUSH(st->stack, st->lpcSize+1, float); - st->pi_gain = PUSH(st->stack, st->nbSubframes, float); - - st->mem_sp = PUSH(st->stack, st->lpcSize, float); - st->mem_sp2 = PUSH(st->stack, st->lpcSize, float); - st->mem_sw = PUSH(st->stack, st->lpcSize, float); - - st->vbr_quality = 8; - st->vbr_enabled = 0; - st->vad_enabled = 0; - st->abr_enabled = 0; - st->relative_quality=0; - - st->complexity=2; - speex_decoder_ctl(st->st_low, SPEEX_GET_SAMPLING_RATE, &st->sampling_rate); - st->sampling_rate*=2; - - return st; -} - -void sb_encoder_destroy(void *state) -{ - SBEncState *st=(SBEncState*)state; - - speex_encoder_destroy(st->st_low); - - speex_free(st); -} - - -int sb_encode(void *state, float *in, SpeexBits *bits) -{ - SBEncState *st; - int i, roots, sub; - char *stack; - float *mem, *innov, *syn_resp; - float *low_pi_gain, *low_exc, *low_innov; - SpeexSBMode *mode; - int dtx; - - st = (SBEncState*)state; - stack=st->stack; - mode = (SpeexSBMode*)(st->mode->mode); - - /* Compute the two sub-bands by filtering with h0 and h1*/ - qmf_decomp(in, h0, st->x0d, st->x1d, st->full_frame_size, QMF_ORDER, st->h0_mem, stack); - - /* Encode the narrowband part*/ - speex_encode(st->st_low, st->x0d, bits); - - /* High-band buffering / sync with low band */ - for (i=0;iwindowSize-st->frame_size;i++) - st->high[i] = st->high[st->frame_size+i]; - for (i=0;iframe_size;i++) - st->high[st->windowSize-st->frame_size+i]=st->x1d[i]; - - speex_move(st->excBuf, st->excBuf+st->frame_size, (st->bufSize-st->frame_size)*sizeof(float)); - - - low_pi_gain = PUSH(stack, st->nbSubframes, float); - low_exc = PUSH(stack, st->frame_size, float); - low_innov = PUSH(stack, st->frame_size, float); - speex_encoder_ctl(st->st_low, SPEEX_GET_PI_GAIN, low_pi_gain); - speex_encoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc); - speex_encoder_ctl(st->st_low, SPEEX_GET_INNOV, low_innov); - - speex_encoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, &dtx); - - if (dtx==0) - dtx=1; - else - dtx=0; - - /* Start encoding the high-band */ - for (i=0;iwindowSize;i++) - st->buf[i] = st->high[i] * st->window[i]; - - /* Compute auto-correlation */ - _spx_autocorr(st->buf, st->autocorr, st->lpcSize+1, st->windowSize); - - st->autocorr[0] += 1; /* prevents NANs */ - st->autocorr[0] *= st->lpc_floor; /* Noise floor in auto-correlation domain */ - /* Lag windowing: equivalent to filtering in the power-spectrum domain */ - for (i=0;ilpcSize+1;i++) - st->autocorr[i] *= st->lagWindow[i]; - - /* Levinson-Durbin */ - wld(st->lpc+1, st->autocorr, st->rc, st->lpcSize); - st->lpc[0]=1; - - /* LPC to LSPs (x-domain) transform */ - roots=lpc_to_lsp (st->lpc, st->lpcSize, st->lsp, 15, 0.2, stack); - if (roots!=st->lpcSize) - { - roots = lpc_to_lsp (st->lpc, st->lpcSize, st->lsp, 11, 0.02, stack); - if (roots!=st->lpcSize) { - /*If we can't find all LSP's, do some damage control and use a flat filter*/ - for (i=0;ilpcSize;i++) - { - st->lsp[i]=cos(M_PI*((float)(i+1))/(st->lpcSize+1)); - } - } - } - - /* x-domain to angle domain*/ - for (i=0;ilpcSize;i++) - st->lsp[i] = acos(st->lsp[i]); - - /* VBR code */ - if ((st->vbr_enabled || st->vad_enabled) && !dtx) - { - float e_low=0, e_high=0; - float ratio; - if (st->abr_enabled) - { - float qual_change=0; - if (st->abr_drift2 * st->abr_drift > 0) - { - /* Only adapt if long-term and short-term drift are the same sign */ - qual_change = -.00001*st->abr_drift/(1+st->abr_count); - if (qual_change>.1) - qual_change=.1; - if (qual_change<-.1) - qual_change=-.1; - } - st->vbr_quality += qual_change; - if (st->vbr_quality>10) - st->vbr_quality=10; - if (st->vbr_quality<0) - st->vbr_quality=0; - } - - - for (i=0;iframe_size;i++) - { - e_low += st->x0d[i]* st->x0d[i]; - e_high += st->high[i]* st->high[i]; - } - ratio = log((1+e_high)/(1+e_low)); - speex_encoder_ctl(st->st_low, SPEEX_GET_RELATIVE_QUALITY, &st->relative_quality); - if (ratio<-4) - ratio=-4; - if (ratio>2) - ratio=2; - /*if (ratio>-2)*/ - if (st->vbr_enabled) - { - int modeid; - modeid = mode->nb_modes-1; - st->relative_quality+=1.0*(ratio+2); - if (st->relative_quality<-1) - st->relative_quality=-1; - while (modeid) - { - int v1; - float thresh; - v1=(int)floor(st->vbr_quality); - if (v1==10) - thresh = mode->vbr_thresh[modeid][v1]; - else - thresh = (st->vbr_quality-v1) * mode->vbr_thresh[modeid][v1+1] + - (1+v1-st->vbr_quality) * mode->vbr_thresh[modeid][v1]; - if (st->relative_quality >= thresh) - break; - modeid--; - } - speex_encoder_ctl(state, SPEEX_SET_HIGH_MODE, &modeid); - if (st->abr_enabled) - { - int bitrate; - speex_encoder_ctl(state, SPEEX_GET_BITRATE, &bitrate); - st->abr_drift+=(bitrate-st->abr_enabled); - st->abr_drift2 = .95*st->abr_drift2 + .05*(bitrate-st->abr_enabled); - st->abr_count += 1.0; - } - - } else { - /* VAD only */ - int modeid; - if (st->relative_quality<2.0) - modeid=1; - else - modeid=st->submodeSelect; - /*speex_encoder_ctl(state, SPEEX_SET_MODE, &mode);*/ - st->submodeID=modeid; - - } - /*fprintf (stderr, "%f %f\n", ratio, low_qual);*/ - } - - speex_bits_pack(bits, 1, 1); - if (dtx) - speex_bits_pack(bits, 0, SB_SUBMODE_BITS); - else - speex_bits_pack(bits, st->submodeID, SB_SUBMODE_BITS); - - /* If null mode (no transmission), just set a couple things to zero*/ - if (dtx || st->submodes[st->submodeID] == NULL) - { - for (i=0;iframe_size;i++) - st->exc[i]=st->sw[i]=0; - - for (i=0;ilpcSize;i++) - st->mem_sw[i]=0; - st->first=1; - - /* Final signal synthesis from excitation */ - iir_mem2(st->exc, st->interp_qlpc, st->high, st->subframeSize, st->lpcSize, st->mem_sp); - -#ifndef RELEASE - - /* Reconstruct the original */ - fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack); - fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack); - - for (i=0;ifull_frame_size;i++) - in[i]=2*(st->y0[i]-st->y1[i]); -#endif - - if (dtx) - return 0; - else - return 1; - } - - - /* LSP quantization */ - SUBMODE(lsp_quant)(st->lsp, st->qlsp, st->lpcSize, bits); - - if (st->first) - { - for (i=0;ilpcSize;i++) - st->old_lsp[i] = st->lsp[i]; - for (i=0;ilpcSize;i++) - st->old_qlsp[i] = st->qlsp[i]; - } - - mem=PUSH(stack, st->lpcSize, float); - syn_resp=PUSH(stack, st->subframeSize, float); - innov = PUSH(stack, st->subframeSize, float); - - for (sub=0;subnbSubframes;sub++) - { - float *exc, *sp, *res, *target, *sw, tmp, filter_ratio; - int offset; - float rl, rh, eh=0, el=0; - int fold; - - offset = st->subframeSize*sub; - sp=st->high+offset; - exc=st->exc+offset; - res=st->res+offset; - target=st->target+offset; - sw=st->sw+offset; - - /* LSP interpolation (quantized and unquantized) */ - tmp = (1.0 + sub)/st->nbSubframes; - for (i=0;ilpcSize;i++) - st->interp_lsp[i] = (1-tmp)*st->old_lsp[i] + tmp*st->lsp[i]; - for (i=0;ilpcSize;i++) - st->interp_qlsp[i] = (1-tmp)*st->old_qlsp[i] + tmp*st->qlsp[i]; - - lsp_enforce_margin(st->interp_lsp, st->lpcSize, .05); - lsp_enforce_margin(st->interp_qlsp, st->lpcSize, .05); - - /* Compute interpolated LPCs (quantized and unquantized) */ - for (i=0;ilpcSize;i++) - st->interp_lsp[i] = cos(st->interp_lsp[i]); - for (i=0;ilpcSize;i++) - st->interp_qlsp[i] = cos(st->interp_qlsp[i]); - - lsp_to_lpc(st->interp_lsp, st->interp_lpc, st->lpcSize,stack); - lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack); - - bw_lpc(st->gamma1, st->interp_lpc, st->bw_lpc1, st->lpcSize); - bw_lpc(st->gamma2, st->interp_lpc, st->bw_lpc2, st->lpcSize); - - /* Compute mid-band (4000 Hz for wideband) response of low-band and high-band - filters */ - rl=rh=0; - tmp=1; - st->pi_gain[sub]=0; - for (i=0;i<=st->lpcSize;i++) - { - rh += tmp*st->interp_qlpc[i]; - tmp = -tmp; - st->pi_gain[sub]+=st->interp_qlpc[i]; - } - rl = low_pi_gain[sub]; - rl=1/(fabs(rl)+.01); - rh=1/(fabs(rh)+.01); - /* Compute ratio, will help predict the gain */ - filter_ratio=fabs(.01+rh)/(.01+fabs(rl)); - - fold = filter_ratio<5; - /*printf ("filter_ratio %f\n", filter_ratio);*/ - fold=0; - - /* Compute "real excitation" */ - fir_mem2(sp, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, st->mem_sp2); - /* Compute energy of low-band and high-band excitation */ - for (i=0;isubframeSize;i++) - eh+=sqr(exc[i]); - - if (!SUBMODE(innovation_quant)) {/* 1 for spectral folding excitation, 0 for stochastic */ - float g; - /*speex_bits_pack(bits, 1, 1);*/ - for (i=0;isubframeSize;i++) - el+=sqr(low_innov[offset+i]); - - /* Gain to use if we want to use the low-band excitation for high-band */ - g=eh/(.01+el); - g=sqrt(g); - - g *= filter_ratio; - /*print_vec(&g, 1, "gain factor");*/ - /* Gain quantization */ - { - int quant = (int) floor(.5 + 10 + 8.0 * log((g+.0001))); - /*speex_warning_int("tata", quant);*/ - if (quant<0) - quant=0; - if (quant>31) - quant=31; - speex_bits_pack(bits, quant, 5); - g= .1*exp(quant/9.4); - } - /*printf ("folding gain: %f\n", g);*/ - g /= filter_ratio; - - } else { - float gc, scale, scale_1; - - for (i=0;isubframeSize;i++) - el+=sqr(low_exc[offset+i]); - /*speex_bits_pack(bits, 0, 1);*/ - - gc = sqrt(1+eh)*filter_ratio/sqrt((1+el)*st->subframeSize); - { - int qgc = (int)floor(.5+3.7*(log(gc)+2)); - if (qgc<0) - qgc=0; - if (qgc>15) - qgc=15; - speex_bits_pack(bits, qgc, 4); - gc = exp((1/3.7)*qgc-2); - } - - scale = gc*sqrt(1+el)/filter_ratio; - scale_1 = 1/scale; - - for (i=0;isubframeSize;i++) - exc[i]=0; - exc[0]=1; - syn_percep_zero(exc, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, syn_resp, st->subframeSize, st->lpcSize, stack); - - /* Reset excitation */ - for (i=0;isubframeSize;i++) - exc[i]=0; - - /* Compute zero response (ringing) of A(z/g1) / ( A(z/g2) * Aq(z) ) */ - for (i=0;ilpcSize;i++) - mem[i]=st->mem_sp[i]; - iir_mem2(exc, st->interp_qlpc, exc, st->subframeSize, st->lpcSize, mem); - - for (i=0;ilpcSize;i++) - mem[i]=st->mem_sw[i]; - filter_mem2(exc, st->bw_lpc1, st->bw_lpc2, res, st->subframeSize, st->lpcSize, mem); - - /* Compute weighted signal */ - for (i=0;ilpcSize;i++) - mem[i]=st->mem_sw[i]; - filter_mem2(sp, st->bw_lpc1, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, mem); - - /* Compute target signal */ - for (i=0;isubframeSize;i++) - target[i]=sw[i]-res[i]; - - for (i=0;isubframeSize;i++) - exc[i]=0; - - - for (i=0;isubframeSize;i++) - target[i]*=scale_1; - - /* Reset excitation */ - for (i=0;isubframeSize;i++) - innov[i]=0; - - /*print_vec(target, st->subframeSize, "\ntarget");*/ - SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, - SUBMODE(innovation_params), st->lpcSize, st->subframeSize, - innov, syn_resp, bits, stack, (st->complexity+1)>>1); - /*print_vec(target, st->subframeSize, "after");*/ - - for (i=0;isubframeSize;i++) - exc[i] += innov[i]*scale; - - if (SUBMODE(double_codebook)) { - char *tmp_stack=stack; - float *innov2 = PUSH(tmp_stack, st->subframeSize, float); - for (i=0;isubframeSize;i++) - innov2[i]=0; - for (i=0;isubframeSize;i++) - target[i]*=2.5; - SUBMODE(innovation_quant)(target, st->interp_qlpc, st->bw_lpc1, st->bw_lpc2, - SUBMODE(innovation_params), st->lpcSize, st->subframeSize, - innov2, syn_resp, bits, tmp_stack, (st->complexity+1)>>1); - for (i=0;isubframeSize;i++) - innov2[i]*=scale*(1/2.5); - for (i=0;isubframeSize;i++) - exc[i] += innov2[i]; - } - - } - - /*Keep the previous memory*/ - for (i=0;ilpcSize;i++) - mem[i]=st->mem_sp[i]; - /* Final signal synthesis from excitation */ - iir_mem2(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp); - - /* Compute weighted signal again, from synthesized speech (not sure it's the right thing) */ - filter_mem2(sp, st->bw_lpc1, st->bw_lpc2, sw, st->subframeSize, st->lpcSize, st->mem_sw); - } - - -#ifndef RELEASE - - /* Reconstruct the original */ - fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack); - fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack); - - for (i=0;ifull_frame_size;i++) - in[i]=2*(st->y0[i]-st->y1[i]); -#endif - for (i=0;ilpcSize;i++) - st->old_lsp[i] = st->lsp[i]; - for (i=0;ilpcSize;i++) - st->old_qlsp[i] = st->qlsp[i]; - - st->first=0; - - return 1; -} - - - - - -void *sb_decoder_init(SpeexMode *m) -{ - SBDecState *st; - SpeexSBMode *mode; - st = (SBDecState*)speex_alloc(sizeof(SBDecState)+6000*sizeof(float)); - st->mode = m; - mode=(SpeexSBMode*)m->mode; - - st->stack = ((char*)st) + sizeof(SBDecState); - - - - st->st_low = speex_decoder_init(mode->nb_mode); - st->full_frame_size = 2*mode->frameSize; - st->frame_size = mode->frameSize; - st->subframeSize = mode->subframeSize; - st->nbSubframes = mode->frameSize/mode->subframeSize; - st->lpcSize=8; - speex_decoder_ctl(st->st_low, SPEEX_GET_SAMPLING_RATE, &st->sampling_rate); - st->sampling_rate*=2; - - st->submodes=mode->submodes; - st->submodeID=mode->defaultSubmode; - - st->first=1; - - - st->x0d=PUSH(st->stack, st->frame_size, float); - st->x1d=PUSH(st->stack, st->frame_size, float); - st->high=PUSH(st->stack, st->full_frame_size, float); - st->y0=PUSH(st->stack, st->full_frame_size, float); - st->y1=PUSH(st->stack, st->full_frame_size, float); - - st->h0_mem=PUSH(st->stack, QMF_ORDER, float); - st->h1_mem=PUSH(st->stack, QMF_ORDER, float); - st->g0_mem=PUSH(st->stack, QMF_ORDER, float); - st->g1_mem=PUSH(st->stack, QMF_ORDER, float); - - st->exc=PUSH(st->stack, st->frame_size, float); - - st->qlsp = PUSH(st->stack, st->lpcSize, float); - st->old_qlsp = PUSH(st->stack, st->lpcSize, float); - st->interp_qlsp = PUSH(st->stack, st->lpcSize, float); - st->interp_qlpc = PUSH(st->stack, st->lpcSize+1, float); - - st->pi_gain = PUSH(st->stack, st->nbSubframes, float); - st->mem_sp = PUSH(st->stack, 2*st->lpcSize, float); - - st->lpc_enh_enabled=0; - - return st; -} - -void sb_decoder_destroy(void *state) -{ - SBDecState *st; - st = (SBDecState*)state; - speex_decoder_destroy(st->st_low); - - speex_free(state); -} - -static void sb_decode_lost(SBDecState *st, float *out, int dtx, char *stack) -{ - int i; - float *awk1, *awk2, *awk3; - int saved_modeid=0; - - if (dtx) - { - saved_modeid=st->submodeID; - st->submodeID=1; - } else { - bw_lpc(0.99, st->interp_qlpc, st->interp_qlpc, st->lpcSize); - } - - st->first=1; - - awk1=PUSH(stack, st->lpcSize+1, float); - awk2=PUSH(stack, st->lpcSize+1, float); - awk3=PUSH(stack, st->lpcSize+1, float); - - if (st->lpc_enh_enabled) - { - float r=.9; - - float k1,k2,k3; - if (st->submodes[st->submodeID] != NULL) - { - k1=SUBMODE(lpc_enh_k1); - k2=SUBMODE(lpc_enh_k2); - } else { - k1=k2=.7; - } - k3=(1-(1-r*k1)/(1-r*k2))/r; - k3=k1-k2; - if (!st->lpc_enh_enabled) - { - k1=k2; - k3=0; - } - bw_lpc(k1, st->interp_qlpc, awk1, st->lpcSize); - bw_lpc(k2, st->interp_qlpc, awk2, st->lpcSize); - bw_lpc(k3, st->interp_qlpc, awk3, st->lpcSize); - /*fprintf (stderr, "%f %f %f\n", k1, k2, k3);*/ - } - - - /* Final signal synthesis from excitation */ - if (!dtx) - { - for (i=0;iframe_size;i++) - st->exc[i] *= .9; - } - - for (i=0;iframe_size;i++) - st->high[i]=st->exc[i]; - - if (st->lpc_enh_enabled) - { - /* Use enhanced LPC filter */ - filter_mem2(st->high, awk2, awk1, st->high, st->frame_size, st->lpcSize, - st->mem_sp+st->lpcSize); - filter_mem2(st->high, awk3, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, - st->mem_sp); - } else { - /* Use regular filter */ - for (i=0;ilpcSize;i++) - st->mem_sp[st->lpcSize+i] = 0; - iir_mem2(st->high, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, - st->mem_sp); - } - - /*iir_mem2(st->exc, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, st->mem_sp);*/ - - /* Reconstruct the original */ - fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack); - fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack); - - for (i=0;ifull_frame_size;i++) - out[i]=2*(st->y0[i]-st->y1[i]); - - if (dtx) - { - st->submodeID=saved_modeid; - } - - return; -} - -int sb_decode(void *state, SpeexBits *bits, float *out) -{ - int i, sub; - SBDecState *st; - int wideband; - int ret; - char *stack; - float *low_pi_gain, *low_exc, *low_innov; - float *awk1, *awk2, *awk3; - int dtx; - SpeexSBMode *mode; - - st = (SBDecState*)state; - stack=st->stack; - mode = (SpeexSBMode*)(st->mode->mode); - - /* Decode the low-band */ - ret = speex_decode(st->st_low, bits, st->x0d); - - speex_decoder_ctl(st->st_low, SPEEX_GET_DTX_STATUS, &dtx); - - /* If error decoding the narrowband part, propagate error */ - if (ret!=0) - { - return ret; - } - - if (!bits) - { - sb_decode_lost(st, out, dtx, stack); - return 0; - } - - /*Check "wideband bit"*/ - if (speex_bits_remaining(bits)>0) - wideband = speex_bits_peek(bits); - else - wideband = 0; - if (wideband) - { - /*Regular wideband frame, read the submode*/ - wideband = speex_bits_unpack_unsigned(bits, 1); - st->submodeID = speex_bits_unpack_unsigned(bits, SB_SUBMODE_BITS); - } else - { - /*Was a narrowband frame, set "null submode"*/ - st->submodeID = 0; - } - if (st->submodeID != 0 && st->submodes[st->submodeID] == NULL) - { - speex_warning("Invalid mode encountered: corrupted stream?"); - return -2; - } - - /* If null mode (no transmission), just set a couple things to zero*/ - if (st->submodes[st->submodeID] == NULL) - { - if (dtx) - { - sb_decode_lost(st, out, 1, stack); - return 0; - } - - for (i=0;iframe_size;i++) - st->exc[i]=0; - - st->first=1; - - /* Final signal synthesis from excitation */ - iir_mem2(st->exc, st->interp_qlpc, st->high, st->frame_size, st->lpcSize, st->mem_sp); - - fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack); - fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack); - - for (i=0;ifull_frame_size;i++) - out[i]=2*(st->y0[i]-st->y1[i]); - - return 0; - - } - - for (i=0;iframe_size;i++) - st->exc[i]=0; - - low_pi_gain = PUSH(stack, st->nbSubframes, float); - low_exc = PUSH(stack, st->frame_size, float); - low_innov = PUSH(stack, st->frame_size, float); - speex_decoder_ctl(st->st_low, SPEEX_GET_PI_GAIN, low_pi_gain); - speex_decoder_ctl(st->st_low, SPEEX_GET_EXC, low_exc); - speex_decoder_ctl(st->st_low, SPEEX_GET_INNOV, low_innov); - - SUBMODE(lsp_unquant)(st->qlsp, st->lpcSize, bits); - - if (st->first) - { - for (i=0;ilpcSize;i++) - st->old_qlsp[i] = st->qlsp[i]; - } - - awk1=PUSH(stack, st->lpcSize+1, float); - awk2=PUSH(stack, st->lpcSize+1, float); - awk3=PUSH(stack, st->lpcSize+1, float); - - for (sub=0;subnbSubframes;sub++) - { - float *exc, *sp, tmp, filter_ratio, el=0; - int offset; - float rl=0,rh=0; - - offset = st->subframeSize*sub; - sp=st->high+offset; - exc=st->exc+offset; - - /* LSP interpolation */ - tmp = (1.0 + sub)/st->nbSubframes; - for (i=0;ilpcSize;i++) - st->interp_qlsp[i] = (1-tmp)*st->old_qlsp[i] + tmp*st->qlsp[i]; - - lsp_enforce_margin(st->interp_qlsp, st->lpcSize, .05); - - /* LSPs to x-domain */ - for (i=0;ilpcSize;i++) - st->interp_qlsp[i] = cos(st->interp_qlsp[i]); - - /* LSP to LPC */ - lsp_to_lpc(st->interp_qlsp, st->interp_qlpc, st->lpcSize, stack); - - - if (st->lpc_enh_enabled) - { - float r=.9; - - float k1,k2,k3; - k1=SUBMODE(lpc_enh_k1); - k2=SUBMODE(lpc_enh_k2); - k3=(1-(1-r*k1)/(1-r*k2))/r; - k3=k1-k2; - if (!st->lpc_enh_enabled) - { - k1=k2; - k3=0; - } - bw_lpc(k1, st->interp_qlpc, awk1, st->lpcSize); - bw_lpc(k2, st->interp_qlpc, awk2, st->lpcSize); - bw_lpc(k3, st->interp_qlpc, awk3, st->lpcSize); - /*fprintf (stderr, "%f %f %f\n", k1, k2, k3);*/ - } - - - /* Calculate reponse ratio between the low and high filter in the middle - of the band (4000 Hz) */ - - tmp=1; - st->pi_gain[sub]=0; - for (i=0;i<=st->lpcSize;i++) - { - rh += tmp*st->interp_qlpc[i]; - tmp = -tmp; - st->pi_gain[sub]+=st->interp_qlpc[i]; - } - rl = low_pi_gain[sub]; - rl=1/(fabs(rl)+.01); - rh=1/(fabs(rh)+.01); - filter_ratio=fabs(.01+rh)/(.01+fabs(rl)); - - - for (i=0;isubframeSize;i++) - exc[i]=0; - if (!SUBMODE(innovation_unquant)) - { - float g; - int quant; - - for (i=0;isubframeSize;i++) - el+=sqr(low_innov[offset+i]); - quant = speex_bits_unpack_unsigned(bits, 5); - g= exp(((float)quant-10)/8.0); - - /*printf ("unquant folding gain: %f\n", g);*/ - g /= filter_ratio; - - /* High-band excitation using the low-band excitation and a gain */ - for (i=0;isubframeSize;i++) - exc[i]=mode->folding_gain*g*low_innov[offset+i]; - /*speex_rand_vec(mode->folding_gain*g*sqrt(el/st->subframeSize), exc, st->subframeSize);*/ - } else { - float gc, scale; - int qgc = speex_bits_unpack_unsigned(bits, 4); - for (i=0;isubframeSize;i++) - el+=sqr(low_exc[offset+i]); - - - gc = exp((1/3.7)*qgc-2); - - scale = gc*sqrt(1+el)/filter_ratio; - - - SUBMODE(innovation_unquant)(exc, SUBMODE(innovation_params), st->subframeSize, - bits, stack); - for (i=0;isubframeSize;i++) - exc[i]*=scale; - - if (SUBMODE(double_codebook)) { - char *tmp_stack=stack; - float *innov2 = PUSH(tmp_stack, st->subframeSize, float); - for (i=0;isubframeSize;i++) - innov2[i]=0; - SUBMODE(innovation_unquant)(innov2, SUBMODE(innovation_params), st->subframeSize, - bits, tmp_stack); - for (i=0;isubframeSize;i++) - innov2[i]*=scale*(1/2.5); - for (i=0;isubframeSize;i++) - exc[i] += innov2[i]; - } - - } - - for (i=0;isubframeSize;i++) - sp[i]=exc[i]; - if (st->lpc_enh_enabled) - { - /* Use enhanced LPC filter */ - filter_mem2(sp, awk2, awk1, sp, st->subframeSize, st->lpcSize, - st->mem_sp+st->lpcSize); - filter_mem2(sp, awk3, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, - st->mem_sp); - } else { - /* Use regular filter */ - for (i=0;ilpcSize;i++) - st->mem_sp[st->lpcSize+i] = 0; - iir_mem2(sp, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, - st->mem_sp); - } - /*iir_mem2(exc, st->interp_qlpc, sp, st->subframeSize, st->lpcSize, st->mem_sp);*/ - - } - - fir_mem_up(st->x0d, h0, st->y0, st->full_frame_size, QMF_ORDER, st->g0_mem, stack); - fir_mem_up(st->high, h1, st->y1, st->full_frame_size, QMF_ORDER, st->g1_mem, stack); - - for (i=0;ifull_frame_size;i++) - out[i]=2*(st->y0[i]-st->y1[i]); - - for (i=0;ilpcSize;i++) - st->old_qlsp[i] = st->qlsp[i]; - - st->first=0; - - return 0; -} - - -int sb_encoder_ctl(void *state, int request, void *ptr) -{ - SBEncState *st; - st=(SBEncState*)state; - switch(request) - { - case SPEEX_GET_FRAME_SIZE: - (*(int*)ptr) = st->full_frame_size; - break; - case SPEEX_SET_HIGH_MODE: - st->submodeSelect = st->submodeID = (*(int*)ptr); - break; - case SPEEX_SET_LOW_MODE: - speex_encoder_ctl(st->st_low, SPEEX_SET_LOW_MODE, ptr); - break; - case SPEEX_SET_DTX: - speex_encoder_ctl(st->st_low, SPEEX_SET_DTX, ptr); - break; - case SPEEX_GET_DTX: - speex_encoder_ctl(st->st_low, SPEEX_GET_DTX, ptr); - break; - case SPEEX_GET_LOW_MODE: - speex_encoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, ptr); - break; - case SPEEX_SET_MODE: - speex_encoder_ctl(st, SPEEX_SET_QUALITY, ptr); - break; - case SPEEX_SET_VBR: - st->vbr_enabled = (*(int*)ptr); - speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, ptr); - break; - case SPEEX_GET_VBR: - (*(int*)ptr) = st->vbr_enabled; - break; - case SPEEX_SET_VAD: - st->vad_enabled = (*(int*)ptr); - speex_encoder_ctl(st->st_low, SPEEX_SET_VAD, ptr); - break; - case SPEEX_GET_VAD: - (*(int*)ptr) = st->vad_enabled; - break; - case SPEEX_SET_VBR_QUALITY: - { - int q; - float qual = (*(float*)ptr)+.6; - st->vbr_quality = (*(float*)ptr); - if (qual>10) - qual=10; - q=(int)floor(.5+*(float*)ptr); - if (q>10) - q=10; - speex_encoder_ctl(st->st_low, SPEEX_SET_VBR_QUALITY, &qual); - speex_encoder_ctl(state, SPEEX_SET_QUALITY, &q); - break; - } - case SPEEX_SET_ABR: - st->abr_enabled = (*(int*)ptr); - st->vbr_enabled = 1; - speex_encoder_ctl(st->st_low, SPEEX_SET_VBR, &st->vbr_enabled); - { - int i=10, rate, target; - float vbr_qual; - target = (*(int*)ptr); - while (i>=0) - { - speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i); - speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate); - if (rate <= target) - break; - i--; - } - vbr_qual=i; - if (vbr_qual<0) - vbr_qual=0; - speex_encoder_ctl(st, SPEEX_SET_VBR_QUALITY, &vbr_qual); - st->abr_count=0; - st->abr_drift=0; - st->abr_drift2=0; - } - - break; - case SPEEX_GET_ABR: - (*(int*)ptr) = st->abr_enabled; - break; - case SPEEX_SET_QUALITY: - { - int nb_qual; - int quality = (*(int*)ptr); - if (quality < 0) - quality = 0; - if (quality > 10) - quality = 10; - st->submodeSelect = st->submodeID = ((SpeexSBMode*)(st->mode->mode))->quality_map[quality]; - nb_qual = ((SpeexSBMode*)(st->mode->mode))->low_quality_map[quality]; - speex_encoder_ctl(st->st_low, SPEEX_SET_MODE, &nb_qual); - } - break; - case SPEEX_SET_COMPLEXITY: - speex_encoder_ctl(st->st_low, SPEEX_SET_COMPLEXITY, ptr); - st->complexity = (*(int*)ptr); - if (st->complexity<1) - st->complexity=1; - break; - case SPEEX_GET_COMPLEXITY: - (*(int*)ptr) = st->complexity; - break; - case SPEEX_SET_BITRATE: - { - int i=10, rate, target; - target = (*(int*)ptr); - while (i>=0) - { - speex_encoder_ctl(st, SPEEX_SET_QUALITY, &i); - speex_encoder_ctl(st, SPEEX_GET_BITRATE, &rate); - if (rate <= target) - break; - i--; - } - } - break; - case SPEEX_GET_BITRATE: - speex_encoder_ctl(st->st_low, request, ptr); - /*fprintf (stderr, "before: %d\n", (*(int*)ptr));*/ - if (st->submodes[st->submodeID]) - (*(int*)ptr) += st->sampling_rate*SUBMODE(bits_per_frame)/st->full_frame_size; - else - (*(int*)ptr) += st->sampling_rate*(SB_SUBMODE_BITS+1)/st->full_frame_size; - /*fprintf (stderr, "after: %d\n", (*(int*)ptr));*/ - break; - case SPEEX_SET_SAMPLING_RATE: - { - int tmp=(*(int*)ptr); - st->sampling_rate = tmp; - tmp>>=1; - speex_encoder_ctl(st->st_low, SPEEX_SET_SAMPLING_RATE, &tmp); - } - break; - case SPEEX_GET_SAMPLING_RATE: - (*(int*)ptr)=st->sampling_rate; - break; - case SPEEX_RESET_STATE: - { - int i; - st->first = 1; - for (i=0;ilpcSize;i++) - st->lsp[i]=(M_PI*((float)(i+1)))/(st->lpcSize+1); - for (i=0;ilpcSize;i++) - st->mem_sw[i]=st->mem_sp[i]=st->mem_sp2[i]=0; - for (i=0;ibufSize;i++) - st->excBuf[i]=0; - for (i=0;ih0_mem[i]=st->h1_mem[i]=st->g0_mem[i]=st->g1_mem[i]=0; - } - break; - case SPEEX_GET_PI_GAIN: - { - int i; - float *g = (float*)ptr; - for (i=0;inbSubframes;i++) - g[i]=st->pi_gain[i]; - } - break; - case SPEEX_GET_EXC: - { - int i; - float *e = (float*)ptr; - for (i=0;ifull_frame_size;i++) - e[i]=0; - for (i=0;iframe_size;i++) - e[2*i]=2*st->exc[i]; - } - break; - case SPEEX_GET_INNOV: - { - int i; - float *e = (float*)ptr; - for (i=0;ifull_frame_size;i++) - e[i]=0; - for (i=0;iframe_size;i++) - e[2*i]=2*st->exc[i]; - } - break; - case SPEEX_GET_RELATIVE_QUALITY: - (*(float*)ptr)=st->relative_quality; - break; - default: - speex_warning_int("Unknown nb_ctl request: ", request); - return -1; - } - return 0; -} - -int sb_decoder_ctl(void *state, int request, void *ptr) -{ - SBDecState *st; - st=(SBDecState*)state; - switch(request) - { - case SPEEX_GET_LOW_MODE: - speex_decoder_ctl(st->st_low, SPEEX_GET_LOW_MODE, ptr); - break; - case SPEEX_GET_FRAME_SIZE: - (*(int*)ptr) = st->full_frame_size; - break; - case SPEEX_SET_ENH: - speex_decoder_ctl(st->st_low, request, ptr); - st->lpc_enh_enabled = *((int*)ptr); - break; - case SPEEX_GET_BITRATE: - speex_decoder_ctl(st->st_low, request, ptr); - if (st->submodes[st->submodeID]) - (*(int*)ptr) += st->sampling_rate*SUBMODE(bits_per_frame)/st->full_frame_size; - else - (*(int*)ptr) += st->sampling_rate*(SB_SUBMODE_BITS+1)/st->full_frame_size; - break; - case SPEEX_SET_SAMPLING_RATE: - { - int tmp=(*(int*)ptr); - st->sampling_rate = tmp; - tmp>>=1; - speex_decoder_ctl(st->st_low, SPEEX_SET_SAMPLING_RATE, &tmp); - } - break; - case SPEEX_GET_SAMPLING_RATE: - (*(int*)ptr)=st->sampling_rate; - break; - case SPEEX_SET_HANDLER: - speex_decoder_ctl(st->st_low, SPEEX_SET_HANDLER, ptr); - break; - case SPEEX_SET_USER_HANDLER: - speex_decoder_ctl(st->st_low, SPEEX_SET_USER_HANDLER, ptr); - break; - case SPEEX_RESET_STATE: - { - int i; - for (i=0;i<2*st->lpcSize;i++) - st->mem_sp[i]=0; - for (i=0;ih0_mem[i]=st->h1_mem[i]=st->g0_mem[i]=st->g1_mem[i]=0; - } - break; - case SPEEX_GET_PI_GAIN: - { - int i; - float *g = (float*)ptr; - for (i=0;inbSubframes;i++) - g[i]=st->pi_gain[i]; - } - break; - case SPEEX_GET_EXC: - { - int i; - float *e = (float*)ptr; - for (i=0;ifull_frame_size;i++) - e[i]=0; - for (i=0;iframe_size;i++) - e[2*i]=2*st->exc[i]; - } - break; - case SPEEX_GET_INNOV: - { - int i; - float *e = (float*)ptr; - for (i=0;ifull_frame_size;i++) - e[i]=0; - for (i=0;iframe_size;i++) - e[2*i]=2*st->exc[i]; - } - break; - case SPEEX_GET_DTX_STATUS: - speex_decoder_ctl(st->st_low, SPEEX_GET_DTX_STATUS, ptr); - break; - default: - speex_warning_int("Unknown nb_ctl request: ", request); - return -1; - } - return 0; -} diff --git a/engine/voice_codecs/speex/source/libspeex/sb_celp.h b/engine/voice_codecs/speex/source/libspeex/sb_celp.h deleted file mode 100644 index 64b23eea..00000000 --- a/engine/voice_codecs/speex/source/libspeex/sb_celp.h +++ /dev/null @@ -1,167 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin */ -/** - @file sb_celp.h - @brief Sub-band CELP mode used for wideband encoding -*/ -/* - 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. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - 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 FOUNDATION 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 SB_CELP_H -#define SB_CELP_H - -#include "modes.h" -#include "speex_bits.h" -#include "nb_celp.h" - -/**Structure representing the full state of the sub-band encoder*/ -typedef struct SBEncState { - SpeexMode *mode; /**< Pointer to the mode (containing for vtable info) */ - void *st_low; /**< State of the low-band (narrowband) encoder */ - int full_frame_size; /**< Length of full-band frames*/ - int frame_size; /**< Length of high-band frames*/ - int subframeSize; /**< Length of high-band sub-frames*/ - int nbSubframes; /**< Number of high-band sub-frames*/ - int windowSize; /**< Length of high-band LPC window*/ - int lpcSize; /**< Order of high-band LPC analysis */ - int bufSize; /**< Buffer size */ - int first; /**< First frame? */ - float lag_factor; /**< Lag-windowing control parameter */ - float lpc_floor; /**< Controls LPC analysis noise floor */ - float gamma1; /**< Perceptual weighting coef 1 */ - float gamma2; /**< Perceptual weighting coef 2 */ - - char *stack; /**< Temporary allocation stack */ - float *x0d, *x1d; /**< QMF filter signals*/ - float *high; /**< High-band signal (buffer) */ - float *y0, *y1; /**< QMF synthesis signals */ - float *h0_mem, *h1_mem, *g0_mem, *g1_mem; /**< QMF memories */ - - float *excBuf; /**< High-band excitation */ - float *exc; /**< High-band excitation (for QMF only)*/ - float *buf; /**< Temporary buffer */ - float *res; /**< Zero-input response (ringing) */ - float *sw; /**< Perceptually weighted signal */ - float *target; /**< Weighted target signal (analysis by synthesis) */ - float *window; /**< LPC analysis window */ - float *lagWindow; /**< Auto-correlation window */ - float *autocorr; /**< Auto-correlation (for LPC analysis) */ - float *rc; /**< Reflection coefficients (unused) */ - float *lpc; /**< LPC coefficients */ - float *lsp; /**< LSP coefficients */ - float *qlsp; /**< Quantized LSPs */ - float *old_lsp; /**< LSPs of previous frame */ - float *old_qlsp; /**< Quantized LSPs of previous frame */ - float *interp_lsp; /**< Interpolated LSPs for current sub-frame */ - float *interp_qlsp; /**< Interpolated quantized LSPs for current sub-frame */ - float *interp_lpc; /**< Interpolated LPCs for current sub-frame */ - float *interp_qlpc; /**< Interpolated quantized LPCs for current sub-frame */ - float *bw_lpc1; /**< Bandwidth-expanded version of LPCs (#1) */ - float *bw_lpc2; /**< Bandwidth-expanded version of LPCs (#2) */ - - float *mem_sp; /**< Synthesis signal memory */ - float *mem_sp2; - float *mem_sw; /**< Perceptual signal memory */ - float *pi_gain; - - float vbr_quality; /**< Quality setting for VBR encoding */ - int vbr_enabled; /**< 1 for enabling VBR, 0 otherwise */ - int abr_enabled; /**< ABR setting (in bps), 0 if off */ - float abr_drift; - float abr_drift2; - float abr_count; - int vad_enabled; /**< 1 for enabling VAD, 0 otherwise */ - float relative_quality; - - SpeexSubmode **submodes; - int submodeID; - int submodeSelect; - int complexity; - int sampling_rate; - -} SBEncState; - - -/**Structure representing the full state of the sub-band decoder*/ -typedef struct SBDecState { - SpeexMode *mode; /**< Pointer to the mode (containing for vtable info) */ - void *st_low; /**< State of the low-band (narrowband) encoder */ - int full_frame_size; - int frame_size; - int subframeSize; - int nbSubframes; - int lpcSize; - int first; - int sampling_rate; - int lpc_enh_enabled; - - char *stack; - float *x0d, *x1d; - float *high; - float *y0, *y1; - float *h0_mem, *h1_mem, *g0_mem, *g1_mem; - - float *exc; - float *qlsp; - float *old_qlsp; - float *interp_qlsp; - float *interp_qlpc; - - float *mem_sp; - float *pi_gain; - - SpeexSubmode **submodes; - int submodeID; -} SBDecState; - - -/**Initializes encoder state*/ -void *sb_encoder_init(SpeexMode *m); - -/**De-allocates encoder state resources*/ -void sb_encoder_destroy(void *state); - -/**Encodes one frame*/ -int sb_encode(void *state, float *in, SpeexBits *bits); - - -/**Initializes decoder state*/ -void *sb_decoder_init(SpeexMode *m); - -/**De-allocates decoder state resources*/ -void sb_decoder_destroy(void *state); - -/**Decodes one frame*/ -int sb_decode(void *state, SpeexBits *bits, float *out); - -int sb_encoder_ctl(void *state, int request, void *ptr); - -int sb_decoder_ctl(void *state, int request, void *ptr); - -#endif diff --git a/engine/voice_codecs/speex/source/libspeex/speex_callbacks.c b/engine/voice_codecs/speex/source/libspeex/speex_callbacks.c deleted file mode 100644 index 3b486965..00000000 --- a/engine/voice_codecs/speex/source/libspeex/speex_callbacks.c +++ /dev/null @@ -1,135 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File speex_callbacks.c - Callback handling and in-band signalling - - - 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. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - 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 FOUNDATION 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. - -*/ - -#include "speex_callbacks.h" -#include "misc.h" - -int speex_inband_handler(SpeexBits *bits, SpeexCallback *callback_list, void *state) -{ - int id; - SpeexCallback *callback; - /*speex_bits_advance(bits, 5);*/ - id=speex_bits_unpack_unsigned(bits, 4); - callback = callback_list+id; - - if (callback->func) - { - return callback->func(bits, state, callback->data); - } else - /*If callback is not registered, skip the right number of bits*/ - { - int adv; - if (id<2) - adv = 1; - else if (id<8) - adv = 4; - else if (id<10) - adv = 8; - else if (id<12) - adv = 16; - else if (id<14) - adv = 32; - else - adv = 64; - speex_bits_advance(bits, adv); - } - return 0; -} - -int speex_std_mode_request_handler(SpeexBits *bits, void *state, void *data) -{ - int m; - m = speex_bits_unpack_unsigned(bits, 4); - speex_encoder_ctl(data, SPEEX_SET_MODE, &m); - return 0; -} - -int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data) -{ - int m; - m = speex_bits_unpack_unsigned(bits, 4); - speex_encoder_ctl(data, SPEEX_SET_LOW_MODE, &m); - return 0; -} - -int speex_std_high_mode_request_handler(SpeexBits *bits, void *state, void *data) -{ - int m; - m = speex_bits_unpack_unsigned(bits, 4); - speex_encoder_ctl(data, SPEEX_SET_HIGH_MODE, &m); - return 0; -} - -int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data) -{ - int vbr; - vbr = speex_bits_unpack_unsigned(bits, 1); - speex_encoder_ctl(data, SPEEX_SET_VBR, &vbr); - return 0; -} - -int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data) -{ - int enh; - enh = speex_bits_unpack_unsigned(bits, 1); - speex_decoder_ctl(data, SPEEX_SET_ENH, &enh); - return 0; -} - -int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data) -{ - int qual; - qual = speex_bits_unpack_unsigned(bits, 4); - speex_encoder_ctl(data, SPEEX_SET_VBR_QUALITY, &qual); - return 0; -} - - -int speex_std_char_handler(SpeexBits *bits, void *state, void *data) -{ - unsigned char ch; - ch = speex_bits_unpack_unsigned(bits, 8); - _speex_putc(ch, data); - return 0; -} - - - -/* Default handler for user callbacks: skip it */ -int speex_default_user_handler(SpeexBits *bits, void *state, void *data) -{ - int req_size = speex_bits_unpack_unsigned(bits, 4); - speex_bits_advance(bits, 5+8*req_size); - return 0; -} diff --git a/engine/voice_codecs/speex/source/libspeex/speex_header.c b/engine/voice_codecs/speex/source/libspeex/speex_header.c deleted file mode 100644 index 7ee1ef34..00000000 --- a/engine/voice_codecs/speex/source/libspeex/speex_header.c +++ /dev/null @@ -1,162 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: speex_header.c - Describes the Speex header - - 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. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - 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 FOUNDATION 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. - -*/ - -#include "speex_header.h" -#include "misc.h" -#include "speex.h" - -#ifndef NULL -#define NULL 0 -#endif - -#define ENDIAN_SWITCH(x) {x=le_int(x);} - - -/* -typedef struct SpeexHeader { - char speex_string[8]; - char speex_version[SPEEX_HEADER_VERSION_LENGTH]; - int speex_version_id; - int header_size; - int rate; - int mode; - int mode_bitstream_version; - int nb_channels; - int bitrate; - int frame_size; - int vbr; - int frames_per_packet; - int extra_headers; - int reserved1; - int reserved2; -} SpeexHeader; -*/ - -void speex_init_header(SpeexHeader *header, int rate, int nb_channels, SpeexMode *m) -{ - int i; - char *h="Speex "; - /* - strncpy(header->speex_string, "Speex ", 8); - strncpy(header->speex_version, VERSION, SPEEX_HEADER_VERSION_LENGTH-1); - header->speex_version[SPEEX_HEADER_VERSION_LENGTH-1]=0; - */ - for (i=0;i<8;i++) - header->speex_string[i]=h[i]; - for (i=0;ispeex_version[i]=VERSION[i]; - for (;ispeex_version[i]=0; - - header->speex_version_id = 1; - header->header_size = sizeof(SpeexHeader); - - header->rate = rate; - header->mode = m->modeID; - header->mode_bitstream_version = m->bitstream_version; - if (m->modeID<0) - speex_warning("This mode is meant to be used alone"); - header->nb_channels = nb_channels; - header->bitrate = -1; - speex_mode_query(m, SPEEX_MODE_FRAME_SIZE, &header->frame_size); - header->vbr = 0; - - header->frames_per_packet = 0; - header->extra_headers = 0; - header->reserved1 = 0; - header->reserved2 = 0; -} - -char *speex_header_to_packet(SpeexHeader *header, int *size) -{ - SpeexHeader *le_header; - le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader)); - - speex_move(le_header, header, sizeof(SpeexHeader)); - - /*Make sure everything is now little-endian*/ - ENDIAN_SWITCH(le_header->speex_version_id); - ENDIAN_SWITCH(le_header->header_size); - ENDIAN_SWITCH(le_header->rate); - ENDIAN_SWITCH(le_header->mode); - ENDIAN_SWITCH(le_header->mode_bitstream_version); - ENDIAN_SWITCH(le_header->nb_channels); - ENDIAN_SWITCH(le_header->bitrate); - ENDIAN_SWITCH(le_header->frame_size); - ENDIAN_SWITCH(le_header->vbr); - ENDIAN_SWITCH(le_header->frames_per_packet); - ENDIAN_SWITCH(le_header->extra_headers); - - *size = sizeof(SpeexHeader); - return (char *)le_header; -} - -SpeexHeader *speex_packet_to_header(char *packet, int size) -{ - int i; - SpeexHeader *le_header; - char *h = "Speex "; - for (i=0;i<8;i++) - if (packet[i]!=h[i]) - { - speex_warning ("This doesn't look like a Speex file"); - return NULL; - } - - /*FIXME: Do we allow larger headers?*/ - if (size < sizeof(SpeexHeader)) - { - speex_warning("Speex header too small"); - return NULL; - } - - le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader)); - - speex_move(le_header, packet, sizeof(SpeexHeader)); - - /*Make sure everything is converted correctly from little-endian*/ - ENDIAN_SWITCH(le_header->speex_version_id); - ENDIAN_SWITCH(le_header->header_size); - ENDIAN_SWITCH(le_header->rate); - ENDIAN_SWITCH(le_header->mode); - ENDIAN_SWITCH(le_header->mode_bitstream_version); - ENDIAN_SWITCH(le_header->nb_channels); - ENDIAN_SWITCH(le_header->bitrate); - ENDIAN_SWITCH(le_header->frame_size); - ENDIAN_SWITCH(le_header->vbr); - ENDIAN_SWITCH(le_header->frames_per_packet); - ENDIAN_SWITCH(le_header->extra_headers); - - return le_header; - -} diff --git a/engine/voice_codecs/speex/source/libspeex/stack_alloc.h b/engine/voice_codecs/speex/source/libspeex/stack_alloc.h deleted file mode 100644 index 2390b69d..00000000 --- a/engine/voice_codecs/speex/source/libspeex/stack_alloc.h +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: stack_alloc.h - - Temporary memory allocation on stack - - 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. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - 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 FOUNDATION 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 STACK_ALLOC_H -#define STACK_ALLOC_H - -#if 0 - -/*Aligns the stack to a 'size' boundary */ -#define ALIGN(stack, size) (stack=(void*)((((int)stack)+((size)-1)) & (-(size)))) -/*Aligns the stack to a 'size' boundary minus k */ -#define ALIGN_1(stack, size, k) (stack=(void*)(((((int)stack)+((size)-1+(k))) & (-(size)))-(k))) - -/* Allocates 'size' elements of type 'type' on the stack */ -#define PUSH(stack, size, type) (ALIGN(stack,sizeof(type)),stack=(void*)(((int)stack)+((size)*sizeof(type))),(type*)(((int)stack)-((size)*sizeof(type)))) - - -#else - -/*Aligns the stack to a 'size' boundary */ -#define ALIGN(stack, size) ((stack) += ((size) - (int)(stack)) & ((size) - 1)) - -/* Allocates 'size' elements of type 'type' on the stack */ -#define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)),(stack)+=((size)*sizeof(type)),(type*)((stack)-((size)*sizeof(type)))) - -/* Allocates a struct stack */ -#define PUSHS(stack, type) (ALIGN((stack),sizeof(long)),(stack)+=(sizeof(type)),(type*)((stack)-(sizeof(type)))) - - -#endif - -#endif diff --git a/engine/voice_codecs/speex/source/libspeex/stereo.c b/engine/voice_codecs/speex/source/libspeex/stereo.c deleted file mode 100644 index e033ce54..00000000 --- a/engine/voice_codecs/speex/source/libspeex/stereo.c +++ /dev/null @@ -1,122 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: stereo.c - - 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. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - 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 FOUNDATION 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. -*/ - -#include "speex_stereo.h" -#include "speex_callbacks.h" -#include "vq.h" -#include - -/*float e_ratio_quant[4] = {1, 1.26, 1.587, 2};*/ -static float e_ratio_quant[4] = {.25, .315, .397, .5}; - -void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits) -{ - int i, tmp; - float e_left=0, e_right=0, e_tot=0; - float balance, e_ratio; - for (i=0;i0) - speex_bits_pack(bits, 0, 1); - else - speex_bits_pack(bits, 1, 1); - balance=floor(.5+fabs(balance)); - if (balance>30) - balance=31; - - speex_bits_pack(bits, (int)balance, 5); - - /*Quantize energy ratio*/ - tmp=vq_index(&e_ratio, e_ratio_quant, 1, 4); - speex_bits_pack(bits, tmp, 2); -} - -void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *stereo) -{ - float balance, e_ratio; - int i; - float e_tot=0, e_left, e_right, e_sum; - - balance=stereo->balance; - e_ratio=stereo->e_ratio; - for (i=frame_size-1;i>=0;i--) - { - e_tot += data[i]*data[i]; - } - e_sum=e_tot/e_ratio; - e_left = e_sum*balance / (1+balance); - e_right = e_sum-e_left; - - e_left = sqrt(e_left/(e_tot+.01)); - e_right = sqrt(e_right/(e_tot+.01)); - - for (i=frame_size-1;i>=0;i--) - { - float ftmp=data[i]; - stereo->smooth_left = .98*stereo->smooth_left + .02*e_left; - stereo->smooth_right = .98*stereo->smooth_right + .02*e_right; - data[2*i] = stereo->smooth_left*ftmp; - data[2*i+1] = stereo->smooth_right*ftmp; - } -} - -int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data) -{ - SpeexStereoState *stereo; - float sign=1; - int tmp; - - stereo = (SpeexStereoState*)data; - if (speex_bits_unpack_unsigned(bits, 1)) - sign=-1; - tmp = speex_bits_unpack_unsigned(bits, 5); - stereo->balance = exp(sign*.25*tmp); - - tmp = speex_bits_unpack_unsigned(bits, 2); - stereo->e_ratio = e_ratio_quant[tmp]; - - return 0; -} diff --git a/engine/voice_codecs/speex/source/libspeex/testenc.c b/engine/voice_codecs/speex/source/libspeex/testenc.c deleted file mode 100644 index 7033ef4a..00000000 --- a/engine/voice_codecs/speex/source/libspeex/testenc.c +++ /dev/null @@ -1,127 +0,0 @@ -#include "speex.h" -#include -#include -#include "speex_callbacks.h" - -#define FRAME_SIZE 160 -#include -int main(int argc, char **argv) -{ - char *inFile, *outFile, *bitsFile; - FILE *fin, *fout, *fbits=NULL; - short in[FRAME_SIZE]; - float input[FRAME_SIZE], bak[FRAME_SIZE], bak2[FRAME_SIZE]; - char cbits[200]; - int nbBits; - int i; - void *st; - void *dec; - SpeexBits bits; - int tmp; - int bitCount=0; - SpeexCallback callback; - - for (i=0;i32000) - input[i]=32000; - else if (input[i]<-32000) - input[i]=-32000; - } - speex_bits_reset(&bits); - for (i=0;i -#include - -#define FRAME_SIZE 640 -#include -int main(int argc, char **argv) -{ - char *inFile, *outFile, *bitsFile; - FILE *fin, *fout, *fbits=NULL; - short in[FRAME_SIZE]; - float input[FRAME_SIZE], bak[FRAME_SIZE], bak2[FRAME_SIZE]; - char cbits[200]; - int nbBits; - int i; - void *st; - void *dec; - SpeexBits bits; - int tmp; - int bitCount=0; - - for (i=0;i32000) - input[i]=32000; - else if (input[i]<-32000) - input[i]=-32000; - } - speex_bits_reset(&bits); - for (i=0;i -#include - -#define FRAME_SIZE 320 -#include -int main(int argc, char **argv) -{ - char *inFile, *outFile, *bitsFile; - FILE *fin, *fout, *fbits=NULL; - short in[FRAME_SIZE]; - float input[FRAME_SIZE], bak[FRAME_SIZE], bak2[FRAME_SIZE]; - char cbits[200]; - int nbBits; - int i; - void *st; - void *dec; - SpeexBits bits; - int tmp; - int bitCount=0; - - for (i=0;i32000) - input[i]=32000; - else if (input[i]<-32000) - input[i]=-32000; - } - speex_bits_reset(&bits); - for (i=0;i - - -#define sqr(x) ((x)*(x)) - -#define MIN_ENERGY 6000 -#define NOISE_POW .3 - - -float vbr_nb_thresh[9][11]={ - {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* CNG */ - { 3.5, 2.5, 2.0, 1.2, 0.5, 0.0, -0.5, -0.7, -0.8, -0.9, -1.0}, /* 2 kbps */ - {10.0, 6.5, 5.2, 4.5, 3.9, 3.5, 3.0, 2.5, 2.3, 1.8, 1.0}, /* 6 kbps */ - {11.0, 8.8, 7.5, 6.5, 5.0, 3.9, 3.9, 3.9, 3.5, 3.0, 1.0}, /* 8 kbps */ - {11.0, 11.0, 9.9, 9.0, 8.0, 7.0, 6.5, 6.0, 5.0, 4.0, 2.0}, /* 11 kbps */ - {11.0, 11.0, 11.0, 11.0, 9.5, 9.0, 8.0, 7.0, 6.5, 5.0, 3.0}, /* 15 kbps */ - {11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 9.5, 8.5, 8.0, 6.5, 4.0}, /* 18 kbps */ - {11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 9.8, 7.5, 5.5}, /* 24 kbps */ - { 8.0, 5.0, 3.7, 3.0, 2.5, 2.0, 1.8, 1.5, 1.0, 0.0, 0.0} /* 4 kbps */ -}; - - -float vbr_hb_thresh[5][11]={ - {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* silence */ - {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* 2 kbps */ - {11.0, 11.0, 9.5, 8.5, 7.5, 6.0, 5.0, 3.9, 3.0, 2.0, 1.0}, /* 6 kbps */ - {11.0, 11.0, 11.0, 11.0, 11.0, 9.5, 8.7, 7.8, 7.0, 6.5, 4.0}, /* 10 kbps */ - {11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 11.0, 9.8, 7.5, 5.5} /* 18 kbps */ -}; - -float vbr_uhb_thresh[2][11]={ - {-1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0}, /* silence */ - { 3.9, 2.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0} /* 2 kbps */ -}; - -void vbr_init(VBRState *vbr) -{ - int i; - - vbr->average_energy=0; - vbr->last_energy=1; - vbr->accum_sum=0; - vbr->energy_alpha=.1; - vbr->soft_pitch=0; - vbr->last_pitch_coef=0; - vbr->last_quality=0; - - vbr->noise_accum = .05*pow(MIN_ENERGY, NOISE_POW); - vbr->noise_accum_count=.05; - vbr->noise_level=vbr->noise_accum/vbr->noise_accum_count; - vbr->consec_noise=0; - - - for (i=0;ilast_log_energy[i] = log(MIN_ENERGY); -} - - -/* - This function should analyse the signal and decide how critical the - coding error will be perceptually. The following factors should be - taken into account: - - -Attacks (positive energy derivative) should be coded with more bits - - -Stationary voiced segments should receive more bits - - -Segments with (very) low absolute energy should receive less bits (maybe - only shaped noise?) - - -DTX for near-zero energy? - - -Stationary fricative segments should have less bits - - -Temporal masking: when energy slope is decreasing, decrease the bit-rate - - -Decrease bit-rate for males (low pitch)? - - -(wideband only) less bits in the high-band when signal is very - non-stationary (harder to notice high-frequency noise)??? - -*/ - -float vbr_analysis(VBRState *vbr, float *sig, int len, int pitch, float pitch_coef) -{ - int i; - float ener=0, ener1=0, ener2=0; - float qual=7; - int va; - float log_energy; - float non_st=0; - float voicing; - float pow_ener; - - for (i=0;i>1;i++) - ener1 += sig[i]*sig[i]; - - for (i=len>>1;ilast_log_energy[i]); - non_st = non_st/(30*VBR_MEMORY_SIZE); - if (non_st>1) - non_st=1; - - voicing = 3*(pitch_coef-.4)*fabs(pitch_coef-.4); - vbr->average_energy = (1-vbr->energy_alpha)*vbr->average_energy + vbr->energy_alpha*ener; - vbr->noise_level=vbr->noise_accum/vbr->noise_accum_count; - pow_ener = pow(ener,NOISE_POW); - if (vbr->noise_accum_count<.06 && ener>MIN_ENERGY) - vbr->noise_accum = .05*pow_ener; - - if ((voicing<.3 && non_st < .2 && pow_ener < 1.2*vbr->noise_level) - || (voicing<.3 && non_st < .05 && pow_ener < 1.5*vbr->noise_level) - || (voicing<.4 && non_st < .05 && pow_ener < 1.2*vbr->noise_level) - || (voicing<0 && non_st < .05)) - { - float tmp; - va = 0; - vbr->consec_noise++; - if (pow_ener > 3*vbr->noise_level) - tmp = 3*vbr->noise_level; - else - tmp = pow_ener; - if (vbr->consec_noise>=4) - { - vbr->noise_accum = .95*vbr->noise_accum + .05*tmp; - vbr->noise_accum_count = .95*vbr->noise_accum_count + .05; - } - } else { - va = 1; - vbr->consec_noise=0; - } - - if (pow_ener < vbr->noise_level && ener>MIN_ENERGY) - { - vbr->noise_accum = .95*vbr->noise_accum + .05*pow_ener; - vbr->noise_accum_count = .95*vbr->noise_accum_count + .05; - } - - /* Checking for very low absolute energy */ - if (ener < 30000) - { - qual -= .7; - if (ener < 10000) - qual-=.7; - if (ener < 3000) - qual-=.7; - } else { - float short_diff, long_diff; - short_diff = log((ener+1)/(1+vbr->last_energy)); - long_diff = log((ener+1)/(1+vbr->average_energy)); - /*fprintf (stderr, "%f %f\n", short_diff, long_diff);*/ - - if (long_diff<-5) - long_diff=-5; - if (long_diff>2) - long_diff=2; - - if (long_diff>0) - qual += .6*long_diff; - if (long_diff<0) - qual += .5*long_diff; - if (short_diff>0) - { - if (short_diff>5) - short_diff=5; - qual += .5*short_diff; - } - /* Checking for energy increases */ - if (ener2 > 1.6*ener1) - qual += .5; - } - vbr->last_energy = ener; - vbr->soft_pitch = .6*vbr->soft_pitch + .4*pitch_coef; - qual += 2.2*((pitch_coef-.4) + (vbr->soft_pitch-.4)); - - if (qual < vbr->last_quality) - qual = .5*qual + .5*vbr->last_quality; - if (qual<4) - qual=4; - if (qual>10) - qual=10; - - /* - if (vbr->consec_noise>=2) - qual-=1.3; - if (vbr->consec_noise>=5) - qual-=1.3; - if (vbr->consec_noise>=12) - qual-=1.3; - */ - if (vbr->consec_noise>=3) - qual=4; - - if (vbr->consec_noise) - qual -= 1.0 * (log(3.0 + vbr->consec_noise)-log(3)); - if (qual<0) - qual=0; - - if (ener<60000) - { - if (vbr->consec_noise>2) - qual-=0.5*(log(3.0 + vbr->consec_noise)-log(3)); - if (ener<10000&&vbr->consec_noise>2) - qual-=0.5*(log(3.0 + vbr->consec_noise)-log(3)); - if (qual<0) - qual=0; - qual += .3*log(ener/60000.0); - } - if (qual<-1) - qual=-1; - - /*printf ("%f %f %f %f %d\n", qual, voicing, non_st, pow_ener/(.01+vbr->noise_level), va);*/ - - vbr->last_pitch_coef = pitch_coef; - vbr->last_quality = qual; - - for (i=VBR_MEMORY_SIZE-1;i>0;i--) - vbr->last_log_energy[i] = vbr->last_log_energy[i-1]; - vbr->last_log_energy[0] = log_energy; - - /*printf ("VBR: %f %f %f %d %f\n", (float)(log_energy-log(vbr->average_energy+MIN_ENERGY)), non_st, voicing, va, vbr->noise_level);*/ - - return qual; -} - -void vbr_destroy(VBRState *vbr) -{ -} diff --git a/engine/voice_codecs/speex/source/libspeex/vbr.h b/engine/voice_codecs/speex/source/libspeex/vbr.h deleted file mode 100644 index 405b47f6..00000000 --- a/engine/voice_codecs/speex/source/libspeex/vbr.h +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: vbr.h - - VBR-related routines - - 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. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - 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 FOUNDATION 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 VBR_H -#define VBR_H - -#define VBR_MEMORY_SIZE 5 - -extern float vbr_nb_thresh[9][11]; -extern float vbr_hb_thresh[5][11]; -extern float vbr_uhb_thresh[2][11]; - -typedef struct VBRState { - float energy_alpha; - float average_energy; - float last_energy; - float last_log_energy[VBR_MEMORY_SIZE]; - float accum_sum; - float last_pitch_coef; - float soft_pitch; - float last_quality; - float noise_level; - float noise_accum; - float noise_accum_count; - int consec_noise; -} VBRState; - -void vbr_init(VBRState *vbr); - -float vbr_analysis(VBRState *vbr, float *sig, int len, int pitch, float pitch_coef); - -void vbr_destroy(VBRState *vbr); - -#endif diff --git a/engine/voice_codecs/speex/source/libspeex/vq.c b/engine/voice_codecs/speex/source/libspeex/vq.c deleted file mode 100644 index ed36f7d2..00000000 --- a/engine/voice_codecs/speex/source/libspeex/vq.c +++ /dev/null @@ -1,116 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: vq.c - Vector quantization - - 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. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - 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 FOUNDATION 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. -*/ - -#include "vq.h" - -/*Finds the index of the entry in a codebook that best matches the input*/ -int vq_index(float *in, float *codebook, int len, int entries) -{ - int i,j; - float min_dist=0; - int best_index=0; - for (i=0;i= 1) && (k > used || dist < best_dist[k-1]); k--) - { - best_dist[k]=best_dist[k-1]; - nbest[k] = nbest[k-1]; - } - best_dist[k]=dist; - nbest[k]=i; - used++; - } - } -} - -/*Finds the indices of the n-best entries in a codebook with sign*/ -void vq_nbest_sign(float *in, float *codebook, int len, int entries, float *E, int N, int *nbest, float *best_dist) -{ - int i,j,k, sign, used; - used=0; - for (i=0;i0) - { - sign=1; - dist=-dist; - } else - { - sign=0; - } - dist += .5*E[i]; - if (i= 1) && (k > used || dist < best_dist[k-1]); k--) - { - best_dist[k]=best_dist[k-1]; - nbest[k] = nbest[k-1]; - } - best_dist[k]=dist; - nbest[k]=i; - used++; - if (sign) - nbest[k]+=entries; - } - } -} diff --git a/engine/voice_codecs/speex/source/libspeex/vq.h b/engine/voice_codecs/speex/source/libspeex/vq.h deleted file mode 100644 index e82ba6c0..00000000 --- a/engine/voice_codecs/speex/source/libspeex/vq.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright (C) 2002 Jean-Marc Valin - File: vq.h - Vector quantization - - 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. - - - Neither the name of the Xiph.org Foundation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - - 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 FOUNDATION 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 VQ_H -#define VQ_H - -int vq_index(float *in, float *codebook, int len, int entries); - -void vq_nbest(float *in, float *codebook, int len, int entries, float *E, int N, int *nbest, float *best_dist); - -void vq_nbest_sign(float *in, float *codebook, int len, int entries, float *E, int N, int *nbest, float *best_dist); - -#endif diff --git a/engine/voice_codecs/speex/source/linux/libspeex.a b/engine/voice_codecs/speex/source/linux/libspeex.a deleted file mode 100644 index 6a126717..00000000 Binary files a/engine/voice_codecs/speex/source/linux/libspeex.a and /dev/null differ diff --git a/engine/voice_codecs/speex/source/ltmain.sh b/engine/voice_codecs/speex/source/ltmain.sh deleted file mode 100644 index 239bdefb..00000000 --- a/engine/voice_codecs/speex/source/ltmain.sh +++ /dev/null @@ -1,5130 +0,0 @@ -# ltmain.sh - Provide generalized library-building support services. -# NOTE: Changing this file will not affect anything until you rerun configure. -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 -# Free Software Foundation, Inc. -# Originally by Gordon Matzigkeit , 1996 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Check that we have a working $echo. -if test "X$1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X$1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then - # Yippee, $echo works! - : -else - # Restart under the correct shell, and then maybe $echo will work. - exec $SHELL "$0" --no-reexec ${1+"$@"} -fi - -if test "X$1" = X--fallback-echo; then - # used as fallback echo - shift - cat <&2 - echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 - exit 1 -fi - -# Global variables. -mode=$default_mode -nonopt= -prev= -prevopt= -run= -show="$echo" -show_help= -execute_dlfiles= -lo2o="s/\\.lo\$/.${objext}/" -o2lo="s/\\.${objext}\$/.lo/" - -# Parse our command line options once, thoroughly. -while test $# -gt 0 -do - arg="$1" - shift - - case $arg in - -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; - *) optarg= ;; - esac - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - execute_dlfiles) - execute_dlfiles="$execute_dlfiles $arg" - ;; - *) - eval "$prev=\$arg" - ;; - esac - - prev= - prevopt= - continue - fi - - # Have we seen a non-optional argument yet? - case $arg in - --help) - show_help=yes - ;; - - --version) - echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" - exit 0 - ;; - - --config) - ${SED} -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $0 - exit 0 - ;; - - --debug) - echo "$progname: enabling shell trace mode" - set -x - ;; - - --dry-run | -n) - run=: - ;; - - --features) - echo "host: $host" - if test "$build_libtool_libs" = yes; then - echo "enable shared libraries" - else - echo "disable shared libraries" - fi - if test "$build_old_libs" = yes; then - echo "enable static libraries" - else - echo "disable static libraries" - fi - exit 0 - ;; - - --finish) mode="finish" ;; - - --mode) prevopt="--mode" prev=mode ;; - --mode=*) mode="$optarg" ;; - - --preserve-dup-deps) duplicate_deps="yes" ;; - - --quiet | --silent) - show=: - ;; - - -dlopen) - prevopt="-dlopen" - prev=execute_dlfiles - ;; - - -*) - $echo "$modename: unrecognized option \`$arg'" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; - - *) - nonopt="$arg" - break - ;; - esac -done - -if test -n "$prevopt"; then - $echo "$modename: option \`$prevopt' requires an argument" 1>&2 - $echo "$help" 1>&2 - exit 1 -fi - -# Mandrake: (gc) It's bad to link C++ code with GCC, so we need to use the compiler name if provided -if test "$mode" = link && test -n "$archive_cmds" && test -x "/usr/bin/perl"; then - case $nonopt in - *cc | *++ | gcc* | *-gcc* | egcs*) - archive_cmds=`echo $archive_cmds | perl -pe 's/^\S+\s+//'` - archive_cmds="$nonopt $archive_cmds" - archive_expsym_cmds=`echo $archive_expsym_cmds | perl -pe 's/^\S+\s+//'` - archive_expsym_cmds="$nonopt $archive_expsym_cmds" - esac -fi - -# If this variable is set in any of the actions, the command in it -# will be execed at the end. This prevents here-documents from being -# left over by shells. -exec_cmd= - -if test -z "$show_help"; then - - # Infer the operation mode. - if test -z "$mode"; then - case $nonopt in - *cc | *++ | gcc* | *-gcc* | xlc*) - mode=link - for arg - do - case $arg in - -c) - mode=compile - break - ;; - esac - done - ;; - *db | *dbx | *strace | *truss) - mode=execute - ;; - *install*|cp|mv) - mode=install - ;; - *rm) - mode=uninstall - ;; - *) - # If we have no mode, but dlfiles were specified, then do execute mode. - test -n "$execute_dlfiles" && mode=execute - - # Just use the default operation mode. - if test -z "$mode"; then - if test -n "$nonopt"; then - $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 - else - $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 - fi - fi - ;; - esac - fi - - # Only execute mode is allowed to have -dlopen flags. - if test -n "$execute_dlfiles" && test "$mode" != execute; then - $echo "$modename: unrecognized option \`-dlopen'" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - # Change the help message to a mode-specific one. - generic_help="$help" - help="Try \`$modename --help --mode=$mode' for more information." - - # These modes are in order of execution frequency so that they run quickly. - case $mode in - # libtool compile mode - compile) - modename="$modename: compile" - # Get the compilation command and the source file. - base_compile= - prev= - lastarg= - srcfile="$nonopt" - suppress_output= - - user_target=no - for arg - do - case $prev in - "") ;; - xcompiler) - # Aesthetically quote the previous argument. - prev= - lastarg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - - case $arg in - # Double-quote args containing other shell metacharacters. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - - # Add the previous argument to base_compile. - if test -z "$base_compile"; then - base_compile="$lastarg" - else - base_compile="$base_compile $lastarg" - fi - continue - ;; - esac - - # Accept any command-line options. - case $arg in - -o) - if test "$user_target" != "no"; then - $echo "$modename: you cannot specify \`-o' more than once" 1>&2 - exit 1 - fi - user_target=next - ;; - - -static) - build_old_libs=yes - continue - ;; - - -prefer-pic) - pic_mode=yes - continue - ;; - - -prefer-non-pic) - pic_mode=no - continue - ;; - - -Xcompiler) - prev=xcompiler - continue - ;; - - -Wc,*) - args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` - lastarg= - save_ifs="$IFS"; IFS=',' - for arg in $args; do - IFS="$save_ifs" - - # Double-quote args containing other shell metacharacters. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - lastarg="$lastarg $arg" - done - IFS="$save_ifs" - lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` - - # Add the arguments to base_compile. - if test -z "$base_compile"; then - base_compile="$lastarg" - else - base_compile="$base_compile $lastarg" - fi - continue - ;; - esac - - case $user_target in - next) - # The next one is the -o target name - user_target=yes - continue - ;; - yes) - # We got the output file - user_target=set - libobj="$arg" - continue - ;; - esac - - # Accept the current argument as the source file. - lastarg="$srcfile" - srcfile="$arg" - - # Aesthetically quote the previous argument. - - # Backslashify any backslashes, double quotes, and dollar signs. - # These are the only characters that are still specially - # interpreted inside of double-quoted scrings. - lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` - - # Double-quote args containing other shell metacharacters. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - case $lastarg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - lastarg="\"$lastarg\"" - ;; - esac - - # Add the previous argument to base_compile. - if test -z "$base_compile"; then - base_compile="$lastarg" - else - base_compile="$base_compile $lastarg" - fi - done - - case $user_target in - set) - ;; - no) - # Get the name of the library object. - libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` - ;; - *) - $echo "$modename: you must specify a target with \`-o'" 1>&2 - exit 1 - ;; - esac - - # Recognize several different file suffixes. - # If the user specifies -o file.o, it is replaced with file.lo - xform='[cCFSfmso]' - case $libobj in - *.ada) xform=ada ;; - *.adb) xform=adb ;; - *.ads) xform=ads ;; - *.asm) xform=asm ;; - *.c++) xform=c++ ;; - *.cc) xform=cc ;; - *.cpp) xform=cpp ;; - *.cxx) xform=cxx ;; - *.f90) xform=f90 ;; - *.for) xform=for ;; - esac - - libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` - - case $libobj in - *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; - *) - $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 - exit 1 - ;; - esac - - if test -z "$base_compile"; then - $echo "$modename: you must specify a compilation command" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - # Delete any leftover library objects. - if test "$build_old_libs" = yes; then - removelist="$obj $libobj" - else - removelist="$libobj" - fi - - $run $rm $removelist - trap "$run $rm $removelist; exit 1" 1 2 15 - - # On Cygwin there's no "real" PIC flag so we must build both object types - case $host_os in - cygwin* | mingw* | pw32* | os2*) - pic_mode=default - ;; - esac - if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then - # non-PIC code in shared libraries is not supported - pic_mode=default - fi - - # Calculate the filename of the output object if compiler does - # not support -o with -c - if test "$compiler_c_o" = no; then - output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} - lockfile="$output_obj.lock" - removelist="$removelist $output_obj $lockfile" - trap "$run $rm $removelist; exit 1" 1 2 15 - else - need_locks=no - lockfile= - fi - - # Lock this critical section if it is needed - # We use this script file to make the link, it avoids creating a new file - if test "$need_locks" = yes; then - until $run ln "$0" "$lockfile" 2>/dev/null; do - $show "Waiting for $lockfile to be removed" - sleep 2 - done - elif test "$need_locks" = warn; then - if test -f "$lockfile"; then - echo "\ -*** ERROR, $lockfile exists and contains: -`cat $lockfile 2>/dev/null` - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit 1 - fi - echo $srcfile > "$lockfile" - fi - - if test -n "$fix_srcfile_path"; then - eval srcfile=\"$fix_srcfile_path\" - fi - - # Only build a PIC object if we are building libtool libraries. - if test "$build_libtool_libs" = yes; then - # Without this assignment, base_compile gets emptied. - fbsd_hideous_sh_bug=$base_compile - - if test "$pic_mode" != no; then - # All platforms use -DPIC, to notify preprocessed assembler code. - command="$base_compile $srcfile $pic_flag -DPIC" - else - # Don't build PIC code - command="$base_compile $srcfile" - fi - if test "$build_old_libs" = yes; then - lo_libobj="$libobj" - dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$dir" = "X$libobj"; then - dir="$objdir" - else - dir="$dir/$objdir" - fi - libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` - - if test -d "$dir"; then - $show "$rm $libobj" - $run $rm $libobj - else - $show "$mkdir $dir" - $run $mkdir $dir - status=$? - if test $status -ne 0 && test ! -d $dir; then - exit $status - fi - fi - fi - if test "$compiler_o_lo" = yes; then - output_obj="$libobj" - command="$command -o $output_obj" - elif test "$compiler_c_o" = yes; then - output_obj="$obj" - command="$command -o $output_obj" - fi - - $run $rm "$output_obj" - $show "$command" - if $run eval "$command"; then : - else - test -n "$output_obj" && $run $rm $removelist - exit 1 - fi - - if test "$need_locks" = warn && - test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then - echo "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit 1 - fi - - # Just move the object if needed, then go on to compile the next one - if test x"$output_obj" != x"$libobj"; then - $show "$mv $output_obj $libobj" - if $run $mv $output_obj $libobj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - fi - - # If we have no pic_flag, then copy the object into place and finish. - if (test -z "$pic_flag" || test "$pic_mode" != default) && - test "$build_old_libs" = yes; then - # Rename the .lo from within objdir to obj - if test -f $obj; then - $show $rm $obj - $run $rm $obj - fi - - $show "$mv $libobj $obj" - if $run $mv $libobj $obj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - - xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$obj"; then - xdir="." - else - xdir="$xdir" - fi - baseobj=`$echo "X$obj" | $Xsed -e "s%.*/%%"` - libobj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` - # Now arrange that obj and lo_libobj become the same file - $show "(cd $xdir && $LN_S $baseobj $libobj)" - if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then - # Unlock the critical section if it was locked - if test "$need_locks" != no; then - $run $rm "$lockfile" - fi - exit 0 - else - error=$? - $run $rm $removelist - exit $error - fi - fi - - # Allow error messages only from the first compilation. - suppress_output=' >/dev/null 2>&1' - fi - - # Only build a position-dependent object if we build old libraries. - if test "$build_old_libs" = yes; then - if test "$pic_mode" != yes; then - # Don't build PIC code - command="$base_compile $srcfile" - else - # All platforms use -DPIC, to notify preprocessed assembler code. - command="$base_compile $srcfile $pic_flag -DPIC" - fi - if test "$compiler_c_o" = yes; then - command="$command -o $obj" - output_obj="$obj" - fi - - # Suppress compiler output if we already did a PIC compilation. - command="$command$suppress_output" - $run $rm "$output_obj" - $show "$command" - if $run eval "$command"; then : - else - $run $rm $removelist - exit 1 - fi - - if test "$need_locks" = warn && - test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then - echo "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit 1 - fi - - # Just move the object if needed - if test x"$output_obj" != x"$obj"; then - $show "$mv $output_obj $obj" - if $run $mv $output_obj $obj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - fi - - # Create an invalid libtool object if no PIC, so that we do not - # accidentally link it into a program. - if test "$build_libtool_libs" != yes; then - $show "echo timestamp > $libobj" - $run eval "echo timestamp > \$libobj" || exit $? - else - # Move the .lo from within objdir - $show "$mv $libobj $lo_libobj" - if $run $mv $libobj $lo_libobj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - fi - fi - - # Unlock the critical section if it was locked - if test "$need_locks" != no; then - $run $rm "$lockfile" - fi - - exit 0 - ;; - - # libtool link mode - link | relink) - modename="$modename: link" - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - # It is impossible to link a dll without this setting, and - # we shouldn't force the makefile maintainer to figure out - # which system we are compiling for in order to pass an extra - # flag for every libtool invokation. - # allow_undefined=no - - # FIXME: Unfortunately, there are problems with the above when trying - # to make a dll which has undefined symbols, in which case not - # even a static library is built. For now, we need to specify - # -no-undefined on the libtool link line when we can be certain - # that all symbols are satisfied, otherwise we get a static library. - allow_undefined=yes - ;; - *) - allow_undefined=yes - ;; - esac - libtool_args="$nonopt" - compile_command="$nonopt" - finalize_command="$nonopt" - - compile_rpath= - finalize_rpath= - compile_shlibpath= - finalize_shlibpath= - convenience= - old_convenience= - deplibs= - old_deplibs= - compiler_flags= - linker_flags= - dllsearchpath= - lib_search_path=`pwd` - inst_prefix_dir= - - avoid_version=no - dlfiles= - dlprefiles= - dlself=no - export_dynamic=no - export_symbols= - export_symbols_regex= - generated= - libobjs= - ltlibs= - module=no - no_install=no - objs= - prefer_static_libs=no - preload=no - prev= - prevarg= - release= - rpath= - xrpath= - perm_rpath= - temp_rpath= - thread_safe=no - vinfo= - - # We need to know -static, to get the right output filenames. - for arg - do - case $arg in - -all-static | -static) - if test "X$arg" = "X-all-static"; then - if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then - $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2 - fi - if test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - else - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - fi - build_libtool_libs=no - build_old_libs=yes - prefer_static_libs=yes - break - ;; - esac - done - - # See if our shared archives depend on static archives. - test -n "$old_archive_from_new_cmds" && build_old_libs=yes - - # Go through the arguments, transforming them on the way. - while test $# -gt 0; do - arg="$1" - shift - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test - ;; - *) qarg=$arg ;; - esac - libtool_args="$libtool_args $qarg" - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - output) - compile_command="$compile_command @OUTPUT@" - finalize_command="$finalize_command @OUTPUT@" - ;; - esac - - case $prev in - dlfiles|dlprefiles) - if test "$preload" = no; then - # Add the symbol object into the linking commands. - compile_command="$compile_command @SYMFILE@" - finalize_command="$finalize_command @SYMFILE@" - preload=yes - fi - case $arg in - *.la | *.lo) ;; # We handle these cases below. - force) - if test "$dlself" = no; then - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - self) - if test "$prev" = dlprefiles; then - dlself=yes - elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then - dlself=yes - else - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - *) - if test "$prev" = dlfiles; then - dlfiles="$dlfiles $arg" - else - dlprefiles="$dlprefiles $arg" - fi - prev= - continue - ;; - esac - ;; - expsyms) - export_symbols="$arg" - if test ! -f "$arg"; then - $echo "$modename: symbol file \`$arg' does not exist" - exit 1 - fi - prev= - continue - ;; - expsyms_regex) - export_symbols_regex="$arg" - prev= - continue - ;; - inst_prefix) - inst_prefix_dir="$arg" - prev= - continue - ;; - release) - release="-$arg" - prev= - continue - ;; - rpath | xrpath) - # We need an absolute path. - case $arg in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - $echo "$modename: only absolute run-paths are allowed" 1>&2 - exit 1 - ;; - esac - if test "$prev" = rpath; then - case "$rpath " in - *" $arg "*) ;; - *) rpath="$rpath $arg" ;; - esac - else - case "$xrpath " in - *" $arg "*) ;; - *) xrpath="$xrpath $arg" ;; - esac - fi - prev= - continue - ;; - xcompiler) - compiler_flags="$compiler_flags $qarg" - prev= - compile_command="$compile_command $qarg" - finalize_command="$finalize_command $qarg" - continue - ;; - xlinker) - linker_flags="$linker_flags $qarg" - compiler_flags="$compiler_flags $wl$qarg" - prev= - compile_command="$compile_command $wl$qarg" - finalize_command="$finalize_command $wl$qarg" - continue - ;; - *) - eval "$prev=\"\$arg\"" - prev= - continue - ;; - esac - fi # test -n $prev - - prevarg="$arg" - - case $arg in - -all-static) - if test -n "$link_static_flag"; then - compile_command="$compile_command $link_static_flag" - finalize_command="$finalize_command $link_static_flag" - fi - continue - ;; - - -allow-undefined) - # FIXME: remove this flag sometime in the future. - $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 - continue - ;; - - -avoid-version) - avoid_version=yes - continue - ;; - - -dlopen) - prev=dlfiles - continue - ;; - - -dlpreopen) - prev=dlprefiles - continue - ;; - - -export-dynamic) - export_dynamic=yes - continue - ;; - - -export-symbols | -export-symbols-regex) - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - $echo "$modename: more than one -exported-symbols argument is not allowed" - exit 1 - fi - if test "X$arg" = "X-export-symbols"; then - prev=expsyms - else - prev=expsyms_regex - fi - continue - ;; - - -inst-prefix-dir) - prev=inst_prefix - continue - ;; - - # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* - # so, if we see these flags be careful not to treat them like -L - -L[A-Z][A-Z]*:*) - case $with_gcc/$host in - no/*-*-irix* | no/*-*-nonstopux*) - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - ;; - esac - continue - ;; - - -L*) - dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 - exit 1 - fi - dir="$absdir" - ;; - esac - case "$deplibs " in - *" -L$dir "*) ;; - *) - deplibs="$deplibs -L$dir" - lib_search_path="$lib_search_path $dir" - ;; - esac - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - case :$dllsearchpath: in - *":$dir:"*) ;; - *) dllsearchpath="$dllsearchpath:$dir";; - esac - ;; - esac - continue - ;; - - -l*) - if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then - case $host in - *-*-cygwin* | *-*-pw32* | *-*-beos*) - # These systems don't actually have a C or math library (as such) - continue - ;; - *-*-mingw* | *-*-os2*) - # These systems don't actually have a C library (as such) - test "X$arg" = "X-lc" && continue - ;; - *-*-openbsd* | *-*-freebsd*) - # Do not include libc due to us having libc/libc_r. - test "X$arg" = "X-lc" && continue - ;; - esac - elif test "X$arg" = "X-lc_r"; then - case $host in - *-*-openbsd* | *-*-freebsd*) - # Do not include libc_r directly, use -pthread flag. - continue - ;; - esac - fi - deplibs="$deplibs $arg" - continue - ;; - - -module) - module=yes - continue - ;; - - -no-fast-install) - fast_install=no - continue - ;; - - -no-install) - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - # The PATH hackery in wrapper scripts is required on Windows - # in order for the loader to find any dlls it needs. - $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 - $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 - fast_install=no - ;; - *) no_install=yes ;; - esac - continue - ;; - - -no-undefined) - allow_undefined=no - continue - ;; - - -o) prev=output ;; - - -release) - prev=release - continue - ;; - - -rpath) - prev=rpath - continue - ;; - - -R) - prev=xrpath - continue - ;; - - -R*) - dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - $echo "$modename: only absolute run-paths are allowed" 1>&2 - exit 1 - ;; - esac - case "$xrpath " in - *" $dir "*) ;; - *) xrpath="$xrpath $dir" ;; - esac - continue - ;; - - -static) - # The effects of -static are defined in a previous loop. - # We used to do the same as -all-static on platforms that - # didn't have a PIC flag, but the assumption that the effects - # would be equivalent was wrong. It would break on at least - # Digital Unix and AIX. - continue - ;; - - -thread-safe) - thread_safe=yes - continue - ;; - - -version-info) - prev=vinfo - continue - ;; - - -Wc,*) - args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` - arg= - save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - case $flag in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - flag="\"$flag\"" - ;; - esac - arg="$arg $wl$flag" - compiler_flags="$compiler_flags $flag" - done - IFS="$save_ifs" - arg=`$echo "X$arg" | $Xsed -e "s/^ //"` - ;; - - -Wl,*) - args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` - arg= - save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - case $flag in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - flag="\"$flag\"" - ;; - esac - arg="$arg $wl$flag" - compiler_flags="$compiler_flags $wl$flag" - linker_flags="$linker_flags $flag" - done - IFS="$save_ifs" - arg=`$echo "X$arg" | $Xsed -e "s/^ //"` - ;; - - -Xcompiler) - prev=xcompiler - continue - ;; - - -Xlinker) - prev=xlinker - continue - ;; - - # Some other compiler flag. - -* | +*) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - ;; - - *.lo | *.$objext) - # A library or standard object. - if test "$prev" = dlfiles; then - # This file was specified with -dlopen. - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then - dlfiles="$dlfiles $arg" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - if test "$prev" = dlprefiles; then - # Preload the old-style object. - dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"` - prev= - else - case $arg in - *.lo) libobjs="$libobjs $arg" ;; - *) objs="$objs $arg" ;; - esac - fi - ;; - - *.$libext) - # An archive. - deplibs="$deplibs $arg" - old_deplibs="$old_deplibs $arg" - continue - ;; - - *.la) - # A libtool-controlled library. - - if test "$prev" = dlfiles; then - # This library was specified with -dlopen. - dlfiles="$dlfiles $arg" - prev= - elif test "$prev" = dlprefiles; then - # The library was specified with -dlpreopen. - dlprefiles="$dlprefiles $arg" - prev= - else - deplibs="$deplibs $arg" - fi - continue - ;; - - # Some other compiler argument. - *) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - ;; - esac # arg - - # Now actually substitute the argument into the commands. - if test -n "$arg"; then - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - fi - done # argument parsing loop - - if test -n "$prev"; then - $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then - eval arg=\"$export_dynamic_flag_spec\" - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - fi - - # calculate the name of the file, without its directory - outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` - libobjs_save="$libobjs" - - if test -n "$shlibpath_var"; then - # get the directories listed in $shlibpath_var - eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` - else - shlib_search_path= - fi - eval sys_lib_search_path=\"$sys_lib_search_path_spec\" - eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" - - output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` - if test "X$output_objdir" = "X$output"; then - output_objdir="$objdir" - else - output_objdir="$output_objdir/$objdir" - fi - # Create the object directory. - if test ! -d $output_objdir; then - $show "$mkdir $output_objdir" - $run $mkdir $output_objdir - status=$? - if test $status -ne 0 && test ! -d $output_objdir; then - exit $status - fi - fi - - # Determine the type of output - case $output in - "") - $echo "$modename: you must specify an output file" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; - *.$libext) linkmode=oldlib ;; - *.lo | *.$objext) linkmode=obj ;; - *.la) linkmode=lib ;; - *) linkmode=prog ;; # Anything else should be a program. - esac - - specialdeplibs= - libs= - # Find all interdependent deplibs by searching for libraries - # that are linked more than once (e.g. -la -lb -la) - for deplib in $deplibs; do - if test "X$duplicate_deps" = "Xyes" ; then - case "$libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - libs="$libs $deplib" - done - deplibs= - newdependency_libs= - newlib_search_path= - need_relink=no # whether we're linking any uninstalled libtool libraries - notinst_deplibs= # not-installed libtool libraries - notinst_path= # paths that contain not-installed libtool libraries - case $linkmode in - lib) - passes="conv link" - for file in $dlfiles $dlprefiles; do - case $file in - *.la) ;; - *) - $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 - exit 1 - ;; - esac - done - ;; - prog) - compile_deplibs= - finalize_deplibs= - alldeplibs=no - newdlfiles= - newdlprefiles= - passes="conv scan dlopen dlpreopen link" - ;; - *) passes="conv" - ;; - esac - for pass in $passes; do - if test $linkmode = prog; then - # Determine which files to process - case $pass in - dlopen) - libs="$dlfiles" - save_deplibs="$deplibs" # Collect dlpreopened libraries - deplibs= - ;; - dlpreopen) libs="$dlprefiles" ;; - link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; - esac - fi - for deplib in $libs; do - lib= - found=no - case $deplib in - -l*) - if test $linkmode = oldlib && test $linkmode = obj; then - $echo "$modename: warning: \`-l' is ignored for archives/objects: $deplib" 1>&2 - continue - fi - if test $pass = conv; then - deplibs="$deplib $deplibs" - continue - fi - name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` - for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do - # Search the libtool library - lib="$searchdir/lib${name}.la" - if test -f "$lib"; then - found=yes - break - fi - done - if test "$found" != yes; then - # deplib doesn't seem to be a libtool library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test $linkmode = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - fi - ;; # -l - -L*) - case $linkmode in - lib) - deplibs="$deplib $deplibs" - test $pass = conv && continue - newdependency_libs="$deplib $newdependency_libs" - newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` - ;; - prog) - if test $pass = conv; then - deplibs="$deplib $deplibs" - continue - fi - if test $pass = scan; then - deplibs="$deplib $deplibs" - newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - ;; - *) - $echo "$modename: warning: \`-L' is ignored for archives/objects: $deplib" 1>&2 - ;; - esac # linkmode - continue - ;; # -L - -R*) - if test $pass = link; then - dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` - # Make sure the xrpath contains only unique directories. - case "$xrpath " in - *" $dir "*) ;; - *) xrpath="$xrpath $dir" ;; - esac - fi - deplibs="$deplib $deplibs" - continue - ;; - *.la) lib="$deplib" ;; - *.$libext) - if test $pass = conv; then - deplibs="$deplib $deplibs" - continue - fi - case $linkmode in - lib) - if test "$deplibs_check_method" != pass_all; then - echo - echo "*** Warning: Trying to link with static lib archive $deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because the file extensions .$libext of this argument makes me believe" - echo "*** that it is just a static archive that I should not used here." - else - echo - echo "*** Warning: Linking the shared library $output against the" - echo "*** static library $deplib is not portable!" - deplibs="$deplib $deplibs" - fi - continue - ;; - prog) - if test $pass != link; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - continue - ;; - esac # linkmode - ;; # *.$libext - *.lo | *.$objext) - if test $pass = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then - # If there is no dlopen support or we're linking statically, - # we need to preload. - newdlprefiles="$newdlprefiles $deplib" - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - newdlfiles="$newdlfiles $deplib" - fi - continue - ;; - %DEPLIBS%) - alldeplibs=yes - continue - ;; - esac # case $deplib - if test $found = yes || test -f "$lib"; then : - else - $echo "$modename: cannot find the library \`$lib'" 1>&2 - exit 1 - fi - - # Check to see that this really is a libtool archive. - if (${SED} -e '2q' $lib | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit 1 - fi - - ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` - test "X$ladir" = "X$lib" && ladir="." - - dlname= - dlopen= - dlpreopen= - libdir= - library_names= - old_library= - # If the library was installed with an old release of libtool, - # it will not redefine variable installed. - installed=yes - - # Read the .la file - case $lib in - */* | *\\*) . $lib ;; - *) . ./$lib ;; - esac - - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan" || - { test $linkmode = oldlib && test $linkmode = obj; }; then - # Add dl[pre]opened files of deplib - test -n "$dlopen" && dlfiles="$dlfiles $dlopen" - test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" - fi - - if test $pass = conv; then - # Only check for convenience libraries - deplibs="$lib $deplibs" - if test -z "$libdir"; then - if test -z "$old_library"; then - $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 - exit 1 - fi - # It is a libtool convenience library, so add in its objects. - convenience="$convenience $ladir/$objdir/$old_library" - old_convenience="$old_convenience $ladir/$objdir/$old_library" - tmp_libs= - for deplib in $dependency_libs; do - deplibs="$deplib $deplibs" - if test "X$duplicate_deps" = "Xyes" ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done - elif test $linkmode != prog && test $linkmode != lib; then - $echo "$modename: \`$lib' is not a convenience library" 1>&2 - exit 1 - fi - continue - fi # $pass = conv - - # Get the name of the library we link against. - linklib= - for l in $old_library $library_names; do - linklib="$l" - done - if test -z "$linklib"; then - $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 - exit 1 - fi - - # This library was specified with -dlopen. - if test $pass = dlopen; then - if test -z "$libdir"; then - $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 - exit 1 - fi - if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then - # If there is no dlname, no dlopen support or we're linking - # statically, we need to preload. - dlprefiles="$dlprefiles $lib" - else - newdlfiles="$newdlfiles $lib" - fi - continue - fi # $pass = dlopen - - # We need an absolute path. - case $ladir in - [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; - *) - abs_ladir=`cd "$ladir" && pwd` - if test -z "$abs_ladir"; then - $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 - $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 - abs_ladir="$ladir" - fi - ;; - esac - laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - - # Find the relevant object directory and library name. - if test "X$installed" = Xyes; then - if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then - $echo "$modename: warning: library \`$lib' was moved." 1>&2 - dir="$ladir" - absdir="$abs_ladir" - libdir="$abs_ladir" - else - dir="$libdir" - absdir="$libdir" - fi - else - dir="$ladir/$objdir" - absdir="$abs_ladir/$objdir" - # Remove this search path later - notinst_path="$notinst_path $abs_ladir" - fi # $installed = yes - name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` - - # This library was specified with -dlpreopen. - if test $pass = dlpreopen; then - if test -z "$libdir"; then - $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 - exit 1 - fi - # Prefer using a static library (so that no silly _DYNAMIC symbols - # are required to link). - if test -n "$old_library"; then - newdlprefiles="$newdlprefiles $dir/$old_library" - # Otherwise, use the dlname, so that lt_dlopen finds it. - elif test -n "$dlname"; then - newdlprefiles="$newdlprefiles $dir/$dlname" - else - newdlprefiles="$newdlprefiles $dir/$linklib" - fi - fi # $pass = dlpreopen - - if test -z "$libdir"; then - # Link the convenience library - if test $linkmode = lib; then - deplibs="$dir/$old_library $deplibs" - elif test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$dir/$old_library $compile_deplibs" - finalize_deplibs="$dir/$old_library $finalize_deplibs" - else - deplibs="$lib $deplibs" - fi - continue - fi - - if test $linkmode = prog && test $pass != link; then - newlib_search_path="$newlib_search_path $ladir" - deplibs="$lib $deplibs" - - linkalldeplibs=no - if test "$link_all_deplibs" != no || test -z "$library_names" || - test "$build_libtool_libs" = no; then - linkalldeplibs=yes - fi - - tmp_libs= - for deplib in $dependency_libs; do - case $deplib in - -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test - esac - # Need to link against all dependency_libs? - if test $linkalldeplibs = yes; then - deplibs="$deplib $deplibs" - else - # Need to hardcode shared library paths - # or/and link against static libraries - newdependency_libs="$deplib $newdependency_libs" - fi - if test "X$duplicate_deps" = "Xyes" ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done # for deplib - continue - fi # $linkmode = prog... - - link_static=no # Whether the deplib will be linked statically - if test -n "$library_names" && - { test "$prefer_static_libs" = no || test -z "$old_library"; }; then - # Link against this shared library - - if test "$linkmode,$pass" = "prog,link" || - { test $linkmode = lib && test $hardcode_into_libs = yes; }; then - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) compile_rpath="$compile_rpath $absdir" - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" - esac - ;; - esac - if test $linkmode = prog; then - # We need to hardcode the library path - if test -n "$shlibpath_var"; then - # Make sure the rpath contains only unique directories. - case "$temp_rpath " in - *" $dir "*) ;; - *" $absdir "*) ;; - *) temp_rpath="$temp_rpath $dir" ;; - esac - fi - fi - fi # $linkmode,$pass = prog,link... - - if test "$alldeplibs" = yes && - { test "$deplibs_check_method" = pass_all || - { test "$build_libtool_libs" = yes && - test -n "$library_names"; }; }; then - # We only need to search for static libraries - continue - fi - - if test "$installed" = no; then - notinst_deplibs="$notinst_deplibs $lib" - need_relink=yes - fi - - if test -n "$old_archive_from_expsyms_cmds"; then - # figure out the soname - set dummy $library_names - realname="$2" - shift; shift - libname=`eval \\$echo \"$libname_spec\"` - # use dlname if we got it. it's perfectly good, no? - if test -n "$dlname"; then - soname="$dlname" - elif test -n "$soname_spec"; then - # bleh windows - case $host in - *cygwin*) - major=`expr $current - $age` - versuffix="-$major" - ;; - esac - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - - # Make a new name for the extract_expsyms_cmds to use - soroot="$soname" - soname=`echo $soroot | ${SED} -e 's/^.*\///'` - newlib="libimp-`echo $soname | ${SED} 's/^lib//;s/\.dll$//'`.a" - - # If the library has no export list, then create one now - if test -f "$output_objdir/$soname-def"; then : - else - $show "extracting exported symbol list from \`$soname'" - save_ifs="$IFS"; IFS='~' - eval cmds=\"$extract_expsyms_cmds\" - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - - # Create $newlib - if test -f "$output_objdir/$newlib"; then :; else - $show "generating import library for \`$soname'" - save_ifs="$IFS"; IFS='~' - eval cmds=\"$old_archive_from_expsyms_cmds\" - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - # make sure the library variables are pointing to the new library - dir=$output_objdir - linklib=$newlib - fi # test -n $old_archive_from_expsyms_cmds - - if test $linkmode = prog || test "$mode" != relink; then - add_shlibpath= - add_dir= - add= - lib_linked=yes - case $hardcode_action in - immediate | unsupported) - if test "$hardcode_direct" = no; then - add="$dir/$linklib" - elif test "$hardcode_minus_L" = no; then - case $host in - *-*-sunos*) add_shlibpath="$dir" ;; - esac - add_dir="-L$dir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = no; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - relink) - if test "$hardcode_direct" = yes; then - add="$dir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$dir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - *) lib_linked=no ;; - esac - - if test "$lib_linked" != yes; then - $echo "$modename: configuration error: unsupported hardcode properties" - exit 1 - fi - - if test -n "$add_shlibpath"; then - case :$compile_shlibpath: in - *":$add_shlibpath:"*) ;; - *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; - esac - fi - if test $linkmode = prog; then - test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" - test -n "$add" && compile_deplibs="$add $compile_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - if test "$hardcode_direct" != yes && \ - test "$hardcode_minus_L" != yes && \ - test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; - esac - fi - fi - fi - - if test $linkmode = prog || test "$mode" = relink; then - add_shlibpath= - add_prefix_dir= - add_dir= - add= - # Finalize command for both is simple: just hardcode it. - if test "$hardcode_direct" = yes; then - add="$libdir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$libdir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; - esac - add="-l$name" - else - # We cannot seem to hardcode it, guess we'll fake it. - add_dir="-L$libdir" - add="-l$name" - fi - - - if test -n "$inst_prefix_dir"; then - case "$libdir" in - [\\/]*) - add_prefix_dir="-L$inst_prefix_dir$libdir" - ;; - esac - fi - - # add_prefix_dir must be appended instead, otherwise it can - # possibly be overrided by any hardcoded -L/... path in deplibs - if test $linkmode = prog; then - test -n "$add_prefix_dir" && finalize_deplibs="$finalize_deplibs $add_prefix_dir" - test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" - test -n "$add" && finalize_deplibs="$add $finalize_deplibs" - else - test -n "$add_prefix_dir" && deplibs="$deplibs $add_prefix_dir" - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - fi - fi - elif test $linkmode = prog; then - if test "$alldeplibs" = yes && - { test "$deplibs_check_method" = pass_all || - { test "$build_libtool_libs" = yes && - test -n "$library_names"; }; }; then - # We only need to search for static libraries - continue - fi - - # Try to link the static library - # Here we assume that one of hardcode_direct or hardcode_minus_L - # is not unsupported. This is valid on all known static and - # shared platforms. - if test "$hardcode_direct" != unsupported; then - test -n "$old_library" && linklib="$old_library" - compile_deplibs="$dir/$linklib $compile_deplibs" - finalize_deplibs="$dir/$linklib $finalize_deplibs" - else - compile_deplibs="-l$name -L$dir $compile_deplibs" - finalize_deplibs="-l$name -L$dir $finalize_deplibs" - fi - elif test "$build_libtool_libs" = yes; then - # Not a shared library - if test "$deplibs_check_method" != pass_all; then - # We're trying link a shared library against a static one - # but the system doesn't support it. - - # Just print a warning and add the library to dependency_libs so - # that the program can be linked against the static library. - echo - echo "*** Warning: This system can not link to static lib archive $lib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have." - if test "$module" = yes; then - echo "*** But as you try to build a module library, libtool will still create " - echo "*** a static module, that should work as long as the dlopening application" - echo "*** is linked with the -dlopen flag to resolve symbols at runtime." - if test -z "$global_symbol_pipe"; then - echo - echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - echo "*** not find such a program. So, this module is probably useless." - echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - else - convenience="$convenience $dir/$old_library" - old_convenience="$old_convenience $dir/$old_library" - deplibs="$dir/$old_library $deplibs" - link_static=yes - fi - fi # link shared/static library? - - if test $linkmode = lib; then - if test -n "$dependency_libs" && - { test $hardcode_into_libs != yes || test $build_old_libs = yes || - test $link_static = yes; }; then - # Extract -R from dependency_libs - temp_deplibs= - for libdir in $dependency_libs; do - case $libdir in - -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` - case " $xrpath " in - *" $temp_xrpath "*) ;; - *) xrpath="$xrpath $temp_xrpath";; - esac;; - *) temp_deplibs="$temp_deplibs $libdir";; - esac - done - dependency_libs="$temp_deplibs" - fi - - newlib_search_path="$newlib_search_path $absdir" - # Link against this library - test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" - # ... and its dependency_libs - tmp_libs= - for deplib in $dependency_libs; do - newdependency_libs="$deplib $newdependency_libs" - if test "X$duplicate_deps" = "Xyes" ; then - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - fi - tmp_libs="$tmp_libs $deplib" - done - - if test $link_all_deplibs != no; then - # Add the search paths of all dependency libraries - for deplib in $dependency_libs; do - case $deplib in - -L*) path="$deplib" ;; - *.la) - dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$deplib" && dir="." - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 - absdir="$dir" - fi - ;; - esac - if grep "^installed=no" $deplib > /dev/null; then - path="-L$absdir/$objdir" - else - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - if test -z "$libdir"; then - $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 - exit 1 - fi - if test "$absdir" != "$libdir"; then - $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 - fi - path="-L$absdir" - fi - ;; - *) continue ;; - esac - case " $deplibs " in - *" $path "*) ;; - *) deplibs="$deplibs $path" ;; - esac - done - fi # link_all_deplibs != no - fi # linkmode = lib - done # for deplib in $libs - if test $pass = dlpreopen; then - # Link the dlpreopened libraries before other libraries - for deplib in $save_deplibs; do - deplibs="$deplib $deplibs" - done - fi - if test $pass != dlopen; then - test $pass != scan && dependency_libs="$newdependency_libs" - if test $pass != conv; then - # Make sure lib_search_path contains only unique directories. - lib_search_path= - for dir in $newlib_search_path; do - case "$lib_search_path " in - *" $dir "*) ;; - *) lib_search_path="$lib_search_path $dir" ;; - esac - done - newlib_search_path= - fi - - if test "$linkmode,$pass" != "prog,link"; then - vars="deplibs" - else - vars="compile_deplibs finalize_deplibs" - fi - for var in $vars dependency_libs; do - # Add libraries to $var in reverse order - eval tmp_libs=\"\$$var\" - new_libs= - for deplib in $tmp_libs; do - case $deplib in - -L*) new_libs="$deplib $new_libs" ;; - *) - case " $specialdeplibs " in - *" $deplib "*) new_libs="$deplib $new_libs" ;; - *) - case " $new_libs " in - *" $deplib "*) ;; - *) new_libs="$deplib $new_libs" ;; - esac - ;; - esac - ;; - esac - done - tmp_libs= - for deplib in $new_libs; do - case $deplib in - -L*) - case " $tmp_libs " in - *" $deplib "*) ;; - *) tmp_libs="$tmp_libs $deplib" ;; - esac - ;; - *) tmp_libs="$tmp_libs $deplib" ;; - esac - done - eval $var=\"$tmp_libs\" - done # for var - fi - if test "$pass" = "conv" && - { test "$linkmode" = "lib" || test "$linkmode" = "prog"; }; then - libs="$deplibs" # reset libs - deplibs= - fi - done # for pass - if test $linkmode = prog; then - dlfiles="$newdlfiles" - dlprefiles="$newdlprefiles" - fi - - case $linkmode in - oldlib) - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 - fi - - if test -n "$rpath"; then - $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 - fi - - if test -n "$xrpath"; then - $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 - fi - - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 - fi - - # Now set the variables for building old libraries. - build_libtool_libs=no - oldlibs="$output" - objs="$objs$old_deplibs" - ;; - - lib) - # Make sure we only generate libraries of the form `libNAME.la'. - case $outputname in - lib*) - name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` - eval libname=\"$libname_spec\" - ;; - *) - if test "$module" = no; then - $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - if test "$need_lib_prefix" != no; then - # Add the "lib" prefix for modules if required - name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` - eval libname=\"$libname_spec\" - else - libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` - fi - ;; - esac - - if test -n "$objs"; then - if test "$deplibs_check_method" != pass_all; then - $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 - exit 1 - else - echo - echo "*** Warning: Linking the shared library $output against the non-libtool" - echo "*** objects $objs is not portable!" - libobjs="$libobjs $objs" - fi - fi - - if test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 - fi - - set dummy $rpath - if test $# -gt 2; then - $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 - fi - install_libdir="$2" - - oldlibs= - if test -z "$rpath"; then - if test "$build_libtool_libs" = yes; then - # Building a libtool convenience library. - libext=al - oldlibs="$output_objdir/$libname.$libext $oldlibs" - build_libtool_libs=convenience - build_old_libs=yes - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 - fi - else - - # Parse the version information argument. - save_ifs="$IFS"; IFS=':' - set dummy $vinfo 0 0 0 - IFS="$save_ifs" - - if test -n "$8"; then - $echo "$modename: too many parameters to \`-version-info'" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - current="$2" - revision="$3" - age="$4" - - # Check that each of the things are valid numbers. - case $current in - [0-9]*) ;; - *) - $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit 1 - ;; - esac - - case $revision in - [0-9]*) ;; - *) - $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit 1 - ;; - esac - - case $age in - [0-9]*) ;; - *) - $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit 1 - ;; - esac - - if test $age -gt $current; then - $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit 1 - fi - - # Calculate the version variables. - major= - versuffix= - verstring= - case $version_type in - none) ;; - - darwin) - # Like Linux, but with the current version available in - # verstring for coding it into the library header - major=.`expr $current - $age` - versuffix="$major.$age.$revision" - # Darwin ld doesn't like 0 for these options... - minor_current=`expr $current + 1` - verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" - ;; - - freebsd-aout) - major=".$current" - versuffix=".$current.$revision"; - ;; - - freebsd-elf) - major=".$current" - versuffix=".$current"; - ;; - - irix | nonstopux) - major=`expr $current - $age + 1` - - case $version_type in - nonstopux) verstring_prefix=nonstopux ;; - *) verstring_prefix=sgi ;; - esac - verstring="$verstring_prefix$major.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$revision - while test $loop != 0; do - iface=`expr $revision - $loop` - loop=`expr $loop - 1` - verstring="$verstring_prefix$major.$iface:$verstring" - done - - # Before this point, $major must not contain `.'. - major=.$major - versuffix="$major.$revision" - ;; - - linux) - major=.`expr $current - $age` - versuffix="$major.$age.$revision" - ;; - - osf) - major=.`expr $current - $age` - versuffix=".$current.$age.$revision" - verstring="$current.$age.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$age - while test $loop != 0; do - iface=`expr $current - $loop` - loop=`expr $loop - 1` - verstring="$verstring:${iface}.0" - done - - # Make executables depend on our current version. - verstring="$verstring:${current}.0" - ;; - - sunos) - major=".$current" - versuffix=".$current.$revision" - ;; - - windows) - # Use '-' rather than '.', since we only want one - # extension on DOS 8.3 filesystems. - major=`expr $current - $age` - versuffix="-$major" - ;; - - *) - $echo "$modename: unknown library version type \`$version_type'" 1>&2 - echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 - exit 1 - ;; - esac - - # Clear the version info if we defaulted, and they specified a release. - if test -z "$vinfo" && test -n "$release"; then - major= - verstring="0.0" - case $version_type in - darwin) - # we can't check for "0.0" in archive_cmds due to quoting - # problems, so we reset it completely - verstring="" - ;; - *) - verstring="0.0" - ;; - esac - if test "$need_version" = no; then - versuffix= - else - versuffix=".0.0" - fi - fi - - # Remove version info from name if versioning should be avoided - if test "$avoid_version" = yes && test "$need_version" = no; then - major= - versuffix= - verstring="" - fi - - # Check to see if the archive will have undefined symbols. - if test "$allow_undefined" = yes; then - if test "$allow_undefined_flag" = unsupported; then - $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 - build_libtool_libs=no - build_old_libs=yes - fi - else - # Don't allow undefined symbols. - allow_undefined_flag="$no_undefined_flag" - fi - fi - - if test "$mode" != relink; then - # Remove our outputs. - $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*" - $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.* - fi - - # Now set the variables for building old libraries. - if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then - oldlibs="$oldlibs $output_objdir/$libname.$libext" - - # Transform .lo files to .o files. - oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` - fi - - # Eliminate all temporary directories. - for path in $notinst_path; do - lib_search_path=`echo "$lib_search_path " | ${SED} -e 's% $path % %g'` - deplibs=`echo "$deplibs " | ${SED} -e 's% -L$path % %g'` - dependency_libs=`echo "$dependency_libs " | ${SED} -e 's% -L$path % %g'` - done - - if test -n "$xrpath"; then - # If the user specified any rpath flags, then add them. - temp_xrpath= - for libdir in $xrpath; do - temp_xrpath="$temp_xrpath -R$libdir" - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" ;; - esac - done - if test $hardcode_into_libs != yes || test $build_old_libs = yes; then - dependency_libs="$temp_xrpath $dependency_libs" - fi - fi - - # Make sure dlfiles contains only unique files that won't be dlpreopened - old_dlfiles="$dlfiles" - dlfiles= - for lib in $old_dlfiles; do - case " $dlprefiles $dlfiles " in - *" $lib "*) ;; - *) dlfiles="$dlfiles $lib" ;; - esac - done - - # Make sure dlprefiles contains only unique files - old_dlprefiles="$dlprefiles" - dlprefiles= - for lib in $old_dlprefiles; do - case "$dlprefiles " in - *" $lib "*) ;; - *) dlprefiles="$dlprefiles $lib" ;; - esac - done - - if test "$build_libtool_libs" = yes; then - if test -n "$rpath"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) - # these systems don't actually have a c library (as such)! - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C library is in the System framework - deplibs="$deplibs -framework System" - ;; - *-*-netbsd*) - # Don't link with libc until the a.out ld.so is fixed. - ;; - *-*-openbsd* | *-*-freebsd*) - # Do not include libc due to us having libc/libc_r. - ;; - *) - # Add libc to deplibs on all other systems if necessary. - if test $build_libtool_need_lc = "yes"; then - deplibs="$deplibs -lc" - fi - ;; - esac - fi - - # Transform deplibs into only deplibs that can be linked in shared. - name_save=$name - libname_save=$libname - release_save=$release - versuffix_save=$versuffix - major_save=$major - # I'm not sure if I'm treating the release correctly. I think - # release should show up in the -l (ie -lgmp5) so we don't want to - # add it in twice. Is that correct? - release="" - versuffix="" - major="" - newdeplibs= - droppeddeps=no - case $deplibs_check_method in - pass_all) - # Don't check for shared/static. Everything works. - # This might be a little naive. We might want to check - # whether the library exists or not. But this is on - # osf3 & osf4 and I'm not really sure... Just - # implementing what was already the behaviour. - newdeplibs=$deplibs - ;; - test_compile) - # This code stresses the "libraries are programs" paradigm to its - # limits. Maybe even breaks it. We compile a program, linking it - # against the deplibs as a proxy for the library. Then we can check - # whether they linked in statically or dynamically with ldd. - $rm conftest.c - cat > conftest.c </dev/null` - for potent_lib in $potential_libs; do - # Follow soft links. - if ls -lLd "$potent_lib" 2>/dev/null \ - | grep " -> " >/dev/null; then - continue - fi - # The statement above tries to avoid entering an - # endless loop below, in case of cyclic links. - # We might still enter an endless loop, since a link - # loop can be closed while we follow links, - # but so what? - potlib="$potent_lib" - while test -h "$potlib" 2>/dev/null; do - potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` - case $potliblink in - [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; - *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; - esac - done - # It is ok to link against an archive when - # building a shared library. - if $AR -t $potlib > /dev/null 2>&1; then - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - break 2 - fi - if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ - | ${SED} 10q \ - | egrep "$file_magic_regex" > /dev/null; then - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - break 2 - fi - done - done - if test -n "$a_deplib" ; then - droppeddeps=yes - echo - echo "*** Warning: linker path does not have real file for library $a_deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then - echo "*** with $libname but no candidates were found. (...for file magic test)" - else - echo "*** with $libname and none of the candidates passed a file format test" - echo "*** using a file magic. Last file checked: $potlib" - fi - fi - else - # Add a -L argument. - newdeplibs="$newdeplibs $a_deplib" - fi - done # Gone through all deplibs. - ;; - match_pattern*) - set dummy $deplibs_check_method - match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` - for a_deplib in $deplibs; do - name="`expr $a_deplib : '-l\(.*\)'`" - # If $name is empty we are operating on a -L argument. - if test -n "$name" && test "$name" != "0"; then - libname=`eval \\$echo \"$libname_spec\"` - for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do - potential_libs=`ls $i/$libname[.-]* 2>/dev/null` - for potent_lib in $potential_libs; do - potlib="$potent_lib" # see symlink-check below in file_magic test - if eval echo \"$potent_lib\" 2>/dev/null \ - | ${SED} 10q \ - | egrep "$match_pattern_regex" > /dev/null; then - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - break 2 - fi - done - done - if test -n "$a_deplib" ; then - droppeddeps=yes - echo - echo "*** Warning: linker path does not have real file for library $a_deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have" - echo "*** because I did check the linker path looking for a file starting" - if test -z "$potlib" ; then - echo "*** with $libname but no candidates were found. (...for regex pattern test)" - else - echo "*** with $libname and none of the candidates passed a file format test" - echo "*** using a regex pattern. Last file checked: $potlib" - fi - fi - else - # Add a -L argument. - newdeplibs="$newdeplibs $a_deplib" - fi - done # Gone through all deplibs. - ;; - none | unknown | *) - newdeplibs="" - if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ - -e 's/ -[LR][^ ]*//g' -e 's/[ ]//g' | - grep . >/dev/null; then - echo - if test "X$deplibs_check_method" = "Xnone"; then - echo "*** Warning: inter-library dependencies are not supported in this platform." - else - echo "*** Warning: inter-library dependencies are not known to be supported." - fi - echo "*** All declared inter-library dependencies are being dropped." - droppeddeps=yes - fi - ;; - esac - versuffix=$versuffix_save - major=$major_save - release=$release_save - libname=$libname_save - name=$name_save - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` - ;; - esac - - if test "$droppeddeps" = yes; then - if test "$module" = yes; then - echo - echo "*** Warning: libtool could not satisfy all declared inter-library" - echo "*** dependencies of module $libname. Therefore, libtool will create" - echo "*** a static module, that should work as long as the dlopening" - echo "*** application is linked with the -dlopen flag." - if test -z "$global_symbol_pipe"; then - echo - echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - echo "*** not find such a program. So, this module is probably useless." - echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - else - echo "*** The inter-library dependencies that have been dropped here will be" - echo "*** automatically added whenever a program is linked with this library" - echo "*** or is declared to -dlopen it." - - if test $allow_undefined = no; then - echo - echo "*** Since this library must not contain undefined symbols," - echo "*** because either the platform does not support them or" - echo "*** it was explicitly requested with -no-undefined," - echo "*** libtool will only create a static version of it." - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - fi - fi - # Done checking deplibs! - deplibs=$newdeplibs - fi - - # All the library-specific variables (install_libdir is set above). - library_names= - old_library= - dlname= - - # Test again, we may have decided not to build it any more - if test "$build_libtool_libs" = yes; then - if test $hardcode_into_libs = yes; then - # Hardcode the library paths - hardcode_libdirs= - dep_rpath= - rpath="$finalize_rpath" - test "$mode" != relink && rpath="$compile_rpath$rpath" - for libdir in $rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - dep_rpath="$dep_rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) perm_rpath="$perm_rpath $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval dep_rpath=\"$hardcode_libdir_flag_spec\" - fi - if test -n "$runpath_var" && test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - rpath="$rpath$dir:" - done - eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" - fi - test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" - fi - - shlibpath="$finalize_shlibpath" - test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" - if test -n "$shlibpath"; then - eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" - fi - - # Get the real and link names of the library. - eval library_names=\"$library_names_spec\" - set dummy $library_names - realname="$2" - shift; shift - - if test -n "$soname_spec"; then - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - test -z "$dlname" && dlname=$soname - - lib="$output_objdir/$realname" - for link - do - linknames="$linknames $link" - done - - # Ensure that we have .o objects for linkers which dislike .lo - # (e.g. aix) in case we are running --disable-static - for obj in $libobjs; do - xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$obj"; then - xdir="." - else - xdir="$xdir" - fi - baseobj=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` - oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` - if test ! -f $xdir/$oldobj; then - $show "(cd $xdir && ${LN_S} $baseobj $oldobj)" - $run eval '(cd $xdir && ${LN_S} $baseobj $oldobj)' || exit $? - fi - done - - # Use standard objects if they are pic - test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then - $show "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" - $run $rm $export_symbols - eval cmds=\"$export_symbols_cmds\" - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - if test -n "$export_symbols_regex"; then - $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" - $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' - $show "$mv \"${export_symbols}T\" \"$export_symbols\"" - $run eval '$mv "${export_symbols}T" "$export_symbols"' - fi - fi - fi - - if test -n "$export_symbols" && test -n "$include_expsyms"; then - $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' - fi - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - else - gentop="$output_objdir/${outputname}x" - $show "${rm}r $gentop" - $run ${rm}r "$gentop" - $show "mkdir $gentop" - $run mkdir "$gentop" - status=$? - if test $status -ne 0 && test ! -d "$gentop"; then - exit $status - fi - generated="$generated $gentop" - - for xlib in $convenience; do - # Extract the objects. - case $xlib in - [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; - *) xabs=`pwd`"/$xlib" ;; - esac - xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` - xdir="$gentop/$xlib" - - $show "${rm}r $xdir" - $run ${rm}r "$xdir" - $show "mkdir $xdir" - $run mkdir "$xdir" - status=$? - if test $status -ne 0 && test ! -d "$xdir"; then - exit $status - fi - $show "(cd $xdir && $AR x $xabs)" - $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? - - libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` - done - fi - fi - - if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then - eval flag=\"$thread_safe_flag_spec\" - linker_flags="$linker_flags $flag" - fi - - # Make a backup of the uninstalled library when relinking - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? - fi - - # Do each of the archive commands. - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - eval cmds=\"$archive_expsym_cmds\" - else - save_deplibs="$deplibs" - for conv in $convenience; do - tmp_deplibs= - for test_deplib in $deplibs; do - if test "$test_deplib" != "$conv"; then - tmp_deplibs="$tmp_deplibs $test_deplib" - fi - done - deplibs="$tmp_deplibs" - done - eval cmds=\"$archive_cmds\" - deplibs="$save_deplibs" - fi - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - - # Restore the uninstalled library and exit - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? - exit 0 - fi - - # Create links to the real library. - for linkname in $linknames; do - if test "$realname" != "$linkname"; then - $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" - $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? - fi - done - - # If -module or -export-dynamic was specified, set the dlname. - if test "$module" = yes || test "$export_dynamic" = yes; then - # On all known operating systems, these are identical. - dlname="$soname" - fi - fi - ;; - - obj) - if test -n "$deplibs"; then - $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 - fi - - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 - fi - - if test -n "$rpath"; then - $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 - fi - - if test -n "$xrpath"; then - $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 - fi - - case $output in - *.lo) - if test -n "$objs$old_deplibs"; then - $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 - exit 1 - fi - libobj="$output" - obj=`$echo "X$output" | $Xsed -e "$lo2o"` - ;; - *) - libobj= - obj="$output" - ;; - esac - - # Delete the old objects. - $run $rm $obj $libobj - - # Objects from convenience libraries. This assumes - # single-version convenience libraries. Whenever we create - # different ones for PIC/non-PIC, this we'll have to duplicate - # the extraction. - reload_conv_objs= - gentop= - # reload_cmds runs $LD directly, so let us get rid of - # -Wl from whole_archive_flag_spec - wl= - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" - else - gentop="$output_objdir/${obj}x" - $show "${rm}r $gentop" - $run ${rm}r "$gentop" - $show "mkdir $gentop" - $run mkdir "$gentop" - status=$? - if test $status -ne 0 && test ! -d "$gentop"; then - exit $status - fi - generated="$generated $gentop" - - for xlib in $convenience; do - # Extract the objects. - case $xlib in - [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; - *) xabs=`pwd`"/$xlib" ;; - esac - xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` - xdir="$gentop/$xlib" - - $show "${rm}r $xdir" - $run ${rm}r "$xdir" - $show "mkdir $xdir" - $run mkdir "$xdir" - status=$? - if test $status -ne 0 && test ! -d "$xdir"; then - exit $status - fi - $show "(cd $xdir && $AR x $xabs)" - $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? - - reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` - done - fi - fi - - # Create the old-style object. - reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test - - output="$obj" - eval cmds=\"$reload_cmds\" - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - - # Exit if we aren't doing a library object file. - if test -z "$libobj"; then - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - exit 0 - fi - - if test "$build_libtool_libs" != yes; then - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - # Create an invalid libtool object if no PIC, so that we don't - # accidentally link it into a program. - $show "echo timestamp > $libobj" - $run eval "echo timestamp > $libobj" || exit $? - exit 0 - fi - - if test -n "$pic_flag" || test "$pic_mode" != default; then - # Only do commands if we really have different PIC objects. - reload_objs="$libobjs $reload_conv_objs" - output="$libobj" - eval cmds=\"$reload_cmds\" - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - else - # Just create a symlink. - $show $rm $libobj - $run $rm $libobj - xdir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$libobj"; then - xdir="." - else - xdir="$xdir" - fi - baseobj=`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` - oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` - $show "(cd $xdir && $LN_S $oldobj $baseobj)" - $run eval '(cd $xdir && $LN_S $oldobj $baseobj)' || exit $? - fi - - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - exit 0 - ;; - - prog) - case $host in - *cygwin*) output=`echo $output | ${SED} -e 's,.exe$,,;s,$,.exe,'` ;; - esac - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 - fi - - if test "$preload" = yes; then - if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && - test "$dlopen_self_static" = unknown; then - $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." - fi - fi - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` - finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` - case $host in - *darwin*) - # Don't allow lazy linking, it breaks C++ global constructors - compile_command="$compile_command ${wl}-bind_at_load" - finalize_command="$finalize_command ${wl}-bind_at_load" - ;; - esac - ;; - esac - - compile_command="$compile_command $compile_deplibs" - finalize_command="$finalize_command $finalize_deplibs" - - if test -n "$rpath$xrpath"; then - # If the user specified any rpath flags, then add them. - for libdir in $rpath $xrpath; do - # This is the magic to use -rpath. - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" ;; - esac - done - fi - - # Now hardcode the library paths - rpath= - hardcode_libdirs= - for libdir in $compile_rpath $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - rpath="$rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) perm_rpath="$perm_rpath $libdir" ;; - esac - fi - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - case :$dllsearchpath: in - *":$libdir:"*) ;; - *) dllsearchpath="$dllsearchpath:$libdir";; - esac - ;; - esac - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - compile_rpath="$rpath" - - rpath= - hardcode_libdirs= - for libdir in $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - rpath="$rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$finalize_perm_rpath " in - *" $libdir "*) ;; - *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - finalize_rpath="$rpath" - - if test -n "$libobjs" && test "$build_old_libs" = yes; then - # Transform all the library objects into standard objects. - compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - fi - - dlsyms= - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - if test -n "$NM" && test -n "$global_symbol_pipe"; then - dlsyms="${outputname}S.c" - else - $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 - fi - fi - - if test -n "$dlsyms"; then - case $dlsyms in - "") ;; - *.c) - # Discover the nlist of each of the dlfiles. - nlist="$output_objdir/${outputname}.nm" - - $show "$rm $nlist ${nlist}S ${nlist}T" - $run $rm "$nlist" "${nlist}S" "${nlist}T" - - # Parse the name list into a source file. - $show "creating $output_objdir/$dlsyms" - - test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ -/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ -/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ - -#ifdef __cplusplus -extern \"C\" { -#endif - -/* Prevent the only kind of declaration conflicts we can make. */ -#define lt_preloaded_symbols some_other_symbol - -/* External symbol declarations for the compiler. */\ -" - - if test "$dlself" = yes; then - $show "generating symbol list for \`$output'" - - test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" - - # Add our own program objects to the symbol list. - progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - for arg in $progfiles; do - $show "extracting global C symbols from \`$arg'" - $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" - done - - if test -n "$exclude_expsyms"; then - $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' - $run eval '$mv "$nlist"T "$nlist"' - fi - - if test -n "$export_symbols_regex"; then - $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T' - $run eval '$mv "$nlist"T "$nlist"' - fi - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - export_symbols="$output_objdir/$output.exp" - $run $rm $export_symbols - $run eval "${SED} -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' - else - $run eval "${SED} -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"' - $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T' - $run eval 'mv "$nlist"T "$nlist"' - fi - fi - - for arg in $dlprefiles; do - $show "extracting global C symbols from \`$arg'" - name=`echo "$arg" | ${SED} -e 's%^.*/%%'` - $run eval 'echo ": $name " >> "$nlist"' - $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" - done - - if test -z "$run"; then - # Make sure we have at least an empty file. - test -f "$nlist" || : > "$nlist" - - if test -n "$exclude_expsyms"; then - egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T - $mv "$nlist"T "$nlist" - fi - - # Try sorting and uniquifying the output. - if grep -v "^: " < "$nlist" | - if sort -k 3 /dev/null 2>&1; then - sort -k 3 - else - sort +2 - fi | - uniq > "$nlist"S; then - : - else - grep -v "^: " < "$nlist" > "$nlist"S - fi - - if test -f "$nlist"S; then - eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' - else - echo '/* NONE */' >> "$output_objdir/$dlsyms" - fi - - $echo >> "$output_objdir/$dlsyms" "\ - -#undef lt_preloaded_symbols - -#if defined (__STDC__) && __STDC__ -# define lt_ptr void * -#else -# define lt_ptr char * -# define const -#endif - -/* The mapping between symbol names and symbols. */ -const struct { - const char *name; - lt_ptr address; -} -lt_preloaded_symbols[] = -{\ -" - - eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" - - $echo >> "$output_objdir/$dlsyms" "\ - {0, (lt_ptr) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif\ -" - fi - - pic_flag_for_symtable= - case $host in - # compiling the symbol table file with pic_flag works around - # a FreeBSD bug that causes programs to crash when -lm is - # linked before any other PIC object. But we must not use - # pic_flag when linking with -static. The problem exists in - # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. - *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) - case "$compile_command " in - *" -static "*) ;; - *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";; - esac;; - *-*-hpux*) - case "$compile_command " in - *" -static "*) ;; - *) pic_flag_for_symtable=" $pic_flag -DPIC";; - esac - esac - - # Now compile the dynamic symbol file. - $show "(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" - $run eval '(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? - - # Clean up the generated files. - $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" - $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" - - # Transform the symbol file into the correct name. - compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` - finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` - ;; - *) - $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 - exit 1 - ;; - esac - else - # We keep going just in case the user didn't refer to - # lt_preloaded_symbols. The linker will fail if global_symbol_pipe - # really was required. - - # Nullify the symbol file. - compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` - finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` - fi - - if test $need_relink = no || test "$build_libtool_libs" != yes; then - # Replace the output file specification. - compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` - link_command="$compile_command$compile_rpath" - - # We have no uninstalled library dependencies, so finalize right now. - $show "$link_command" - $run eval "$link_command" - status=$? - - # Delete the generated files. - if test -n "$dlsyms"; then - $show "$rm $output_objdir/${outputname}S.${objext}" - $run $rm "$output_objdir/${outputname}S.${objext}" - fi - - exit $status - fi - - if test -n "$shlibpath_var"; then - # We should set the shlibpath_var - rpath= - for dir in $temp_rpath; do - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) - # Absolute path. - rpath="$rpath$dir:" - ;; - *) - # Relative path: add a thisdir entry. - rpath="$rpath\$thisdir/$dir:" - ;; - esac - done - temp_rpath="$rpath" - fi - - if test -n "$compile_shlibpath$finalize_shlibpath"; then - compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" - fi - if test -n "$finalize_shlibpath"; then - finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" - fi - - compile_var= - finalize_var= - if test -n "$runpath_var"; then - if test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - rpath="$rpath$dir:" - done - compile_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - if test -n "$finalize_perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $finalize_perm_rpath; do - rpath="$rpath$dir:" - done - finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - fi - - if test "$no_install" = yes; then - # We don't need to create a wrapper script. - link_command="$compile_var$compile_command$compile_rpath" - # Replace the output file specification. - link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` - # Delete the old output file. - $run $rm $output - # Link the executable and exit - $show "$link_command" - $run eval "$link_command" || exit $? - exit 0 - fi - - if test "$hardcode_action" = relink; then - # Fast installation is not supported - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - - $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 - $echo "$modename: \`$output' will be relinked during installation" 1>&2 - else - if test "$fast_install" != no; then - link_command="$finalize_var$compile_command$finalize_rpath" - if test "$fast_install" = yes; then - relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` - else - # fast_install is set to needless - relink_command= - fi - else - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - fi - fi - - # Replace the output file specification. - link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` - - # Delete the old output files. - $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname - - $show "$link_command" - $run eval "$link_command" || exit $? - - # Now create the wrapper script. - $show "creating $output" - - # Quote the relink command for shipping. - if test -n "$relink_command"; then - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` - relink_command="$var=\"$var_value\"; export $var; $relink_command" - fi - done - relink_command="(cd `pwd`; $relink_command)" - relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` - fi - - # Quote $echo for shipping. - if test "X$echo" = "X$SHELL $0 --fallback-echo"; then - case $0 in - [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";; - *) qecho="$SHELL `pwd`/$0 --fallback-echo";; - esac - qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` - else - qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` - fi - - # Only actually do things if our run command is non-null. - if test -z "$run"; then - # win32 will think the script is a binary if it has - # a .exe suffix, so we strip it off here. - case $output in - *.exe) output=`echo $output|${SED} 's,.exe$,,'` ;; - esac - # test for cygwin because mv fails w/o .exe extensions - case $host in - *cygwin*) exeext=.exe ;; - *) exeext= ;; - esac - $rm $output - trap "$rm $output; exit 1" 1 2 15 - - $echo > $output "\ -#! $SHELL - -# $output - temporary wrapper script for $objdir/$outputname -# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP -# -# The $output program cannot be directly executed until all the libtool -# libraries that it depends on are installed. -# -# This wrapper script should never be moved out of the build directory. -# If it is, it will not operate correctly. - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed="${SED}"' -e 1s/^X//' -sed_quote_subst='$sed_quote_subst' - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi - -relink_command=\"$relink_command\" - -# This environment variable determines our operation mode. -if test \"\$libtool_install_magic\" = \"$magic\"; then - # install mode needs the following variable: - notinst_deplibs='$notinst_deplibs' -else - # When we are sourced in execute mode, \$file and \$echo are already set. - if test \"\$libtool_execute_magic\" != \"$magic\"; then - echo=\"$qecho\" - file=\"\$0\" - # Make sure echo works. - if test \"X\$1\" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift - elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then - # Yippee, \$echo works! - : - else - # Restart under the correct shell, and then maybe \$echo will work. - exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} - fi - fi\ -" - $echo >> $output "\ - - # Find the directory that this script lives in. - thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` - test \"x\$thisdir\" = \"x\$file\" && thisdir=. - - # Follow symbolic links until we get to the real thisdir. - file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` - while test -n \"\$file\"; do - destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` - - # If there was a directory component, then change thisdir. - if test \"x\$destdir\" != \"x\$file\"; then - case \"\$destdir\" in - [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; - *) thisdir=\"\$thisdir/\$destdir\" ;; - esac - fi - - file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` - file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` - done - - # Try to get the absolute directory name. - absdir=\`cd \"\$thisdir\" && pwd\` - test -n \"\$absdir\" && thisdir=\"\$absdir\" -" - - if test "$fast_install" = yes; then - echo >> $output "\ - program=lt-'$outputname'$exeext - progdir=\"\$thisdir/$objdir\" - - if test ! -f \"\$progdir/\$program\" || \\ - { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ - test \"X\$file\" != \"X\$progdir/\$program\"; }; then - - file=\"\$\$-\$program\" - - if test ! -d \"\$progdir\"; then - $mkdir \"\$progdir\" - else - $rm \"\$progdir/\$file\" - fi" - - echo >> $output "\ - - # relink executable if necessary - if test -n \"\$relink_command\"; then - if relink_command_output=\`eval \$relink_command 2>&1\`; then : - else - $echo \"\$relink_command_output\" >&2 - $rm \"\$progdir/\$file\" - exit 1 - fi - fi - - $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || - { $rm \"\$progdir/\$program\"; - $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } - $rm \"\$progdir/\$file\" - fi" - else - echo >> $output "\ - program='$outputname' - progdir=\"\$thisdir/$objdir\" -" - fi - - echo >> $output "\ - - if test -f \"\$progdir/\$program\"; then" - - # Export our shlibpath_var if we have one. - if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then - $echo >> $output "\ - # Add our own library path to $shlibpath_var - $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" - - # Some systems cannot cope with colon-terminated $shlibpath_var - # The second colon is a workaround for a bug in BeOS R4 ${SED} - $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` - - export $shlibpath_var -" - fi - - # fixup the dll searchpath if we need to. - if test -n "$dllsearchpath"; then - $echo >> $output "\ - # Add the dll search path components to the executable PATH - PATH=$dllsearchpath:\$PATH -" - fi - - $echo >> $output "\ - if test \"\$libtool_execute_magic\" != \"$magic\"; then - # Run the actual program with our arguments. -" - case $host in - # win32 systems need to use the prog path for dll - # lookup to work - *-*-cygwin* | *-*-pw32*) - $echo >> $output "\ - exec \$progdir/\$program \${1+\"\$@\"} -" - ;; - - # Backslashes separate directories on plain windows - *-*-mingw | *-*-os2*) - $echo >> $output "\ - exec \$progdir\\\\\$program \${1+\"\$@\"} -" - ;; - - *) - $echo >> $output "\ - # Export the path to the program. - PATH=\"\$progdir:\$PATH\" - export PATH - - exec \$program \${1+\"\$@\"} -" - ;; - esac - $echo >> $output "\ - \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" - exit 1 - fi - else - # The program doesn't exist. - \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 - \$echo \"This script is just a wrapper for \$program.\" 1>&2 - echo \"See the $PACKAGE documentation for more information.\" 1>&2 - exit 1 - fi -fi\ -" - chmod +x $output - fi - exit 0 - ;; - esac - - # See if we need to build an old-fashioned archive. - for oldlib in $oldlibs; do - - if test "$build_libtool_libs" = convenience; then - oldobjs="$libobjs_save" - addlibs="$convenience" - build_libtool_libs=no - else - if test "$build_libtool_libs" = module; then - oldobjs="$libobjs_save" - build_libtool_libs=no - else - oldobjs="$objs$old_deplibs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP` - fi - addlibs="$old_convenience" - fi - - if test -n "$addlibs"; then - gentop="$output_objdir/${outputname}x" - $show "${rm}r $gentop" - $run ${rm}r "$gentop" - $show "mkdir $gentop" - $run mkdir "$gentop" - status=$? - if test $status -ne 0 && test ! -d "$gentop"; then - exit $status - fi - generated="$generated $gentop" - - # Add in members from convenience archives. - for xlib in $addlibs; do - # Extract the objects. - case $xlib in - [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; - *) xabs=`pwd`"/$xlib" ;; - esac - xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` - xdir="$gentop/$xlib" - - $show "${rm}r $xdir" - $run ${rm}r "$xdir" - $show "mkdir $xdir" - $run mkdir "$xdir" - status=$? - if test $status -ne 0 && test ! -d "$xdir"; then - exit $status - fi - $show "(cd $xdir && $AR x $xabs)" - $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? - - oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP` - done - fi - - # Do each command in the archive commands. - if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then - eval cmds=\"$old_archive_from_new_cmds\" - else - # Ensure that we have .o objects in place in case we decided - # not to build a shared library, and have fallen back to building - # static libs even though --disable-static was passed! - for oldobj in $oldobjs; do - if test ! -f $oldobj; then - xdir=`$echo "X$oldobj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$oldobj"; then - xdir="." - else - xdir="$xdir" - fi - baseobj=`$echo "X$oldobj" | $Xsed -e 's%^.*/%%'` - obj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` - $show "(cd $xdir && ${LN_S} $obj $baseobj)" - $run eval '(cd $xdir && ${LN_S} $obj $baseobj)' || exit $? - fi - done - - eval cmds=\"$old_archive_cmds\" - fi - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - done - - if test -n "$generated"; then - $show "${rm}r$generated" - $run ${rm}r$generated - fi - - # Now create the libtool archive. - case $output in - *.la) - old_library= - test "$build_old_libs" = yes && old_library="$libname.$libext" - $show "creating $output" - - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` - relink_command="$var=\"$var_value\"; export $var; $relink_command" - fi - done - # Quote the link command for shipping. - relink_command="(cd `pwd`; $SHELL $0 --mode=relink $libtool_args @inst_prefix_dir@)" - relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` - - # Only create the output if not a dry run. - if test -z "$run"; then - for installed in no yes; do - if test "$installed" = yes; then - if test -z "$install_libdir"; then - break - fi - output="$output_objdir/$outputname"i - # Replace all uninstalled libtool libraries with the installed ones - newdependency_libs= - for deplib in $dependency_libs; do - case $deplib in - *.la) - name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - if test -z "$libdir"; then - $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 - exit 1 - fi - newdependency_libs="$newdependency_libs $libdir/$name" - ;; - *) newdependency_libs="$newdependency_libs $deplib" ;; - esac - done - dependency_libs="$newdependency_libs" - newdlfiles= - for lib in $dlfiles; do - name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - if test -z "$libdir"; then - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit 1 - fi - newdlfiles="$newdlfiles $libdir/$name" - done - dlfiles="$newdlfiles" - newdlprefiles= - for lib in $dlprefiles; do - name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - if test -z "$libdir"; then - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit 1 - fi - newdlprefiles="$newdlprefiles $libdir/$name" - done - dlprefiles="$newdlprefiles" - fi - $rm $output - # place dlname in correct position for cygwin - tdlname=$dlname - case $host,$output,$installed,$module,$dlname in - *cygwin*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; - esac - $echo > $output "\ -# $outputname - a libtool library file -# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='$tdlname' - -# Names of this library. -library_names='$library_names' - -# The name of the static archive. -old_library='$old_library' - -# Libraries that this one depends upon. -dependency_libs='$dependency_libs' - -# Version information for $libname. -current=$current -age=$age -revision=$revision - -# Is this an already installed library? -installed=$installed - -# Files to dlopen/dlpreopen -dlopen='$dlfiles' -dlpreopen='$dlprefiles' - -# Directory that this library needs to be installed in: -libdir='$install_libdir'" - if test "$installed" = no && test $need_relink = yes; then - $echo >> $output "\ -relink_command=\"$relink_command\"" - fi - done - fi - - # Do a symbolic link so that the libtool archive can be found in - # LD_LIBRARY_PATH before the program is installed. - $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" - $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? - ;; - esac - exit 0 - ;; - - # libtool install mode - install) - modename="$modename: install" - - # There may be an optional sh(1) argument at the beginning of - # install_prog (especially on Windows NT). - if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || - # Allow the use of GNU shtool's install command. - $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then - # Aesthetically quote it. - arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) - arg="\"$arg\"" - ;; - esac - install_prog="$arg " - arg="$1" - shift - else - install_prog= - arg="$nonopt" - fi - - # The real first argument should be the name of the installation program. - # Aesthetically quote it. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) - arg="\"$arg\"" - ;; - esac - install_prog="$install_prog$arg" - - # We need to accept at least all the BSD install flags. - dest= - files= - opts= - prev= - install_type= - isdir=no - stripme= - for arg - do - if test -n "$dest"; then - files="$files $dest" - dest="$arg" - continue - fi - - case $arg in - -d) isdir=yes ;; - -f) prev="-f" ;; - -g) prev="-g" ;; - -m) prev="-m" ;; - -o) prev="-o" ;; - -s) - stripme=" -s" - continue - ;; - -*) ;; - - *) - # If the previous option needed an argument, then skip it. - if test -n "$prev"; then - prev= - else - dest="$arg" - continue - fi - ;; - esac - - # Aesthetically quote the argument. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) - arg="\"$arg\"" - ;; - esac - install_prog="$install_prog $arg" - done - - if test -z "$install_prog"; then - $echo "$modename: you must specify an install program" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - if test -n "$prev"; then - $echo "$modename: the \`$prev' option requires an argument" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - if test -z "$files"; then - if test -z "$dest"; then - $echo "$modename: no file or destination specified" 1>&2 - else - $echo "$modename: you must specify a destination" 1>&2 - fi - $echo "$help" 1>&2 - exit 1 - fi - - # Strip any trailing slash from the destination. - dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` - - # Check to see that the destination is a directory. - test -d "$dest" && isdir=yes - if test "$isdir" = yes; then - destdir="$dest" - destname= - else - destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` - test "X$destdir" = "X$dest" && destdir=. - destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` - - # Not a directory, so check to see that there is only one file specified. - set dummy $files - if test $# -gt 2; then - $echo "$modename: \`$dest' is not a directory" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - fi - case $destdir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - for file in $files; do - case $file in - *.lo) ;; - *) - $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; - esac - done - ;; - esac - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - staticlibs= - future_libdirs= - current_libdirs= - for file in $files; do - - # Do each installation. - case $file in - *.$libext) - # Do the static libraries later. - staticlibs="$staticlibs $file" - ;; - - *.la) - # Check to see that this really is a libtool archive. - if (${SED} -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - library_names= - old_library= - relink_command= - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Add the libdir to current_libdirs if it is the destination. - if test "X$destdir" = "X$libdir"; then - case "$current_libdirs " in - *" $libdir "*) ;; - *) current_libdirs="$current_libdirs $libdir" ;; - esac - else - # Note the libdir as a future libdir. - case "$future_libdirs " in - *" $libdir "*) ;; - *) future_libdirs="$future_libdirs $libdir" ;; - esac - fi - - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ - test "X$dir" = "X$file/" && dir= - dir="$dir$objdir" - - if test -n "$relink_command"; then - # Determine the prefix the user has applied to our future dir. - inst_prefix_dir=`$echo "$destdir" | sed "s%$libdir\$%%"` - - # Don't allow the user to place us outside of our expected - # location b/c this prevents finding dependent libraries that - # are installed to the same prefix. - if test "$inst_prefix_dir" = "$destdir"; then - $echo "$modename: error: cannot install \`$file' to a directory not ending in $libdir" 1>&2 - exit 1 - fi - - if test -n "$inst_prefix_dir"; then - # Stick the inst_prefix_dir data into the link command. - relink_command=`$echo "$relink_command" | sed "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` - else - relink_command=`$echo "$relink_command" | sed "s%@inst_prefix_dir@%%"` - fi - - $echo "$modename: warning: relinking \`$file'" 1>&2 - $show "$relink_command" - if $run eval "$relink_command"; then : - else - $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 - continue - fi - fi - - # See the names of the shared library. - set dummy $library_names - if test -n "$2"; then - realname="$2" - shift - shift - - srcname="$realname" - test -n "$relink_command" && srcname="$realname"T - - # Install the shared library and build the symlinks. - $show "$install_prog $dir/$srcname $destdir/$realname" - $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? - if test -n "$stripme" && test -n "$striplib"; then - $show "$striplib $destdir/$realname" - $run eval "$striplib $destdir/$realname" || exit $? - fi - - if test $# -gt 0; then - # Delete the old symlinks, and create new ones. - for linkname - do - if test "$linkname" != "$realname"; then - $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" - $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" - fi - done - fi - - # Do each command in the postinstall commands. - lib="$destdir/$realname" - eval cmds=\"$postinstall_cmds\" - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - - # Install the pseudo-library for information purposes. - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - instname="$dir/$name"i - $show "$install_prog $instname $destdir/$name" - $run eval "$install_prog $instname $destdir/$name" || exit $? - - # Maybe install the static library, too. - test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" - ;; - - *.lo) - # Install (i.e. copy) a libtool object. - - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - destfile="$destdir/$destfile" - fi - - # Deduce the name of the destination old-style object file. - case $destfile in - *.lo) - staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` - ;; - *.$objext) - staticdest="$destfile" - destfile= - ;; - *) - $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; - esac - - # Install the libtool object if requested. - if test -n "$destfile"; then - $show "$install_prog $file $destfile" - $run eval "$install_prog $file $destfile" || exit $? - fi - - # Install the old object if enabled. - if test "$build_old_libs" = yes; then - # Deduce the name of the old-style object file. - staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` - - $show "$install_prog $staticobj $staticdest" - $run eval "$install_prog \$staticobj \$staticdest" || exit $? - fi - exit 0 - ;; - - *) - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - destfile="$destdir/$destfile" - fi - - # Do a test to see if this is really a libtool program. - case $host in - *cygwin*|*mingw*) - wrapper=`echo $file | ${SED} -e 's,.exe$,,'` - ;; - *) - wrapper=$file - ;; - esac - if (${SED} -e '4q' $wrapper | egrep "^# Generated by .*$PACKAGE")>/dev/null 2>&1; then - notinst_deplibs= - relink_command= - - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $wrapper ;; - *) . ./$wrapper ;; - esac - - # Check the variables that should have been set. - if test -z "$notinst_deplibs"; then - $echo "$modename: invalid libtool wrapper script \`$wrapper'" 1>&2 - exit 1 - fi - - finalize=yes - for lib in $notinst_deplibs; do - # Check to see that each library is installed. - libdir= - if test -f "$lib"; then - # If there is no directory component, then add one. - case $lib in - */* | *\\*) . $lib ;; - *) . ./$lib ;; - esac - fi - libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test - if test -n "$libdir" && test ! -f "$libfile"; then - $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 - finalize=no - fi - done - - relink_command= - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $wrapper ;; - *) . ./$wrapper ;; - esac - - outputname= - if test "$fast_install" = no && test -n "$relink_command"; then - if test "$finalize" = yes && test -z "$run"; then - tmpdir="/tmp" - test -n "$TMPDIR" && tmpdir="$TMPDIR" - tmpdir=`mktemp -d $tmpdir/libtool-XXXXXX 2> /dev/null` - if test $? = 0 ; then : - else - tmpdir="$tmpdir/libtool-$$" - fi - if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then : - else - $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 - continue - fi - file=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - outputname="$tmpdir/$file" - # Replace the output file specification. - relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` - - $show "$relink_command" - if $run eval "$relink_command"; then : - else - $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 - ${rm}r "$tmpdir" - continue - fi - file="$outputname" - else - $echo "$modename: warning: cannot relink \`$file'" 1>&2 - fi - else - # Install the binary that we compiled earlier. - file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` - fi - fi - - # remove .exe since cygwin /usr/bin/install will append another - # one anyways - case $install_prog,$host in - /usr/bin/install*,*cygwin*) - case $file:$destfile in - *.exe:*.exe) - # this is ok - ;; - *.exe:*) - destfile=$destfile.exe - ;; - *:*.exe) - destfile=`echo $destfile | ${SED} -e 's,.exe$,,'` - ;; - esac - ;; - esac - $show "$install_prog$stripme $file $destfile" - $run eval "$install_prog\$stripme \$file \$destfile" || exit $? - test -n "$outputname" && ${rm}r "$tmpdir" - ;; - esac - done - - for file in $staticlibs; do - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - - # Set up the ranlib parameters. - oldlib="$destdir/$name" - - $show "$install_prog $file $oldlib" - $run eval "$install_prog \$file \$oldlib" || exit $? - - if test -n "$stripme" && test -n "$striplib"; then - $show "$old_striplib $oldlib" - $run eval "$old_striplib $oldlib" || exit $? - fi - - # Do each command in the postinstall commands. - eval cmds=\"$old_postinstall_cmds\" - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - done - - if test -n "$future_libdirs"; then - $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 - fi - - if test -n "$current_libdirs"; then - # Maybe just do a dry run. - test -n "$run" && current_libdirs=" -n$current_libdirs" - exec_cmd='$SHELL $0 --finish$current_libdirs' - else - exit 0 - fi - ;; - - # libtool finish mode - finish) - modename="$modename: finish" - libdirs="$nonopt" - admincmds= - - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then - for dir - do - libdirs="$libdirs $dir" - done - - for libdir in $libdirs; do - if test -n "$finish_cmds"; then - # Do each command in the finish commands. - eval cmds=\"$finish_cmds\" - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || admincmds="$admincmds - $cmd" - done - IFS="$save_ifs" - fi - if test -n "$finish_eval"; then - # Do the single finish_eval. - eval cmds=\"$finish_eval\" - $run eval "$cmds" || admincmds="$admincmds - $cmds" - fi - done - fi - - # Exit here if they wanted silent mode. - test "$show" = ":" && exit 0 - - echo "----------------------------------------------------------------------" - echo "Libraries have been installed in:" - for libdir in $libdirs; do - echo " $libdir" - done - echo - echo "If you ever happen to want to link against installed libraries" - echo "in a given directory, LIBDIR, you must either use libtool, and" - echo "specify the full pathname of the library, or use the \`-LLIBDIR'" - echo "flag during linking and do at least one of the following:" - if test -n "$shlibpath_var"; then - echo " - add LIBDIR to the \`$shlibpath_var' environment variable" - echo " during execution" - fi - if test -n "$runpath_var"; then - echo " - add LIBDIR to the \`$runpath_var' environment variable" - echo " during linking" - fi - if test -n "$hardcode_libdir_flag_spec"; then - libdir=LIBDIR - eval flag=\"$hardcode_libdir_flag_spec\" - - echo " - use the \`$flag' linker flag" - fi - if test -n "$admincmds"; then - echo " - have your system administrator run these commands:$admincmds" - fi - if test -f /etc/ld.so.conf; then - echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" - fi - echo - echo "See any operating system documentation about shared libraries for" - echo "more information, such as the ld(1) and ld.so(8) manual pages." - echo "----------------------------------------------------------------------" - exit 0 - ;; - - # libtool execute mode - execute) - modename="$modename: execute" - - # The first argument is the command name. - cmd="$nonopt" - if test -z "$cmd"; then - $echo "$modename: you must specify a COMMAND" 1>&2 - $echo "$help" - exit 1 - fi - - # Handle -dlopen flags immediately. - for file in $execute_dlfiles; do - if test ! -f "$file"; then - $echo "$modename: \`$file' is not a file" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - dir= - case $file in - *.la) - # Check to see that this really is a libtool archive. - if (${SED} -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - # Read the libtool library. - dlname= - library_names= - - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Skip this library if it cannot be dlopened. - if test -z "$dlname"; then - # Warn if it was a shared library. - test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" - continue - fi - - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$file" && dir=. - - if test -f "$dir/$objdir/$dlname"; then - dir="$dir/$objdir" - else - $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 - exit 1 - fi - ;; - - *.lo) - # Just add the directory containing the .lo file. - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$file" && dir=. - ;; - - *) - $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 - continue - ;; - esac - - # Get the absolute pathname. - absdir=`cd "$dir" && pwd` - test -n "$absdir" && dir="$absdir" - - # Now add the directory to shlibpath_var. - if eval "test -z \"\$$shlibpath_var\""; then - eval "$shlibpath_var=\"\$dir\"" - else - eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" - fi - done - - # This variable tells wrapper scripts just to set shlibpath_var - # rather than running their programs. - libtool_execute_magic="$magic" - - # Check if any of the arguments is a wrapper script. - args= - for file - do - case $file in - -*) ;; - *) - # Do a test to see if this is really a libtool program. - if (${SED} -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Transform arg to wrapped name. - file="$progdir/$program" - fi - ;; - esac - # Quote arguments (to preserve shell metacharacters). - file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` - args="$args \"$file\"" - done - - if test -z "$run"; then - if test -n "$shlibpath_var"; then - # Export the shlibpath_var. - eval "export $shlibpath_var" - fi - - # Restore saved enviroment variables - if test "${save_LC_ALL+set}" = set; then - LC_ALL="$save_LC_ALL"; export LC_ALL - fi - if test "${save_LANG+set}" = set; then - LANG="$save_LANG"; export LANG - fi - - # Now prepare to actually exec the command. - exec_cmd="\$cmd$args" - else - # Display what would be done. - if test -n "$shlibpath_var"; then - eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" - $echo "export $shlibpath_var" - fi - $echo "$cmd$args" - exit 0 - fi - ;; - - # libtool clean and uninstall mode - clean | uninstall) - modename="$modename: $mode" - rm="$nonopt" - files= - rmforce= - exit_status=0 - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - for arg - do - case $arg in - -f) rm="$rm $arg"; rmforce=yes ;; - -*) rm="$rm $arg" ;; - *) files="$files $arg" ;; - esac - done - - if test -z "$rm"; then - $echo "$modename: you must specify an RM program" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - rmdirs= - - for file in $files; do - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - if test "X$dir" = "X$file"; then - dir=. - objdir="$objdir" - else - objdir="$dir/$objdir" - fi - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - test $mode = uninstall && objdir="$dir" - - # Remember objdir for removal later, being careful to avoid duplicates - if test $mode = clean; then - case " $rmdirs " in - *" $objdir "*) ;; - *) rmdirs="$rmdirs $objdir" ;; - esac - fi - - # Don't error if the file doesn't exist and rm -f was used. - if (test -L "$file") >/dev/null 2>&1 \ - || (test -h "$file") >/dev/null 2>&1 \ - || test -f "$file"; then - : - elif test -d "$file"; then - exit_status=1 - continue - elif test "$rmforce" = yes; then - continue - fi - - rmfiles="$file" - - case $name in - *.la) - # Possibly a libtool archive, so verify it. - if (${SED} -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - . $dir/$name - - # Delete the libtool libraries and symlinks. - for n in $library_names; do - rmfiles="$rmfiles $objdir/$n" - done - test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" - test $mode = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" - - if test $mode = uninstall; then - if test -n "$library_names"; then - # Do each command in the postuninstall commands. - eval cmds=\"$postuninstall_cmds\" - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" - if test $? != 0 && test "$rmforce" != yes; then - exit_status=1 - fi - done - IFS="$save_ifs" - fi - - if test -n "$old_library"; then - # Do each command in the old_postuninstall commands. - eval cmds=\"$old_postuninstall_cmds\" - save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" - if test $? != 0 && test "$rmforce" != yes; then - exit_status=1 - fi - done - IFS="$save_ifs" - fi - # FIXME: should reinstall the best remaining shared library. - fi - fi - ;; - - *.lo) - if test "$build_old_libs" = yes; then - oldobj=`$echo "X$name" | $Xsed -e "$lo2o"` - rmfiles="$rmfiles $dir/$oldobj" - fi - ;; - - *) - # Do a test to see if this is a libtool program. - if test $mode = clean && - (${SED} -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - relink_command= - . $dir/$file - - rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" - if test "$fast_install" = yes && test -n "$relink_command"; then - rmfiles="$rmfiles $objdir/lt-$name" - fi - fi - ;; - esac - $show "$rm $rmfiles" - $run $rm $rmfiles || exit_status=1 - done - - # Try to remove the ${objdir}s in the directories where we deleted files - for dir in $rmdirs; do - if test -d "$dir"; then - $show "rmdir $dir" - $run rmdir $dir >/dev/null 2>&1 - fi - done - - exit $exit_status - ;; - - "") - $echo "$modename: you must specify a MODE" 1>&2 - $echo "$generic_help" 1>&2 - exit 1 - ;; - esac - - if test -z "$exec_cmd"; then - $echo "$modename: invalid operation mode \`$mode'" 1>&2 - $echo "$generic_help" 1>&2 - exit 1 - fi -fi # test -z "$show_help" - -if test -n "$exec_cmd"; then - eval exec $exec_cmd - exit 1 -fi - -# We need to display help for each of the modes. -case $mode in -"") $echo \ -"Usage: $modename [OPTION]... [MODE-ARG]... - -Provide generalized library-building support services. - - --config show all configuration variables - --debug enable verbose shell tracing --n, --dry-run display commands without modifying any files - --features display basic configuration information and exit - --finish same as \`--mode=finish' - --help display this help message and exit - --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] - --quiet same as \`--silent' - --silent don't print informational messages - --version print version information - -MODE must be one of the following: - - clean remove files from the build directory - compile compile a source file into a libtool object - execute automatically set library path, then run a program - finish complete the installation of libtool libraries - install install libraries or executables - link create a library or an executable - uninstall remove libraries from an installed directory - -MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for -a more detailed description of MODE." - exit 0 - ;; - -clean) - $echo \ -"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... - -Remove files from the build directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, object or program, all the files associated -with it are deleted. Otherwise, only FILE itself is deleted using RM." - ;; - -compile) - $echo \ -"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE - -Compile a source file into a libtool library object. - -This mode accepts the following additional options: - - -o OUTPUT-FILE set the output file name to OUTPUT-FILE - -prefer-pic try to building PIC objects only - -prefer-non-pic try to building non-PIC objects only - -static always build a \`.o' file suitable for static linking - -COMPILE-COMMAND is a command to be used in creating a \`standard' object file -from the given SOURCEFILE. - -The output file name is determined by removing the directory component from -SOURCEFILE, then substituting the C source code suffix \`.c' with the -library object suffix, \`.lo'." - ;; - -execute) - $echo \ -"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... - -Automatically set library path, then run a program. - -This mode accepts the following additional options: - - -dlopen FILE add the directory containing FILE to the library path - -This mode sets the library path environment variable according to \`-dlopen' -flags. - -If any of the ARGS are libtool executable wrappers, then they are translated -into their corresponding uninstalled binary, and any of their required library -directories are added to the library path. - -Then, COMMAND is executed, with ARGS as arguments." - ;; - -finish) - $echo \ -"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... - -Complete the installation of libtool libraries. - -Each LIBDIR is a directory that contains libtool libraries. - -The commands that this mode executes may require superuser privileges. Use -the \`--dry-run' option if you just want to see what would be executed." - ;; - -install) - $echo \ -"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... - -Install executables or libraries. - -INSTALL-COMMAND is the installation command. The first component should be -either the \`install' or \`cp' program. - -The rest of the components are interpreted as arguments to that command (only -BSD-compatible install options are recognized)." - ;; - -link) - $echo \ -"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... - -Link object files or libraries together to form another library, or to -create an executable program. - -LINK-COMMAND is a command using the C compiler that you would use to create -a program from several object files. - -The following components of LINK-COMMAND are treated specially: - - -all-static do not do any dynamic linking at all - -avoid-version do not add a version suffix if possible - -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime - -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols - -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) - -export-symbols SYMFILE - try to export only the symbols listed in SYMFILE - -export-symbols-regex REGEX - try to export only the symbols matching REGEX - -LLIBDIR search LIBDIR for required installed libraries - -lNAME OUTPUT-FILE requires the installed library libNAME - -module build a library that can dlopened - -no-fast-install disable the fast-install mode - -no-install link a not-installable executable - -no-undefined declare that a library does not refer to external symbols - -o OUTPUT-FILE create OUTPUT-FILE from the specified objects - -release RELEASE specify package release information - -rpath LIBDIR the created library will eventually be installed in LIBDIR - -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries - -static do not do any dynamic linking of libtool libraries - -version-info CURRENT[:REVISION[:AGE]] - specify library version info [each variable defaults to 0] - -All other options (arguments beginning with \`-') are ignored. - -Every other argument is treated as a filename. Files ending in \`.la' are -treated as uninstalled libtool libraries, other files are standard or library -object files. - -If the OUTPUT-FILE ends in \`.la', then a libtool library is created, -only library objects (\`.lo' files) may be specified, and \`-rpath' is -required, except when creating a convenience library. - -If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created -using \`ar' and \`ranlib', or on Windows using \`lib'. - -If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file -is created, otherwise an executable program is created." - ;; - -uninstall) - $echo \ -"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... - -Remove libraries from an installation directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, all the files associated with it are deleted. -Otherwise, only FILE itself is deleted using RM." - ;; - -*) - $echo "$modename: invalid operation mode \`$mode'" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; -esac - -echo -$echo "Try \`$modename --help' for more information about other modes." - -exit 0 - -# Local Variables: -# mode:shell-script -# sh-indentation:2 -# End: diff --git a/engine/voice_codecs/speex/source/missing b/engine/voice_codecs/speex/source/missing deleted file mode 100644 index 22e101ab..00000000 --- a/engine/voice_codecs/speex/source/missing +++ /dev/null @@ -1,198 +0,0 @@ -#! /bin/sh -# Common stub for a few missing GNU programs while installing. -# Copyright (C) 1996, 1997, 2001, 2002 Free Software Foundation, Inc. -# Franc,ois Pinard , 1996. - -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. - -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA -# 02111-1307, USA. - -if test $# -eq 0; then - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 -fi - -# In the cases where this matters, `missing' is being run in the -# srcdir already. -if test -f configure.in; then - configure_ac=configure.ac -else - configure_ac=configure.in -fi - -case "$1" in - - -h|--h|--he|--hel|--help) - echo "\ -$0 [OPTION]... PROGRAM [ARGUMENT]... - -Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an -error status if there is no known handling for PROGRAM. - -Options: - -h, --help display this help and exit - -v, --version output version information and exit - -Supported PROGRAM values: - aclocal touch file \`aclocal.m4' - autoconf touch file \`configure' - autoheader touch file \`config.h.in' - automake touch all \`Makefile.in' files - bison create \`y.tab.[ch]', if possible, from existing .[ch] - flex create \`lex.yy.c', if possible, from existing .c - lex create \`lex.yy.c', if possible, from existing .c - makeinfo touch the output file - yacc create \`y.tab.[ch]', if possible, from existing .[ch]" - ;; - - -v|--v|--ve|--ver|--vers|--versi|--versio|--version) - echo "missing - GNU libit 0.0" - ;; - - -*) - echo 1>&2 "$0: Unknown \`$1' option" - echo 1>&2 "Try \`$0 --help' for more information" - exit 1 - ;; - - aclocal*) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`acinclude.m4' or \`$configure_ac'. You might want - to install the \`Automake' and \`Perl' packages. Grab them from - any GNU archive site." - touch aclocal.m4 - ;; - - autoconf) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`$configure_ac'. You might want to install the - \`Autoconf' and \`GNU m4' packages. Grab them from any GNU - archive site." - touch configure - ;; - - autoheader) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`acconfig.h' or \`$configure_ac'. You might want - to install the \`Autoconf' and \`GNU m4' packages. Grab them - from any GNU archive site." - files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' $configure_ac` - test -z "$files" && files="config.h" - touch_files= - for f in $files; do - case "$f" in - *:*) touch_files="$touch_files "`echo "$f" | - sed -e 's/^[^:]*://' -e 's/:.*//'`;; - *) touch_files="$touch_files $f.in";; - esac - done - touch $touch_files - ;; - - automake*) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified \`Makefile.am', \`acinclude.m4' or \`$configure_ac'. - You might want to install the \`Automake' and \`Perl' packages. - Grab them from any GNU archive site." - find . -type f -name Makefile.am -print | - sed 's/\.am$/.in/' | - while read f; do touch "$f"; done - ;; - - bison|yacc) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a \`.y' file. You may need the \`Bison' package - in order for those modifications to take effect. You can get - \`Bison' from any GNU archive site." - rm -f y.tab.c y.tab.h - if [ $# -ne 1 ]; then - eval LASTARG="\${$#}" - case "$LASTARG" in - *.y) - SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" y.tab.c - fi - SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" y.tab.h - fi - ;; - esac - fi - if [ ! -f y.tab.h ]; then - echo >y.tab.h - fi - if [ ! -f y.tab.c ]; then - echo 'main() { return 0; }' >y.tab.c - fi - ;; - - lex|flex) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a \`.l' file. You may need the \`Flex' package - in order for those modifications to take effect. You can get - \`Flex' from any GNU archive site." - rm -f lex.yy.c - if [ $# -ne 1 ]; then - eval LASTARG="\${$#}" - case "$LASTARG" in - *.l) - SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` - if [ -f "$SRCFILE" ]; then - cp "$SRCFILE" lex.yy.c - fi - ;; - esac - fi - if [ ! -f lex.yy.c ]; then - echo 'main() { return 0; }' >lex.yy.c - fi - ;; - - makeinfo) - echo 1>&2 "\ -WARNING: \`$1' is missing on your system. You should only need it if - you modified a \`.texi' or \`.texinfo' file, or any other file - indirectly affecting the aspect of the manual. The spurious - call might also be the consequence of using a buggy \`make' (AIX, - DU, IRIX). You might want to install the \`Texinfo' package or - the \`GNU make' package. Grab either from any GNU archive site." - file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` - if test -z "$file"; then - file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` - file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` - fi - touch $file - ;; - - *) - echo 1>&2 "\ -WARNING: \`$1' is needed, and you do not seem to have it handy on your - system. You might have modified some files without having the - proper tools for further handling them. Check the \`README' file, - it often tells you about the needed prerequirements for installing - this package. You may also peek at any GNU archive site, in case - some other package would contain this missing \`$1' program." - exit 1 - ;; -esac - -exit 0 diff --git a/engine/voice_codecs/speex/source/mkinstalldirs b/engine/voice_codecs/speex/source/mkinstalldirs deleted file mode 100644 index 4f58503e..00000000 --- a/engine/voice_codecs/speex/source/mkinstalldirs +++ /dev/null @@ -1,40 +0,0 @@ -#! /bin/sh -# mkinstalldirs --- make directory hierarchy -# Author: Noah Friedman -# Created: 1993-05-16 -# Public domain - -# $Id: mkinstalldirs,v 1.13 1999/01/05 03:18:55 bje Exp $ - -errstatus=0 - -for file -do - set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` - shift - - pathcomp= - for d - do - pathcomp="$pathcomp$d" - case "$pathcomp" in - -* ) pathcomp=./$pathcomp ;; - esac - - if test ! -d "$pathcomp"; then - echo "mkdir $pathcomp" - - mkdir "$pathcomp" || lasterr=$? - - if test ! -d "$pathcomp"; then - errstatus=$lasterr - fi - fi - - pathcomp="$pathcomp/" - done -done - -exit $errstatus - -# mkinstalldirs ends here diff --git a/engine/voice_codecs/speex/source/osx/libspeex.a b/engine/voice_codecs/speex/source/osx/libspeex.a deleted file mode 100644 index af9a8c94..00000000 Binary files a/engine/voice_codecs/speex/source/osx/libspeex.a and /dev/null differ diff --git a/engine/voice_codecs/speex/source/speex.sln b/engine/voice_codecs/speex/source/speex.sln deleted file mode 100644 index cede7d33..00000000 --- a/engine/voice_codecs/speex/source/speex.sln +++ /dev/null @@ -1,22 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibSpeex", "speex.vcxproj", "{60902B83-8B26-4DBD-B635-4CECF5F4744C}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x86 = Debug|x86 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {60902B83-8B26-4DBD-B635-4CECF5F4744C}.Debug|x86.ActiveCfg = Debug|Win32 - {60902B83-8B26-4DBD-B635-4CECF5F4744C}.Debug|x86.Build.0 = Debug|Win32 - {60902B83-8B26-4DBD-B635-4CECF5F4744C}.Release|x86.ActiveCfg = Release|Win32 - {60902B83-8B26-4DBD-B635-4CECF5F4744C}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/engine/voice_codecs/speex/source/speex.vcxproj b/engine/voice_codecs/speex/source/speex.vcxproj deleted file mode 100644 index b6da34be..00000000 --- a/engine/voice_codecs/speex/source/speex.vcxproj +++ /dev/null @@ -1,167 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - LibSpeex - {60902B83-8B26-4DBD-B635-4CECF5F4744C} - LibSpeex - Win32Proj - 8.1 - - - - StaticLibrary - v140_xp - Unicode - true - - - StaticLibrary - v140_xp - Unicode - - - - - - - - - - - - - <_ProjectFileVersion>14.0.25431.1 - - - $(SolutionDir)$(Configuration)_2015\lib\ - $(SolutionDir)$(Configuration)_2015\$(ProjectName)\ - - - $(SolutionDir)$(Configuration)_2015\lib\ - $(SolutionDir)$(Configuration)_2015\$(ProjectName)\ - - - - Disabled - ../../speex/include;../../speex/win32;%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_LIB;HAVE_CONFIG_H;M_PI=3.14159265358979323846;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS - true - true - - EnableFastChecks - MultiThreadedDebug - true - Fast - false - - Level3 - true - ProgramDatabase - 4018;4244;%(DisableSpecificWarnings) - - - win32\libspeex\2015\debug\libspeex.lib - - - - - MaxSpeed - true - ../../speex/include;../../speex/win32;%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_LIB;HAVE_CONFIG_H;M_PI=3.14159265358979323846;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS - true - - MultiThreaded - true - Fast - false - - Level3 - true - ProgramDatabase - 4018;4244;%(DisableSpecificWarnings) - - - win32\libspeex\2015\release\libspeex.lib - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/engine/voice_codecs/speex/source/win32/libspeex/2015/debug/libspeex.lib b/engine/voice_codecs/speex/source/win32/libspeex/2015/debug/libspeex.lib deleted file mode 100644 index aec22379..00000000 Binary files a/engine/voice_codecs/speex/source/win32/libspeex/2015/debug/libspeex.lib and /dev/null differ diff --git a/engine/voice_codecs/speex/source/win32/libspeex/2015/release/libspeex.lib b/engine/voice_codecs/speex/source/win32/libspeex/2015/release/libspeex.lib deleted file mode 100644 index 78ee73c9..00000000 Binary files a/engine/voice_codecs/speex/source/win32/libspeex/2015/release/libspeex.lib and /dev/null differ diff --git a/engine/voice_codecs/speex/source/win32/libspeex/release/libspeex.lib b/engine/voice_codecs/speex/source/win32/libspeex/release/libspeex.lib deleted file mode 100644 index 8be14a88..00000000 Binary files a/engine/voice_codecs/speex/source/win32/libspeex/release/libspeex.lib and /dev/null differ diff --git a/engine/voice_codecs/speex/source/libspeex/speex.h b/engine/voice_codecs/speex/speex/speex.h similarity index 62% rename from engine/voice_codecs/speex/source/libspeex/speex.h rename to engine/voice_codecs/speex/speex/speex.h index cafd0cda..28c4b44d 100644 --- a/engine/voice_codecs/speex/source/libspeex/speex.h +++ b/engine/voice_codecs/speex/speex/speex.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 Jean-Marc Valin*/ +/* Copyright (C) 2002-2006 Jean-Marc Valin*/ /** @file speex.h @brief Describes the different modes of the codec @@ -7,18 +7,18 @@ 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. - + - Neither the name of the Xiph.org Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + 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 @@ -35,7 +35,12 @@ #ifndef SPEEX_H #define SPEEX_H +/** @defgroup Codec Speex encoder and decoder + * This is the Speex codec itself. + * @{ + */ +#include "speex_types.h" #include "speex_bits.h" #ifdef __cplusplus @@ -56,7 +61,7 @@ extern "C" { /** Set quality value */ #define SPEEX_SET_QUALITY 4 /** Get current quality setting */ -#define SPEEX_GET_QUALITY 5 +/* #define SPEEX_GET_QUALITY 5 -- Doesn't make much sense, does it? */ /** Set sub-mode to use */ #define SPEEX_SET_MODE 6 @@ -93,10 +98,10 @@ extern "C" { /** Get current bit-rate used by the encoder or decoder */ #define SPEEX_GET_BITRATE 19 -/**Define a handler function for in-band Speex request*/ +/** Define a handler function for in-band Speex request*/ #define SPEEX_SET_HANDLER 20 -/**Define a handler function for in-band user-defined request*/ +/** Define a handler function for in-band user-defined request*/ #define SPEEX_SET_USER_HANDLER 22 /** Set sampling rate used in bit-rate computation */ @@ -126,16 +131,34 @@ extern "C" { /** Get DTX status (1 for on, 0 for off) */ #define SPEEX_GET_DTX 35 +/** Set submode encoding in each frame (1 for yes, 0 for no, setting to no breaks the standard) */ +#define SPEEX_SET_SUBMODE_ENCODING 36 +/** Get submode encoding in each frame */ +#define SPEEX_GET_SUBMODE_ENCODING 37 -/* Used internally, not to be used in applications */ -/** Used internally*/ -#define SPEEX_GET_PI_GAIN 100 -/** Used internally*/ -#define SPEEX_GET_EXC 101 -/** Used internally*/ -#define SPEEX_GET_INNOV 102 -/** Used internally*/ -#define SPEEX_GET_DTX_STATUS 103 +/*#define SPEEX_SET_LOOKAHEAD 38*/ +/** Returns the lookahead used by Speex separately for an encoder and a decoder. + * Sum encoder and decoder lookahead values to get the total codec lookahead. */ +#define SPEEX_GET_LOOKAHEAD 39 + +/** Sets tuning for packet-loss concealment (expected loss rate) */ +#define SPEEX_SET_PLC_TUNING 40 +/** Gets tuning for PLC */ +#define SPEEX_GET_PLC_TUNING 41 + +/** Sets the max bit-rate allowed in VBR mode */ +#define SPEEX_SET_VBR_MAX_BITRATE 42 +/** Gets the max bit-rate allowed in VBR mode */ +#define SPEEX_GET_VBR_MAX_BITRATE 43 + +/** Turn on/off input/output high-pass filtering */ +#define SPEEX_SET_HIGHPASS 44 +/** Get status of input/output high-pass filtering */ +#define SPEEX_GET_HIGHPASS 45 + +/** Get "activity level" of the last decoded frame, i.e. + how much damage we cause if we remove the frame */ +#define SPEEX_GET_ACTIVITY 47 /* Preserving compatibility:*/ @@ -145,6 +168,8 @@ extern "C" { #define SPEEX_GET_PF 1 + + /* Values allowed for mode queries */ /** Query the frame size of a mode */ #define SPEEX_MODE_FRAME_SIZE 0 @@ -153,52 +178,84 @@ extern "C" { #define SPEEX_SUBMODE_BITS_PER_FRAME 1 + +/** Get major Speex version */ +#define SPEEX_LIB_GET_MAJOR_VERSION 1 +/** Get minor Speex version */ +#define SPEEX_LIB_GET_MINOR_VERSION 3 +/** Get micro Speex version */ +#define SPEEX_LIB_GET_MICRO_VERSION 5 +/** Get extra Speex version */ +#define SPEEX_LIB_GET_EXTRA_VERSION 7 +/** Get Speex version string */ +#define SPEEX_LIB_GET_VERSION_STRING 9 + +/*#define SPEEX_LIB_SET_ALLOC_FUNC 10 +#define SPEEX_LIB_GET_ALLOC_FUNC 11 +#define SPEEX_LIB_SET_FREE_FUNC 12 +#define SPEEX_LIB_GET_FREE_FUNC 13 + +#define SPEEX_LIB_SET_WARNING_FUNC 14 +#define SPEEX_LIB_GET_WARNING_FUNC 15 +#define SPEEX_LIB_SET_ERROR_FUNC 16 +#define SPEEX_LIB_GET_ERROR_FUNC 17 +*/ + /** Number of defined modes in Speex */ #define SPEEX_NB_MODES 3 +/** modeID for the defined narrowband mode */ +#define SPEEX_MODEID_NB 0 + +/** modeID for the defined wideband mode */ +#define SPEEX_MODEID_WB 1 + +/** modeID for the defined ultra-wideband mode */ +#define SPEEX_MODEID_UWB 2 + struct SpeexMode; /* Prototypes for mode function pointers */ /** Encoder state initialization function */ -typedef void *(*encoder_init_func)(struct SpeexMode *mode); +typedef void *(*encoder_init_func)(const struct SpeexMode *mode); /** Encoder state destruction function */ typedef void (*encoder_destroy_func)(void *st); /** Main encoding function */ -typedef int (*encode_func)(void *state, float *in, SpeexBits *bits); +typedef int (*encode_func)(void *state, void *in, SpeexBits *bits); /** Function for controlling the encoder options */ typedef int (*encoder_ctl_func)(void *state, int request, void *ptr); /** Decoder state initialization function */ -typedef void *(*decoder_init_func)(struct SpeexMode *mode); +typedef void *(*decoder_init_func)(const struct SpeexMode *mode); /** Decoder state destruction function */ typedef void (*decoder_destroy_func)(void *st); /** Main decoding function */ -typedef int (*decode_func)(void *state, SpeexBits *bits, float *out); +typedef int (*decode_func)(void *state, SpeexBits *bits, void *out); /** Function for controlling the decoder options */ typedef int (*decoder_ctl_func)(void *state, int request, void *ptr); /** Query function for a mode */ -typedef int (*mode_query_func)(void *mode, int request, void *ptr); +typedef int (*mode_query_func)(const void *mode, int request, void *ptr); -/** Struct defining a Speex mode */ +/** Struct defining a Speex mode */ typedef struct SpeexMode { /** Pointer to the low-level mode data */ - void *mode; + const void *mode; /** Pointer to the mode query function */ mode_query_func query; - + /** The name of the mode (you should not rely on this to identify the mode)*/ - char *modeName; + const char *modeName; /**ID of the mode*/ int modeID; @@ -234,47 +291,59 @@ typedef struct SpeexMode { } SpeexMode; /** - * Returns a handle to a newly created Speex encoder state structure. For now, - * the "mode" argument can be &nb_mode or &wb_mode . In the future, more modes - * may be added. Note that for now if you have more than one channels to + * Returns a handle to a newly created Speex encoder state structure. For now, + * the "mode" argument can be &nb_mode or &wb_mode . In the future, more modes + * may be added. Note that for now if you have more than one channels to * encode, you need one state per channel. * - * @param mode The mode to use (either speex_nb_mode or speex_wb.mode) - * @return A newly created encoder + * @param mode The mode to use (either speex_nb_mode or speex_wb.mode) + * @return A newly created encoder state or NULL if state allocation fails */ -void *speex_encoder_init(SpeexMode *mode); +void *speex_encoder_init(const SpeexMode *mode); -/** Frees all resources associated to an existing Speex encoder state. +/** Frees all resources associated to an existing Speex encoder state. * @param state Encoder state to be destroyed */ void speex_encoder_destroy(void *state); /** Uses an existing encoder state to encode one frame of speech pointed to by "in". The encoded bit-stream is saved in "bits". @param state Encoder state - @param in Frame that will be encoded with a +-2^16 range + @param in Frame that will be encoded with a +-2^15 range. This data MAY be + overwritten by the encoder and should be considered uninitialised + after the call. @param bits Bit-stream where the data will be written + @return 0 if frame needs not be transmitted (DTX only), 1 otherwise */ int speex_encode(void *state, float *in, SpeexBits *bits); +/** Uses an existing encoder state to encode one frame of speech pointed to by + "in". The encoded bit-stream is saved in "bits". + @param state Encoder state + @param in Frame that will be encoded with a +-2^15 range + @param bits Bit-stream where the data will be written + @return 0 if frame needs not be transmitted (DTX only), 1 otherwise + */ +int speex_encode_int(void *state, spx_int16_t *in, SpeexBits *bits); + /** Used like the ioctl function to control the encoder parameters * * @param state Encoder state * @param request ioctl-type request (one of the SPEEX_* macros) * @param ptr Data exchanged to-from function - * @return 0 if frame needs not be transmitted (DTX only), 1 otherwise + * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter */ int speex_encoder_ctl(void *state, int request, void *ptr); -/** Returns a handle to a newly created decoder state structure. For now, +/** Returns a handle to a newly created decoder state structure. For now, * the mode argument can be &nb_mode or &wb_mode . In the future, more modes * may be added. Note that for now if you have more than one channels to * decode, you need one state per channel. * * @param mode Speex mode (one of speex_nb_mode or speex_wb_mode) - * @return A newly created decoder state - */ -void *speex_decoder_init(SpeexMode *mode); + * @return A newly created decoder state or NULL if state allocation fails + */ +void *speex_decoder_init(const SpeexMode *mode); /** Frees all resources associated to an existing decoder state. * @@ -288,16 +357,26 @@ void speex_decoder_destroy(void *state); * @param state Decoder state * @param bits Bit-stream from which to decode the frame (NULL if the packet was lost) * @param out Where to write the decoded frame - * @return return status (0 for no error, -1 for end of stream, -2 other) + * @return return status (0 for no error, -1 for end of stream, -2 corrupt stream) */ int speex_decode(void *state, SpeexBits *bits, float *out); +/** Uses an existing decoder state to decode one frame of speech from + * bit-stream bits. The output speech is saved written to out. + * + * @param state Decoder state + * @param bits Bit-stream from which to decode the frame (NULL if the packet was lost) + * @param out Where to write the decoded frame + * @return return status (0 for no error, -1 for end of stream, -2 corrupt stream) + */ +int speex_decode_int(void *state, SpeexBits *bits, spx_int16_t *out); + /** Used like the ioctl function to control the encoder parameters * * @param state Decoder state * @param request ioctl-type request (one of the SPEEX_* macros) * @param ptr Data exchanged to-from function - * @return 0 for no error, 1 if a terminator is reached, 2 for another error + * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter */ int speex_decoder_ctl(void *state, int request, void *ptr); @@ -307,25 +386,40 @@ int speex_decoder_ctl(void *state, int request, void *ptr); * @param mode Speex mode * @param request ioctl-type request (one of the SPEEX_* macros) * @param ptr Data exchanged to-from function + * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter */ -int speex_mode_query(SpeexMode *mode, int request, void *ptr); +int speex_mode_query(const SpeexMode *mode, int request, void *ptr); +/** Functions for controlling the behavior of libspeex + * @param request ioctl-type request (one of the SPEEX_LIB_* macros) + * @param ptr Data exchanged to-from function + * @return 0 if no error, -1 if request in unknown, -2 for invalid parameter + */ +int speex_lib_ctl(int request, void *ptr); /** Default narrowband mode */ -extern SpeexMode speex_nb_mode; +extern const SpeexMode speex_nb_mode; /** Default wideband mode */ -extern SpeexMode speex_wb_mode; +extern const SpeexMode speex_wb_mode; /** Default "ultra-wideband" mode */ -extern SpeexMode speex_uwb_mode; +extern const SpeexMode speex_uwb_mode; /** List of all modes available */ -extern SpeexMode *speex_mode_list[SPEEX_NB_MODES]; +extern const SpeexMode * const speex_mode_list[SPEEX_NB_MODES]; + +/** Obtain one of the modes available */ +const SpeexMode * speex_lib_get_mode (int mode); + +#ifndef WIN32 +/* We actually override the function in the narrowband case so that we can avoid linking in the wideband stuff */ +#define speex_lib_get_mode(mode) ((mode)==SPEEX_MODEID_NB ? &speex_nb_mode : speex_lib_get_mode (mode)) +#endif #ifdef __cplusplus } #endif - +/** @}*/ #endif diff --git a/engine/voice_codecs/speex/source/libspeex/speex_bits.h b/engine/voice_codecs/speex/speex/speex_bits.h similarity index 78% rename from engine/voice_codecs/speex/source/libspeex/speex_bits.h rename to engine/voice_codecs/speex/speex/speex_bits.h index b41fdad7..f98b8268 100644 --- a/engine/voice_codecs/speex/source/libspeex/speex_bits.h +++ b/engine/voice_codecs/speex/speex/speex_bits.h @@ -7,18 +7,18 @@ 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. - + - Neither the name of the Xiph.org Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + 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 @@ -35,21 +35,23 @@ #ifndef BITS_H #define BITS_H +/** @defgroup SpeexBits SpeexBits: Bit-stream manipulations + * This is the structure that holds the bit-stream when encoding or decoding + * with Speex. It allows some manipulations as well. + * @{ + */ #ifdef __cplusplus extern "C" { #endif -/** Maximum size of the bit-stream (for fixed-size allocation) */ -#define MAX_BYTES_PER_FRAME 2000 - /** Bit-packing data structure representing (part of) a bit-stream. */ typedef struct SpeexBits { - char *bytes; /**< "raw" data */ + char *chars; /**< "raw" data */ int nbBits; /**< Total number of bits stored in the stream*/ - int bytePtr; /**< Position of the byte "cursor" */ - int bitPtr; /**< Position of the bit "cursor" within the current byte */ - int owner; /**< Does the struct "own" the "raw" buffer (member "bytes") */ + int charPtr; /**< Position of the byte "cursor" */ + int bitPtr; /**< Position of the bit "cursor" within the current char */ + int owner; /**< Does the struct "own" the "raw" buffer (member "chars") */ int overflow;/**< Set to one if we try to read past the valid data */ int buf_size;/**< Allocated size for buffer */ int reserved1; /**< Reserved for future use */ @@ -62,6 +64,9 @@ void speex_bits_init(SpeexBits *bits); /** Initializes SpeexBits struct using a pre-allocated buffer*/ void speex_bits_init_buffer(SpeexBits *bits, void *buff, int buf_size); +/** Sets the bits in a SpeexBits struct to use data from an existing buffer (for decoding without copying data) */ +void speex_bits_set_bit_buffer(SpeexBits *bits, void *buff, int buf_size); + /** Frees all resources associated to a SpeexBits struct. Right now this does nothing since no resources are allocated, but this could change in the future.*/ void speex_bits_destroy(SpeexBits *bits); @@ -72,16 +77,23 @@ void speex_bits_reset(SpeexBits *bits); void speex_bits_rewind(SpeexBits *bits); /** Initializes the bit-stream from the data in an area of memory */ -void speex_bits_read_from(SpeexBits *bits, char *bytes, int len); +void speex_bits_read_from(SpeexBits *bits, const char *bytes, int len); /** Append bytes to the bit-stream + * * @param bits Bit-stream to operate on * @param bytes pointer to the bytes what will be appended * @param len Number of bytes of append */ -void speex_bits_read_whole_bytes(SpeexBits *bits, char *bytes, int len); +void speex_bits_read_whole_bytes(SpeexBits *bits, const char *bytes, int len); -/** Write the content of a bit-stream to an area of memory */ +/** Write the content of a bit-stream to an area of memory + * + * @param bits Bit-stream to operate on + * @param bytes Memory location where to write the bits + * @param max_len Maximum number of bytes to write (i.e. size of the "bytes" buffer) + * @return Number of bytes written to the "bytes" buffer +*/ int speex_bits_write(SpeexBits *bits, char *bytes, int max_len); /** Like speex_bits_write, but writes only the complete bytes in the stream. Also removes the written bytes from the stream */ @@ -117,17 +129,23 @@ unsigned int speex_bits_unpack_unsigned(SpeexBits *bits, int nbBits); */ int speex_bits_nbytes(SpeexBits *bits); -/** Same as speex_bits_unpack_unsigned, but without modifying the cursor position */ +/** Same as speex_bits_unpack_unsigned, but without modifying the cursor position + * + * @param bits Bit-stream to operate on + * @param nbBits Number of bits to look for + * @return Value of the bits peeked, interpreted as unsigned + */ unsigned int speex_bits_peek_unsigned(SpeexBits *bits, int nbBits); /** Get the value of the next bit in the stream, without modifying the - * "cursor" position - * + * "cursor" position + * * @param bits Bit-stream to operate on + * @return Value of the bit peeked (one bit only) */ int speex_bits_peek(SpeexBits *bits); -/** Advances the position of the "bit cursor" in the stream +/** Advances the position of the "bit cursor" in the stream * * @param bits Bit-stream to operate on * @param n Number of bits to advance @@ -137,11 +155,12 @@ void speex_bits_advance(SpeexBits *bits, int n); /** Returns the number of bits remaining to be read in a stream * * @param bits Bit-stream to operate on + * @return Number of bits that can still be read from the stream */ int speex_bits_remaining(SpeexBits *bits); -/** Insert a terminator so that the data can be sent as a packet while auto-detecting - * the number of frames in each packet +/** Insert a terminator so that the data can be sent as a packet while auto-detecting + * the number of frames in each packet * * @param bits Bit-stream to operate on */ @@ -151,4 +170,5 @@ void speex_bits_insert_terminator(SpeexBits *bits); } #endif +/* @} */ #endif diff --git a/engine/voice_codecs/speex/source/libspeex/speex_callbacks.h b/engine/voice_codecs/speex/speex/speex_callbacks.h similarity index 91% rename from engine/voice_codecs/speex/source/libspeex/speex_callbacks.h rename to engine/voice_codecs/speex/speex/speex_callbacks.h index f6334f22..3928c34f 100644 --- a/engine/voice_codecs/speex/source/libspeex/speex_callbacks.h +++ b/engine/voice_codecs/speex/speex/speex_callbacks.h @@ -7,18 +7,18 @@ 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. - + - Neither the name of the Xiph.org Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + 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 @@ -35,6 +35,9 @@ #ifndef SPEEX_CALLBACKS_H #define SPEEX_CALLBACKS_H +/** @defgroup SpeexCallbacks Various definitions for Speex callbacks supported by the decoder. + * @{ + */ #include "speex.h" @@ -110,13 +113,16 @@ int speex_default_user_handler(SpeexBits *bits, void *state, void *data); - +/** Standard handler for low mode request (change low mode, no questions asked) */ int speex_std_low_mode_request_handler(SpeexBits *bits, void *state, void *data); +/** Standard handler for VBR request (Set VBR, no questions asked) */ int speex_std_vbr_request_handler(SpeexBits *bits, void *state, void *data); +/** Standard handler for enhancer request (Turn enhancer on/off, no questions asked) */ int speex_std_enh_request_handler(SpeexBits *bits, void *state, void *data); +/** Standard handler for VBR quality request (Set VBR quality, no questions asked) */ int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *data); @@ -124,5 +130,5 @@ int speex_std_vbr_quality_request_handler(SpeexBits *bits, void *state, void *da } #endif - +/** @} */ #endif diff --git a/engine/voice_codecs/speex/speex/speex_config_types.h b/engine/voice_codecs/speex/speex/speex_config_types.h new file mode 100644 index 00000000..ca1f5a3c --- /dev/null +++ b/engine/voice_codecs/speex/speex/speex_config_types.h @@ -0,0 +1,12 @@ +#ifndef __SPEEX_TYPES_H__ +#define __SPEEX_TYPES_H__ + +#include + +typedef int16_t spx_int16_t; +typedef uint16_t spx_uint16_t; +typedef int32_t spx_int32_t; +typedef uint32_t spx_uint32_t; + +#endif + diff --git a/engine/voice_codecs/speex/speex/speex_echo.h b/engine/voice_codecs/speex/speex/speex_echo.h new file mode 100644 index 00000000..4c1aa5a5 --- /dev/null +++ b/engine/voice_codecs/speex/speex/speex_echo.h @@ -0,0 +1,170 @@ +/* Copyright (C) Jean-Marc Valin */ +/** + @file speex_echo.h + @brief Echo cancellation +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 SPEEX_ECHO_H +#define SPEEX_ECHO_H +/** @defgroup SpeexEchoState SpeexEchoState: Acoustic echo canceller + * This is the acoustic echo canceller module. + * @{ + */ +#include "speexdsp_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Obtain frame size used by the AEC */ +#define SPEEX_ECHO_GET_FRAME_SIZE 3 + +/** Set sampling rate */ +#define SPEEX_ECHO_SET_SAMPLING_RATE 24 +/** Get sampling rate */ +#define SPEEX_ECHO_GET_SAMPLING_RATE 25 + +/* Can't set window sizes */ +/** Get size of impulse response (int32) */ +#define SPEEX_ECHO_GET_IMPULSE_RESPONSE_SIZE 27 + +/* Can't set window content */ +/** Get impulse response (int32[]) */ +#define SPEEX_ECHO_GET_IMPULSE_RESPONSE 29 + +/** Internal echo canceller state. Should never be accessed directly. */ +struct SpeexEchoState_; + +/** @class SpeexEchoState + * This holds the state of the echo canceller. You need one per channel. +*/ + +/** Internal echo canceller state. Should never be accessed directly. */ +typedef struct SpeexEchoState_ SpeexEchoState; + +/** Creates a new echo canceller state + * @param frame_size Number of samples to process at one time (should correspond to 10-20 ms) + * @param filter_length Number of samples of echo to cancel (should generally correspond to 100-500 ms) + * @return Newly-created echo canceller state + */ +SpeexEchoState *speex_echo_state_init(int frame_size, int filter_length); + +/** Creates a new multi-channel echo canceller state + * @param frame_size Number of samples to process at one time (should correspond to 10-20 ms) + * @param filter_length Number of samples of echo to cancel (should generally correspond to 100-500 ms) + * @param nb_mic Number of microphone channels + * @param nb_speakers Number of speaker channels + * @return Newly-created echo canceller state + */ +SpeexEchoState *speex_echo_state_init_mc(int frame_size, int filter_length, int nb_mic, int nb_speakers); + +/** Destroys an echo canceller state + * @param st Echo canceller state +*/ +void speex_echo_state_destroy(SpeexEchoState *st); + +/** Performs echo cancellation a frame, based on the audio sent to the speaker (no delay is added + * to playback in this form) + * + * @param st Echo canceller state + * @param rec Signal from the microphone (near end + far end echo) + * @param play Signal played to the speaker (received from far end) + * @param out Returns near-end signal with echo removed + */ +void speex_echo_cancellation(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out); + +/** Performs echo cancellation a frame (deprecated) */ +void speex_echo_cancel(SpeexEchoState *st, const spx_int16_t *rec, const spx_int16_t *play, spx_int16_t *out, spx_int32_t *Yout); + +/** Perform echo cancellation using internal playback buffer, which is delayed by two frames + * to account for the delay introduced by most soundcards (but it could be off!) + * @param st Echo canceller state + * @param rec Signal from the microphone (near end + far end echo) + * @param out Returns near-end signal with echo removed +*/ +void speex_echo_capture(SpeexEchoState *st, const spx_int16_t *rec, spx_int16_t *out); + +/** Let the echo canceller know that a frame was just queued to the soundcard + * @param st Echo canceller state + * @param play Signal played to the speaker (received from far end) +*/ +void speex_echo_playback(SpeexEchoState *st, const spx_int16_t *play); + +/** Reset the echo canceller to its original state + * @param st Echo canceller state + */ +void speex_echo_state_reset(SpeexEchoState *st); + +/** Used like the ioctl function to control the echo canceller parameters + * + * @param st Echo canceller state + * @param request ioctl-type request (one of the SPEEX_ECHO_* macros) + * @param ptr Data exchanged to-from function + * @return 0 if no error, -1 if request in unknown + */ +int speex_echo_ctl(SpeexEchoState *st, int request, void *ptr); + + + +struct SpeexDecorrState_; + +typedef struct SpeexDecorrState_ SpeexDecorrState; + + +/** Create a state for the channel decorrelation algorithm + This is useful for multi-channel echo cancellation only + * @param rate Sampling rate + * @param channels Number of channels (it's a bit pointless if you don't have at least 2) + * @param frame_size Size of the frame to process at ones (counting samples *per* channel) +*/ +SpeexDecorrState *speex_decorrelate_new(int rate, int channels, int frame_size); + +/** Remove correlation between the channels by modifying the phase and possibly + adding noise in a way that is not (or little) perceptible. + * @param st Decorrelator state + * @param in Input audio in interleaved format + * @param out Result of the decorrelation (out *may* alias in) + * @param strength How much alteration of the audio to apply from 0 to 100. +*/ +void speex_decorrelate(SpeexDecorrState *st, const spx_int16_t *in, spx_int16_t *out, int strength); + +/** Destroy a Decorrelation state + * @param st State to destroy +*/ +void speex_decorrelate_destroy(SpeexDecorrState *st); + + +#ifdef __cplusplus +} +#endif + + +/** @}*/ +#endif diff --git a/engine/voice_codecs/speex/source/libspeex/speex_header.h b/engine/voice_codecs/speex/speex/speex_header.h similarity index 59% rename from engine/voice_codecs/speex/source/libspeex/speex_header.h rename to engine/voice_codecs/speex/speex/speex_header.h index 8ded9114..ffe8c471 100644 --- a/engine/voice_codecs/speex/source/libspeex/speex_header.h +++ b/engine/voice_codecs/speex/speex/speex_header.h @@ -7,18 +7,18 @@ 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. - + - Neither the name of the Xiph.org Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + 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 @@ -36,6 +36,12 @@ #ifndef SPEEX_HEADER_H #define SPEEX_HEADER_H +/** @defgroup SpeexHeader SpeexHeader: Makes it easy to write/parse an Ogg/Speex header + * This is the Speex header for the Ogg encapsulation. You don't need that if you just use RTP. + * @{ + */ + +#include "speex_types.h" #ifdef __cplusplus extern "C" { @@ -43,30 +49,33 @@ extern "C" { struct SpeexMode; +/** Length of the Speex header identifier */ +#define SPEEX_HEADER_STRING_LENGTH 8 + /** Maximum number of characters for encoding the Speex version number in the header */ #define SPEEX_HEADER_VERSION_LENGTH 20 /** Speex header info for file-based formats */ typedef struct SpeexHeader { - char speex_string[8]; /**< Identifies a Speex bit-stream, always set to "Speex " */ + char speex_string[SPEEX_HEADER_STRING_LENGTH]; /**< Identifies a Speex bit-stream, always set to "Speex " */ char speex_version[SPEEX_HEADER_VERSION_LENGTH]; /**< Speex version */ - int speex_version_id; /**< Version for Speex (for checking compatibility) */ - int header_size; /**< Total size of the header ( sizeof(SpeexHeader) ) */ - int rate; /**< Sampling rate used */ - int mode; /**< Mode used (0 for narrowband, 1 for wideband) */ - int mode_bitstream_version; /**< Version ID of the bit-stream */ - int nb_channels; /**< Number of channels encoded */ - int bitrate; /**< Bit-rate used */ - int frame_size; /**< Size of frames */ - int vbr; /**< 1 for a VBR encoding, 0 otherwise */ - int frames_per_packet; /**< Number of frames stored per Ogg packet */ - int extra_headers; /**< Number of additional headers after the comments */ - int reserved1; /**< Reserved for future use, must be zero */ - int reserved2; /**< Reserved for future use, must be zero */ + spx_int32_t speex_version_id; /**< Version for Speex (for checking compatibility) */ + spx_int32_t header_size; /**< Total size of the header ( sizeof(SpeexHeader) ) */ + spx_int32_t rate; /**< Sampling rate used */ + spx_int32_t mode; /**< Mode used (0 for narrowband, 1 for wideband) */ + spx_int32_t mode_bitstream_version; /**< Version ID of the bit-stream */ + spx_int32_t nb_channels; /**< Number of channels encoded */ + spx_int32_t bitrate; /**< Bit-rate used */ + spx_int32_t frame_size; /**< Size of frames */ + spx_int32_t vbr; /**< 1 for a VBR encoding, 0 otherwise */ + spx_int32_t frames_per_packet; /**< Number of frames stored per Ogg packet */ + spx_int32_t extra_headers; /**< Number of additional headers after the comments */ + spx_int32_t reserved1; /**< Reserved for future use, must be zero */ + spx_int32_t reserved2; /**< Reserved for future use, must be zero */ } SpeexHeader; /** Initializes a SpeexHeader using basic information */ -void speex_init_header(SpeexHeader *header, int rate, int nb_channels, struct SpeexMode *m); +void speex_init_header(SpeexHeader *header, int rate, int nb_channels, const struct SpeexMode *m); /** Creates the header packet from the header itself (mostly involves endianness conversion) */ char *speex_header_to_packet(SpeexHeader *header, int *size); @@ -74,9 +83,12 @@ char *speex_header_to_packet(SpeexHeader *header, int *size); /** Creates a SpeexHeader from a packet */ SpeexHeader *speex_packet_to_header(char *packet, int size); +/** Frees the memory allocated by either speex_header_to_packet() or speex_packet_to_header() */ +void speex_header_free(void *ptr); + #ifdef __cplusplus } #endif - +/** @} */ #endif diff --git a/engine/voice_codecs/speex/speex/speex_jitter.h b/engine/voice_codecs/speex/speex/speex_jitter.h new file mode 100644 index 00000000..8fc8d7ec --- /dev/null +++ b/engine/voice_codecs/speex/speex/speex_jitter.h @@ -0,0 +1,197 @@ +/* Copyright (C) 2002 Jean-Marc Valin */ +/** + @file speex_jitter.h + @brief Adaptive jitter buffer for Speex +*/ +/* + 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. + + - Neither the name of the Xiph.org Foundation nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + 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 FOUNDATION 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 SPEEX_JITTER_H +#define SPEEX_JITTER_H +/** @defgroup JitterBuffer JitterBuffer: Adaptive jitter buffer + * This is the jitter buffer that reorders UDP/RTP packets and adjusts the buffer size + * to maintain good quality and low latency. + * @{ + */ + +#include "speexdsp_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Generic adaptive jitter buffer state */ +struct JitterBuffer_; + +/** Generic adaptive jitter buffer state */ +typedef struct JitterBuffer_ JitterBuffer; + +/** Definition of an incoming packet */ +typedef struct _JitterBufferPacket JitterBufferPacket; + +/** Definition of an incoming packet */ +struct _JitterBufferPacket { + char *data; /**< Data bytes contained in the packet */ + spx_uint32_t len; /**< Length of the packet in bytes */ + spx_uint32_t timestamp; /**< Timestamp for the packet */ + spx_uint32_t span; /**< Time covered by the packet (same units as timestamp) */ + spx_uint16_t sequence; /**< RTP Sequence number if available (0 otherwise) */ + spx_uint32_t user_data; /**< Put whatever data you like here (it's ignored by the jitter buffer) */ +}; + +/** Packet has been retrieved */ +#define JITTER_BUFFER_OK 0 +/** Packet is lost or is late */ +#define JITTER_BUFFER_MISSING 1 +/** A "fake" packet is meant to be inserted here to increase buffering */ +#define JITTER_BUFFER_INSERTION 2 +/** There was an error in the jitter buffer */ +#define JITTER_BUFFER_INTERNAL_ERROR -1 +/** Invalid argument */ +#define JITTER_BUFFER_BAD_ARGUMENT -2 + + +/** Set minimum amount of extra buffering required (margin) */ +#define JITTER_BUFFER_SET_MARGIN 0 +/** Get minimum amount of extra buffering required (margin) */ +#define JITTER_BUFFER_GET_MARGIN 1 +/* JITTER_BUFFER_SET_AVAILABLE_COUNT wouldn't make sense */ + +/** Get the amount of available packets currently buffered */ +#define JITTER_BUFFER_GET_AVAILABLE_COUNT 3 +/** Included because of an early misspelling (will remove in next release) */ +#define JITTER_BUFFER_GET_AVALIABLE_COUNT 3 + +/** Assign a function to destroy unused packet. When setting that, the jitter + buffer no longer copies packet data. */ +#define JITTER_BUFFER_SET_DESTROY_CALLBACK 4 +/** */ +#define JITTER_BUFFER_GET_DESTROY_CALLBACK 5 + +/** Tell the jitter buffer to only adjust the delay in multiples of the step parameter provided */ +#define JITTER_BUFFER_SET_DELAY_STEP 6 +/** */ +#define JITTER_BUFFER_GET_DELAY_STEP 7 + +/** Tell the jitter buffer to only do concealment in multiples of the size parameter provided */ +#define JITTER_BUFFER_SET_CONCEALMENT_SIZE 8 +#define JITTER_BUFFER_GET_CONCEALMENT_SIZE 9 + +/** Absolute max amount of loss that can be tolerated regardless of the delay. Typical loss + should be half of that or less. */ +#define JITTER_BUFFER_SET_MAX_LATE_RATE 10 +#define JITTER_BUFFER_GET_MAX_LATE_RATE 11 + +/** Equivalent cost of one percent late packet in timestamp units */ +#define JITTER_BUFFER_SET_LATE_COST 12 +#define JITTER_BUFFER_GET_LATE_COST 13 + + +/** Initialises jitter buffer + * + * @param step_size Starting value for the size of concleanment packets and delay + adjustment steps. Can be changed at any time using JITTER_BUFFER_SET_DELAY_STEP + and JITTER_BUFFER_GET_CONCEALMENT_SIZE. + * @return Newly created jitter buffer state + */ +JitterBuffer *jitter_buffer_init(int step_size); + +/** Restores jitter buffer to its original state + * + * @param jitter Jitter buffer state + */ +void jitter_buffer_reset(JitterBuffer *jitter); + +/** Destroys jitter buffer + * + * @param jitter Jitter buffer state + */ +void jitter_buffer_destroy(JitterBuffer *jitter); + +/** Put one packet into the jitter buffer + * + * @param jitter Jitter buffer state + * @param packet Incoming packet +*/ +void jitter_buffer_put(JitterBuffer *jitter, const JitterBufferPacket *packet); + +/** Get one packet from the jitter buffer + * + * @param jitter Jitter buffer state + * @param packet Returned packet + * @param desired_span Number of samples (or units) we wish to get from the buffer (no guarantee) + * @param current_timestamp Timestamp for the returned packet +*/ +int jitter_buffer_get(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t desired_span, spx_int32_t *start_offset); + +/** Used right after jitter_buffer_get() to obtain another packet that would have the same timestamp. + * This is mainly useful for media where a single "frame" can be split into several packets. + * + * @param jitter Jitter buffer state + * @param packet Returned packet + */ +int jitter_buffer_get_another(JitterBuffer *jitter, JitterBufferPacket *packet); + +/** Get pointer timestamp of jitter buffer + * + * @param jitter Jitter buffer state +*/ +int jitter_buffer_get_pointer_timestamp(JitterBuffer *jitter); + +/** Advance by one tick + * + * @param jitter Jitter buffer state +*/ +void jitter_buffer_tick(JitterBuffer *jitter); + +/** Telling the jitter buffer about the remaining data in the application buffer + * @param jitter Jitter buffer state + * @param rem Amount of data buffered by the application (timestamp units) + */ +void jitter_buffer_remaining_span(JitterBuffer *jitter, spx_uint32_t rem); + +/** Used like the ioctl function to control the jitter buffer parameters + * + * @param jitter Jitter buffer state + * @param request ioctl-type request (one of the JITTER_BUFFER_* macros) + * @param ptr Data exchanged to-from function + * @return 0 if no error, -1 if request in unknown +*/ +int jitter_buffer_ctl(JitterBuffer *jitter, int request, void *ptr); + +int jitter_buffer_update_delay(JitterBuffer *jitter, JitterBufferPacket *packet, spx_int32_t *start_offset); + +/* @} */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/engine/voice_codecs/speex/speex/speex_preprocess.h b/engine/voice_codecs/speex/speex/speex_preprocess.h new file mode 100644 index 00000000..a2e1210d --- /dev/null +++ b/engine/voice_codecs/speex/speex/speex_preprocess.h @@ -0,0 +1,219 @@ +/* Copyright (C) 2003 Epic Games + Written by Jean-Marc Valin */ +/** + * @file speex_preprocess.h + * @brief Speex preprocessor. The preprocess can do noise suppression, + * residual echo suppression (after using the echo canceller), automatic + * gain control (AGC) and voice activity detection (VAD). +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 SPEEX_PREPROCESS_H +#define SPEEX_PREPROCESS_H +/** @defgroup SpeexPreprocessState SpeexPreprocessState: The Speex preprocessor + * This is the Speex preprocessor. The preprocess can do noise suppression, + * residual echo suppression (after using the echo canceller), automatic + * gain control (AGC) and voice activity detection (VAD). + * @{ + */ + +#include "speexdsp_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** State of the preprocessor (one per channel). Should never be accessed directly. */ +struct SpeexPreprocessState_; + +/** State of the preprocessor (one per channel). Should never be accessed directly. */ +typedef struct SpeexPreprocessState_ SpeexPreprocessState; + + +/** Creates a new preprocessing state. You MUST create one state per channel processed. + * @param frame_size Number of samples to process at one time (should correspond to 10-20 ms). Must be + * the same value as that used for the echo canceller for residual echo cancellation to work. + * @param sampling_rate Sampling rate used for the input. + * @return Newly created preprocessor state +*/ +SpeexPreprocessState *speex_preprocess_state_init(int frame_size, int sampling_rate); + +/** Destroys a preprocessor state + * @param st Preprocessor state to destroy +*/ +void speex_preprocess_state_destroy(SpeexPreprocessState *st); + +/** Preprocess a frame + * @param st Preprocessor state + * @param x Audio sample vector (in and out). Must be same size as specified in speex_preprocess_state_init(). + * @return Bool value for voice activity (1 for speech, 0 for noise/silence), ONLY if VAD turned on. +*/ +int speex_preprocess_run(SpeexPreprocessState *st, spx_int16_t *x); + +/** Preprocess a frame (deprecated, use speex_preprocess_run() instead)*/ +int speex_preprocess(SpeexPreprocessState *st, spx_int16_t *x, spx_int32_t *echo); + +/** Update preprocessor state, but do not compute the output + * @param st Preprocessor state + * @param x Audio sample vector (in only). Must be same size as specified in speex_preprocess_state_init(). +*/ +void speex_preprocess_estimate_update(SpeexPreprocessState *st, spx_int16_t *x); + +/** Used like the ioctl function to control the preprocessor parameters + * @param st Preprocessor state + * @param request ioctl-type request (one of the SPEEX_PREPROCESS_* macros) + * @param ptr Data exchanged to-from function + * @return 0 if no error, -1 if request in unknown +*/ +int speex_preprocess_ctl(SpeexPreprocessState *st, int request, void *ptr); + + + +/** Set preprocessor denoiser state */ +#define SPEEX_PREPROCESS_SET_DENOISE 0 +/** Get preprocessor denoiser state */ +#define SPEEX_PREPROCESS_GET_DENOISE 1 + +/** Set preprocessor Automatic Gain Control state */ +#define SPEEX_PREPROCESS_SET_AGC 2 +/** Get preprocessor Automatic Gain Control state */ +#define SPEEX_PREPROCESS_GET_AGC 3 + +/** Set preprocessor Voice Activity Detection state */ +#define SPEEX_PREPROCESS_SET_VAD 4 +/** Get preprocessor Voice Activity Detection state */ +#define SPEEX_PREPROCESS_GET_VAD 5 + +/** Set preprocessor Automatic Gain Control level (float) */ +#define SPEEX_PREPROCESS_SET_AGC_LEVEL 6 +/** Get preprocessor Automatic Gain Control level (float) */ +#define SPEEX_PREPROCESS_GET_AGC_LEVEL 7 + +/** Set preprocessor dereverb state */ +#define SPEEX_PREPROCESS_SET_DEREVERB 8 +/** Get preprocessor dereverb state */ +#define SPEEX_PREPROCESS_GET_DEREVERB 9 + +/** Set preprocessor dereverb level */ +#define SPEEX_PREPROCESS_SET_DEREVERB_LEVEL 10 +/** Get preprocessor dereverb level */ +#define SPEEX_PREPROCESS_GET_DEREVERB_LEVEL 11 + +/** Set preprocessor dereverb decay */ +#define SPEEX_PREPROCESS_SET_DEREVERB_DECAY 12 +/** Get preprocessor dereverb decay */ +#define SPEEX_PREPROCESS_GET_DEREVERB_DECAY 13 + +/** Set probability required for the VAD to go from silence to voice */ +#define SPEEX_PREPROCESS_SET_PROB_START 14 +/** Get probability required for the VAD to go from silence to voice */ +#define SPEEX_PREPROCESS_GET_PROB_START 15 + +/** Set probability required for the VAD to stay in the voice state (integer percent) */ +#define SPEEX_PREPROCESS_SET_PROB_CONTINUE 16 +/** Get probability required for the VAD to stay in the voice state (integer percent) */ +#define SPEEX_PREPROCESS_GET_PROB_CONTINUE 17 + +/** Set maximum attenuation of the noise in dB (negative number) */ +#define SPEEX_PREPROCESS_SET_NOISE_SUPPRESS 18 +/** Get maximum attenuation of the noise in dB (negative number) */ +#define SPEEX_PREPROCESS_GET_NOISE_SUPPRESS 19 + +/** Set maximum attenuation of the residual echo in dB (negative number) */ +#define SPEEX_PREPROCESS_SET_ECHO_SUPPRESS 20 +/** Get maximum attenuation of the residual echo in dB (negative number) */ +#define SPEEX_PREPROCESS_GET_ECHO_SUPPRESS 21 + +/** Set maximum attenuation of the residual echo in dB when near end is active (negative number) */ +#define SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE 22 +/** Get maximum attenuation of the residual echo in dB when near end is active (negative number) */ +#define SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE 23 + +/** Set the corresponding echo canceller state so that residual echo suppression can be performed (NULL for no residual echo suppression) */ +#define SPEEX_PREPROCESS_SET_ECHO_STATE 24 +/** Get the corresponding echo canceller state */ +#define SPEEX_PREPROCESS_GET_ECHO_STATE 25 + +/** Set maximal gain increase in dB/second (int32) */ +#define SPEEX_PREPROCESS_SET_AGC_INCREMENT 26 + +/** Get maximal gain increase in dB/second (int32) */ +#define SPEEX_PREPROCESS_GET_AGC_INCREMENT 27 + +/** Set maximal gain decrease in dB/second (int32) */ +#define SPEEX_PREPROCESS_SET_AGC_DECREMENT 28 + +/** Get maximal gain decrease in dB/second (int32) */ +#define SPEEX_PREPROCESS_GET_AGC_DECREMENT 29 + +/** Set maximal gain in dB (int32) */ +#define SPEEX_PREPROCESS_SET_AGC_MAX_GAIN 30 + +/** Get maximal gain in dB (int32) */ +#define SPEEX_PREPROCESS_GET_AGC_MAX_GAIN 31 + +/* Can't set loudness */ +/** Get loudness */ +#define SPEEX_PREPROCESS_GET_AGC_LOUDNESS 33 + +/* Can't set gain */ +/** Get current gain (int32 percent) */ +#define SPEEX_PREPROCESS_GET_AGC_GAIN 35 + +/* Can't set spectrum size */ +/** Get spectrum size for power spectrum (int32) */ +#define SPEEX_PREPROCESS_GET_PSD_SIZE 37 + +/* Can't set power spectrum */ +/** Get power spectrum (int32[] of squared values) */ +#define SPEEX_PREPROCESS_GET_PSD 39 + +/* Can't set noise size */ +/** Get spectrum size for noise estimate (int32) */ +#define SPEEX_PREPROCESS_GET_NOISE_PSD_SIZE 41 + +/* Can't set noise estimate */ +/** Get noise estimate (int32[] of squared values) */ +#define SPEEX_PREPROCESS_GET_NOISE_PSD 43 + +/* Can't set speech probability */ +/** Get speech probability in last frame (int32). */ +#define SPEEX_PREPROCESS_GET_PROB 45 + +/** Set preprocessor Automatic Gain Control level (int32) */ +#define SPEEX_PREPROCESS_SET_AGC_TARGET 46 +/** Get preprocessor Automatic Gain Control level (int32) */ +#define SPEEX_PREPROCESS_GET_AGC_TARGET 47 + +#ifdef __cplusplus +} +#endif + +/** @}*/ +#endif diff --git a/engine/voice_codecs/speex/speex/speex_resampler.h b/engine/voice_codecs/speex/speex/speex_resampler.h new file mode 100644 index 00000000..901de37b --- /dev/null +++ b/engine/voice_codecs/speex/speex/speex_resampler.h @@ -0,0 +1,343 @@ +/* Copyright (C) 2007 Jean-Marc Valin + + File: speex_resampler.h + Resampling code + + The design goals of this code are: + - Very fast algorithm + - Low memory requirement + - Good *perceptual* quality (and not best SNR) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. 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. + + 3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 SPEEX_RESAMPLER_H +#define SPEEX_RESAMPLER_H + +#ifdef OUTSIDE_SPEEX + +/********* WARNING: MENTAL SANITY ENDS HERE *************/ + +/* If the resampler is defined outside of Speex, we change the symbol names so that + there won't be any clash if linking with Speex later on. */ + +/* #define RANDOM_PREFIX your software name here */ +#ifndef RANDOM_PREFIX +#error "Please define RANDOM_PREFIX (above) to something specific to your project to prevent symbol name clashes" +#endif + +#define CAT_PREFIX2(a,b) a ## b +#define CAT_PREFIX(a,b) CAT_PREFIX2(a, b) + +#define speex_resampler_init CAT_PREFIX(RANDOM_PREFIX,_resampler_init) +#define speex_resampler_init_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_init_frac) +#define speex_resampler_destroy CAT_PREFIX(RANDOM_PREFIX,_resampler_destroy) +#define speex_resampler_process_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_float) +#define speex_resampler_process_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_int) +#define speex_resampler_process_interleaved_float CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_float) +#define speex_resampler_process_interleaved_int CAT_PREFIX(RANDOM_PREFIX,_resampler_process_interleaved_int) +#define speex_resampler_set_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate) +#define speex_resampler_get_rate CAT_PREFIX(RANDOM_PREFIX,_resampler_get_rate) +#define speex_resampler_set_rate_frac CAT_PREFIX(RANDOM_PREFIX,_resampler_set_rate_frac) +#define speex_resampler_get_ratio CAT_PREFIX(RANDOM_PREFIX,_resampler_get_ratio) +#define speex_resampler_set_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_set_quality) +#define speex_resampler_get_quality CAT_PREFIX(RANDOM_PREFIX,_resampler_get_quality) +#define speex_resampler_set_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_input_stride) +#define speex_resampler_get_input_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_stride) +#define speex_resampler_set_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_set_output_stride) +#define speex_resampler_get_output_stride CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_stride) +#define speex_resampler_get_input_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_input_latency) +#define speex_resampler_get_output_latency CAT_PREFIX(RANDOM_PREFIX,_resampler_get_output_latency) +#define speex_resampler_skip_zeros CAT_PREFIX(RANDOM_PREFIX,_resampler_skip_zeros) +#define speex_resampler_reset_mem CAT_PREFIX(RANDOM_PREFIX,_resampler_reset_mem) +#define speex_resampler_strerror CAT_PREFIX(RANDOM_PREFIX,_resampler_strerror) + +#define spx_int16_t short +#define spx_int32_t int +#define spx_uint16_t unsigned short +#define spx_uint32_t unsigned int + +#define speex_assert(cond) + +#else /* OUTSIDE_SPEEX */ + +#include "speexdsp_types.h" + +#endif /* OUTSIDE_SPEEX */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define SPEEX_RESAMPLER_QUALITY_MAX 10 +#define SPEEX_RESAMPLER_QUALITY_MIN 0 +#define SPEEX_RESAMPLER_QUALITY_DEFAULT 4 +#define SPEEX_RESAMPLER_QUALITY_VOIP 3 +#define SPEEX_RESAMPLER_QUALITY_DESKTOP 5 + +enum { + RESAMPLER_ERR_SUCCESS = 0, + RESAMPLER_ERR_ALLOC_FAILED = 1, + RESAMPLER_ERR_BAD_STATE = 2, + RESAMPLER_ERR_INVALID_ARG = 3, + RESAMPLER_ERR_PTR_OVERLAP = 4, + RESAMPLER_ERR_OVERFLOW = 5, + + RESAMPLER_ERR_MAX_ERROR +}; + +struct SpeexResamplerState_; +typedef struct SpeexResamplerState_ SpeexResamplerState; + +/** Create a new resampler with integer input and output rates. + * @param nb_channels Number of channels to be processed + * @param in_rate Input sampling rate (integer number of Hz). + * @param out_rate Output sampling rate (integer number of Hz). + * @param quality Resampling quality between 0 and 10, where 0 has poor quality + * and 10 has very high quality. + * @return Newly created resampler state + * @retval NULL Error: not enough memory + */ +SpeexResamplerState *speex_resampler_init(spx_uint32_t nb_channels, + spx_uint32_t in_rate, + spx_uint32_t out_rate, + int quality, + int *err); + +/** Create a new resampler with fractional input/output rates. The sampling + * rate ratio is an arbitrary rational number with both the numerator and + * denominator being 32-bit integers. + * @param nb_channels Number of channels to be processed + * @param ratio_num Numerator of the sampling rate ratio + * @param ratio_den Denominator of the sampling rate ratio + * @param in_rate Input sampling rate rounded to the nearest integer (in Hz). + * @param out_rate Output sampling rate rounded to the nearest integer (in Hz). + * @param quality Resampling quality between 0 and 10, where 0 has poor quality + * and 10 has very high quality. + * @return Newly created resampler state + * @retval NULL Error: not enough memory + */ +SpeexResamplerState *speex_resampler_init_frac(spx_uint32_t nb_channels, + spx_uint32_t ratio_num, + spx_uint32_t ratio_den, + spx_uint32_t in_rate, + spx_uint32_t out_rate, + int quality, + int *err); + +/** Destroy a resampler state. + * @param st Resampler state + */ +void speex_resampler_destroy(SpeexResamplerState *st); + +/** Resample a float array. The input and output buffers must *not* overlap. + * @param st Resampler state + * @param channel_index Index of the channel to process for the multi-channel + * base (0 otherwise) + * @param in Input buffer + * @param in_len Number of input samples in the input buffer. Returns the + * number of samples processed + * @param out Output buffer + * @param out_len Size of the output buffer. Returns the number of samples written + */ +int speex_resampler_process_float(SpeexResamplerState *st, + spx_uint32_t channel_index, + const float *in, + spx_uint32_t *in_len, + float *out, + spx_uint32_t *out_len); + +/** Resample an int array. The input and output buffers must *not* overlap. + * @param st Resampler state + * @param channel_index Index of the channel to process for the multi-channel + * base (0 otherwise) + * @param in Input buffer + * @param in_len Number of input samples in the input buffer. Returns the number + * of samples processed + * @param out Output buffer + * @param out_len Size of the output buffer. Returns the number of samples written + */ +int speex_resampler_process_int(SpeexResamplerState *st, + spx_uint32_t channel_index, + const spx_int16_t *in, + spx_uint32_t *in_len, + spx_int16_t *out, + spx_uint32_t *out_len); + +/** Resample an interleaved float array. The input and output buffers must *not* overlap. + * @param st Resampler state + * @param in Input buffer + * @param in_len Number of input samples in the input buffer. Returns the number + * of samples processed. This is all per-channel. + * @param out Output buffer + * @param out_len Size of the output buffer. Returns the number of samples written. + * This is all per-channel. + */ +int speex_resampler_process_interleaved_float(SpeexResamplerState *st, + const float *in, + spx_uint32_t *in_len, + float *out, + spx_uint32_t *out_len); + +/** Resample an interleaved int array. The input and output buffers must *not* overlap. + * @param st Resampler state + * @param in Input buffer + * @param in_len Number of input samples in the input buffer. Returns the number + * of samples processed. This is all per-channel. + * @param out Output buffer + * @param out_len Size of the output buffer. Returns the number of samples written. + * This is all per-channel. + */ +int speex_resampler_process_interleaved_int(SpeexResamplerState *st, + const spx_int16_t *in, + spx_uint32_t *in_len, + spx_int16_t *out, + spx_uint32_t *out_len); + +/** Set (change) the input/output sampling rates (integer value). + * @param st Resampler state + * @param in_rate Input sampling rate (integer number of Hz). + * @param out_rate Output sampling rate (integer number of Hz). + */ +int speex_resampler_set_rate(SpeexResamplerState *st, + spx_uint32_t in_rate, + spx_uint32_t out_rate); + +/** Get the current input/output sampling rates (integer value). + * @param st Resampler state + * @param in_rate Input sampling rate (integer number of Hz) copied. + * @param out_rate Output sampling rate (integer number of Hz) copied. + */ +void speex_resampler_get_rate(SpeexResamplerState *st, + spx_uint32_t *in_rate, + spx_uint32_t *out_rate); + +/** Set (change) the input/output sampling rates and resampling ratio + * (fractional values in Hz supported). + * @param st Resampler state + * @param ratio_num Numerator of the sampling rate ratio + * @param ratio_den Denominator of the sampling rate ratio + * @param in_rate Input sampling rate rounded to the nearest integer (in Hz). + * @param out_rate Output sampling rate rounded to the nearest integer (in Hz). + */ +int speex_resampler_set_rate_frac(SpeexResamplerState *st, + spx_uint32_t ratio_num, + spx_uint32_t ratio_den, + spx_uint32_t in_rate, + spx_uint32_t out_rate); + +/** Get the current resampling ratio. This will be reduced to the least + * common denominator. + * @param st Resampler state + * @param ratio_num Numerator of the sampling rate ratio copied + * @param ratio_den Denominator of the sampling rate ratio copied + */ +void speex_resampler_get_ratio(SpeexResamplerState *st, + spx_uint32_t *ratio_num, + spx_uint32_t *ratio_den); + +/** Set (change) the conversion quality. + * @param st Resampler state + * @param quality Resampling quality between 0 and 10, where 0 has poor + * quality and 10 has very high quality. + */ +int speex_resampler_set_quality(SpeexResamplerState *st, + int quality); + +/** Get the conversion quality. + * @param st Resampler state + * @param quality Resampling quality between 0 and 10, where 0 has poor + * quality and 10 has very high quality. + */ +void speex_resampler_get_quality(SpeexResamplerState *st, + int *quality); + +/** Set (change) the input stride. + * @param st Resampler state + * @param stride Input stride + */ +void speex_resampler_set_input_stride(SpeexResamplerState *st, + spx_uint32_t stride); + +/** Get the input stride. + * @param st Resampler state + * @param stride Input stride copied + */ +void speex_resampler_get_input_stride(SpeexResamplerState *st, + spx_uint32_t *stride); + +/** Set (change) the output stride. + * @param st Resampler state + * @param stride Output stride + */ +void speex_resampler_set_output_stride(SpeexResamplerState *st, + spx_uint32_t stride); + +/** Get the output stride. + * @param st Resampler state copied + * @param stride Output stride + */ +void speex_resampler_get_output_stride(SpeexResamplerState *st, + spx_uint32_t *stride); + +/** Get the latency introduced by the resampler measured in input samples. + * @param st Resampler state + */ +int speex_resampler_get_input_latency(SpeexResamplerState *st); + +/** Get the latency introduced by the resampler measured in output samples. + * @param st Resampler state + */ +int speex_resampler_get_output_latency(SpeexResamplerState *st); + +/** Make sure that the first samples to go out of the resamplers don't have + * leading zeros. This is only useful before starting to use a newly created + * resampler. It is recommended to use that when resampling an audio file, as + * it will generate a file with the same length. For real-time processing, + * it is probably easier not to use this call (so that the output duration + * is the same for the first frame). + * @param st Resampler state + */ +int speex_resampler_skip_zeros(SpeexResamplerState *st); + +/** Reset a resampler so a new (unrelated) stream can be processed. + * @param st Resampler state + */ +int speex_resampler_reset_mem(SpeexResamplerState *st); + +/** Returns the English meaning for an error code + * @param err Error code + * @return English string + */ +const char *speex_resampler_strerror(int err); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/engine/voice_codecs/speex/source/libspeex/speex_stereo.h b/engine/voice_codecs/speex/speex/speex_stereo.h similarity index 69% rename from engine/voice_codecs/speex/source/libspeex/speex_stereo.h rename to engine/voice_codecs/speex/speex/speex_stereo.h index 3fbeb91b..5844f5a1 100644 --- a/engine/voice_codecs/speex/source/libspeex/speex_stereo.h +++ b/engine/voice_codecs/speex/speex/speex_stereo.h @@ -7,18 +7,18 @@ 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. - + - Neither the name of the Xiph.org Foundation nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - + 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 @@ -34,10 +34,20 @@ #ifndef STEREO_H #define STEREO_H +/** @defgroup SpeexStereoState SpeexStereoState: Handling Speex stereo files + * This describes the Speex intensity stereo encoding/decoding + * @{ + */ +#include "speex_types.h" #include "speex_bits.h" -/** State used for decoding (intensity) stereo information */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** If you access any of these fields directly, I'll personally come and bite you */ typedef struct SpeexStereoState { float balance; /**< Left/right balance info */ float e_ratio; /**< Ratio of energies: E(left+right)/[E(left)+E(right)] */ @@ -47,16 +57,36 @@ typedef struct SpeexStereoState { float reserved2; /**< Reserved for future use */ } SpeexStereoState; -/** Initialization value for a stereo state */ -#define SPEEX_STEREO_STATE_INIT {1,.5,1,1} +/** Deprecated. Use speex_stereo_state_init() instead. */ +#define SPEEX_STEREO_STATE_INIT {1,.5,1,1,0,0} + +/** Initialise/create a stereo stereo state */ +SpeexStereoState *speex_stereo_state_init(); + +/** Reset/re-initialise an already allocated stereo state */ +void speex_stereo_state_reset(SpeexStereoState *stereo); + +/** Destroy a stereo stereo state */ +void speex_stereo_state_destroy(SpeexStereoState *stereo); /** Transforms a stereo frame into a mono frame and stores intensity stereo info in 'bits' */ void speex_encode_stereo(float *data, int frame_size, SpeexBits *bits); +/** Transforms a stereo frame into a mono frame and stores intensity stereo info in 'bits' */ +void speex_encode_stereo_int(spx_int16_t *data, int frame_size, SpeexBits *bits); + /** Transforms a mono frame into a stereo frame using intensity stereo info */ void speex_decode_stereo(float *data, int frame_size, SpeexStereoState *stereo); +/** Transforms a mono frame into a stereo frame using intensity stereo info */ +void speex_decode_stereo_int(spx_int16_t *data, int frame_size, SpeexStereoState *stereo); + /** Callback handler for intensity stereo info */ int speex_std_stereo_request_handler(SpeexBits *bits, void *state, void *data); +#ifdef __cplusplus +} +#endif + +/** @} */ #endif diff --git a/engine/voice_codecs/speex/speex/speex_types.h b/engine/voice_codecs/speex/speex/speex_types.h new file mode 100644 index 00000000..bdc63295 --- /dev/null +++ b/engine/voice_codecs/speex/speex/speex_types.h @@ -0,0 +1,126 @@ +/* speex_types.h taken from libogg */ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: #ifdef jail to whip a few platforms into the UNIX ideal. + last mod: $Id: os_types.h 7524 2004-08-11 04:20:36Z conrad $ + + ********************************************************************/ +/** + @file speex_types.h + @brief Speex types +*/ +#ifndef _SPEEX_TYPES_H +#define _SPEEX_TYPES_H + +#if defined(_WIN32) + +# if defined(__CYGWIN__) +# include <_G_config.h> + typedef _G_int32_t spx_int32_t; + typedef _G_uint32_t spx_uint32_t; + typedef _G_int16_t spx_int16_t; + typedef _G_uint16_t spx_uint16_t; +# elif defined(__MINGW32__) + typedef short spx_int16_t; + typedef unsigned short spx_uint16_t; + typedef int spx_int32_t; + typedef unsigned int spx_uint32_t; +# elif defined(__MWERKS__) + typedef int spx_int32_t; + typedef unsigned int spx_uint32_t; + typedef short spx_int16_t; + typedef unsigned short spx_uint16_t; +# else + /* MSVC/Borland */ + typedef __int32 spx_int32_t; + typedef unsigned __int32 spx_uint32_t; + typedef __int16 spx_int16_t; + typedef unsigned __int16 spx_uint16_t; +# endif + +#elif defined(__MACOS__) + +# include + typedef SInt16 spx_int16_t; + typedef UInt16 spx_uint16_t; + typedef SInt32 spx_int32_t; + typedef UInt32 spx_uint32_t; + +#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ + +# include + typedef int16_t spx_int16_t; + typedef u_int16_t spx_uint16_t; + typedef int32_t spx_int32_t; + typedef u_int32_t spx_uint32_t; + +#elif defined(__BEOS__) + + /* Be */ +# include + typedef int16_t spx_int16_t; + typedef u_int16_t spx_uint16_t; + typedef int32_t spx_int32_t; + typedef u_int32_t spx_uint32_t; + +#elif defined (__EMX__) + + /* OS/2 GCC */ + typedef short spx_int16_t; + typedef unsigned short spx_uint16_t; + typedef int spx_int32_t; + typedef unsigned int spx_uint32_t; + +#elif defined (DJGPP) + + /* DJGPP */ + typedef short spx_int16_t; + typedef int spx_int32_t; + typedef unsigned int spx_uint32_t; + +#elif defined(R5900) + + /* PS2 EE */ + typedef int spx_int32_t; + typedef unsigned spx_uint32_t; + typedef short spx_int16_t; + +#elif defined(__SYMBIAN32__) + + /* Symbian GCC */ + typedef signed short spx_int16_t; + typedef unsigned short spx_uint16_t; + typedef signed int spx_int32_t; + typedef unsigned int spx_uint32_t; + +#elif defined(CONFIG_TI_C54X) || defined (CONFIG_TI_C55X) + + typedef short spx_int16_t; + typedef unsigned short spx_uint16_t; + typedef long spx_int32_t; + typedef unsigned long spx_uint32_t; + +#elif defined(CONFIG_TI_C6X) + + typedef short spx_int16_t; + typedef unsigned short spx_uint16_t; + typedef int spx_int32_t; + typedef unsigned int spx_uint32_t; + +#else + +#include "speex_config_types.h" + +#endif + +#endif /* _SPEEX_TYPES_H */ diff --git a/engine/voice_codecs/speex/speex/speexdsp_config_types.h b/engine/voice_codecs/speex/speex/speexdsp_config_types.h new file mode 100644 index 00000000..ca1f5a3c --- /dev/null +++ b/engine/voice_codecs/speex/speex/speexdsp_config_types.h @@ -0,0 +1,12 @@ +#ifndef __SPEEX_TYPES_H__ +#define __SPEEX_TYPES_H__ + +#include + +typedef int16_t spx_int16_t; +typedef uint16_t spx_uint16_t; +typedef int32_t spx_int32_t; +typedef uint32_t spx_uint32_t; + +#endif + diff --git a/engine/voice_codecs/speex/speex/speexdsp_types.h b/engine/voice_codecs/speex/speex/speexdsp_types.h new file mode 100644 index 00000000..4b4a76a4 --- /dev/null +++ b/engine/voice_codecs/speex/speex/speexdsp_types.h @@ -0,0 +1,126 @@ +/* speexdsp_types.h taken from libogg */ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: #ifdef jail to whip a few platforms into the UNIX ideal. + last mod: $Id: os_types.h 7524 2004-08-11 04:20:36Z conrad $ + + ********************************************************************/ +/** + @file speexdsp_types.h + @brief Speex types +*/ +#ifndef _SPEEX_TYPES_H +#define _SPEEX_TYPES_H + +#if defined(_WIN32) + +# if defined(__CYGWIN__) +# include <_G_config.h> + typedef _G_int32_t spx_int32_t; + typedef _G_uint32_t spx_uint32_t; + typedef _G_int16_t spx_int16_t; + typedef _G_uint16_t spx_uint16_t; +# elif defined(__MINGW32__) + typedef short spx_int16_t; + typedef unsigned short spx_uint16_t; + typedef int spx_int32_t; + typedef unsigned int spx_uint32_t; +# elif defined(__MWERKS__) + typedef int spx_int32_t; + typedef unsigned int spx_uint32_t; + typedef short spx_int16_t; + typedef unsigned short spx_uint16_t; +# else + /* MSVC/Borland */ + typedef __int32 spx_int32_t; + typedef unsigned __int32 spx_uint32_t; + typedef __int16 spx_int16_t; + typedef unsigned __int16 spx_uint16_t; +# endif + +#elif defined(__MACOS__) + +# include + typedef SInt16 spx_int16_t; + typedef UInt16 spx_uint16_t; + typedef SInt32 spx_int32_t; + typedef UInt32 spx_uint32_t; + +#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ + +# include + typedef int16_t spx_int16_t; + typedef u_int16_t spx_uint16_t; + typedef int32_t spx_int32_t; + typedef u_int32_t spx_uint32_t; + +#elif defined(__BEOS__) + + /* Be */ +# include + typedef int16_t spx_int16_t; + typedef u_int16_t spx_uint16_t; + typedef int32_t spx_int32_t; + typedef u_int32_t spx_uint32_t; + +#elif defined (__EMX__) + + /* OS/2 GCC */ + typedef short spx_int16_t; + typedef unsigned short spx_uint16_t; + typedef int spx_int32_t; + typedef unsigned int spx_uint32_t; + +#elif defined (DJGPP) + + /* DJGPP */ + typedef short spx_int16_t; + typedef int spx_int32_t; + typedef unsigned int spx_uint32_t; + +#elif defined(R5900) + + /* PS2 EE */ + typedef int spx_int32_t; + typedef unsigned spx_uint32_t; + typedef short spx_int16_t; + +#elif defined(__SYMBIAN32__) + + /* Symbian GCC */ + typedef signed short spx_int16_t; + typedef unsigned short spx_uint16_t; + typedef signed int spx_int32_t; + typedef unsigned int spx_uint32_t; + +#elif defined(CONFIG_TI_C54X) || defined (CONFIG_TI_C55X) + + typedef short spx_int16_t; + typedef unsigned short spx_uint16_t; + typedef long spx_int32_t; + typedef unsigned long spx_uint32_t; + +#elif defined(CONFIG_TI_C6X) + + typedef short spx_int16_t; + typedef unsigned short spx_uint16_t; + typedef int spx_int32_t; + typedef unsigned int spx_uint32_t; + +#else + +#include "speexdsp_config_types.h" + +#endif + +#endif /* _SPEEX_TYPES_H */ diff --git a/engine/voice_codecs/speex/wscript b/engine/voice_codecs/speex/wscript new file mode 100755 index 00000000..d1b1f581 --- /dev/null +++ b/engine/voice_codecs/speex/wscript @@ -0,0 +1,54 @@ +#! /usr/bin/env python +# encoding: utf-8 + +from waflib import Utils +import os + +top = '.' +PROJECT_NAME = 'vaudio_speex' + +def options(opt): + # stub + return + +def configure(conf): + conf.define('SPEEX_EXPORTS',1) +# conf.define('NO_HOOK_MALLOC',1) + +def build(bld): + source = [ + 'VoiceEncoder_Speex.cpp', + '../frame_encoder/voice_codec_frame.cpp', + '../../../tier1/interface.cpp' + ] + + includes = [ + '.', + '../frame_encoder', + '../../../public', + '../../../public/tier1', + '../../../public/tier0', + '../../', + '../../../common', + '../../audio/public' + ] + + defines = [] + + libs = ['tier0','tier1','vstdlib','SPEEX'] + + install_path = bld.env.LIBDIR + + bld.shlib( + source = source, + target = PROJECT_NAME, + name = PROJECT_NAME, + features = 'c cxx', + includes = includes, + defines = defines, + use = libs, + install_path = install_path, + subsystem = bld.env.MSVC_SUBSYSTEM, + idx = bld.get_taskgen_count() + ) + diff --git a/engine/vprof_engine.cpp b/engine/vprof_engine.cpp index 31df9668..a57db191 100644 --- a/engine/vprof_engine.cpp +++ b/engine/vprof_engine.cpp @@ -1117,8 +1117,6 @@ void WriteRemoteVProfGroupData( VProfListenInfo_t &info ) const char *pName = g_pVProfileForDisplay->GetBudgetGroupName( nIndex ); buf.PutString( pName ); } - - g_ServerRemoteAccess.SendVProfData( info.m_nListenerId, true, buf.Base(), buf.TellMaxPut() ); } static ConVar rpt_vprof_time( "rpt_vprof_time","0.25", FCVAR_HIDDEN | FCVAR_DONTRECORD, "" ); @@ -1167,7 +1165,6 @@ void WriteRemoteVProfData() Assert( nIndex >= 0 ); pSentTimes[ nIndex ] = pTimes[j]; } - g_ServerRemoteAccess.SendVProfData( s_VProfListeners[i].m_nListenerId, false, pSentTimes, nSentSize ); } } diff --git a/engine/wscript b/engine/wscript index 117e5047..510ee253 100755 --- a/engine/wscript +++ b/engine/wscript @@ -22,7 +22,8 @@ def configure(conf): 'ENGINE_DLL', 'VERSION_SAFE_STEAM_API_INTERFACES', 'USE_BREAKPAD_HANDLER', - 'USE_CONVARS' + 'USE_CONVARS', + 'VOICE_OVER_IP' ]) def build(bld): @@ -203,7 +204,8 @@ def build(bld): if bld.env.SDL: source += [ - 'audio/private/snd_dev_sdl.cpp' #[$SDL && !$OSXALL] + 'audio/private/snd_dev_sdl.cpp', #[$SDL && !$OSXALL] + 'audio/private/voice_record_sdl.cpp' #[$OSXALL||$LINUXALL] ] if bld.env.DEST_OS == 'win32': @@ -321,7 +323,7 @@ def build(bld): 'vgui_helpers.cpp', 'vgui_texturebudgetpanel.cpp', 'vgui_vprofgraphpanel.cpp', - 'vgui_vprofpanel.cpp', + 'vgui_vprofpanel.cpp', 'toolframework.cpp' ] diff --git a/engine/zone.cpp b/engine/zone.cpp index 5d90fa57..83363497 100644 --- a/engine/zone.cpp +++ b/engine/zone.cpp @@ -133,7 +133,14 @@ void Hunk_Print() void Memory_Init( void ) { MEM_ALLOC_CREDIT(); + +#ifdef PLATFORM_64BITS + // Seems to need to be larger to not get exhausted on + // 64-bit. Perhaps because of larger pointer sizes. + int nMaxBytes = 128*1024*1024; +#else int nMaxBytes = 48*1024*1024; +#endif const int nMinCommitBytes = 0x8000; #ifndef HUNK_USE_16MB_PAGE const int nInitialCommit = 0x280000; diff --git a/filesystem/QueuedLoader.cpp b/filesystem/QueuedLoader.cpp index 15ab20f1..dce2bd63 100644 --- a/filesystem/QueuedLoader.cpp +++ b/filesystem/QueuedLoader.cpp @@ -306,7 +306,7 @@ CQueuedLoader::CQueuedLoader() : BaseClass( false ) V_memset( m_pLoaders, 0, sizeof( m_pLoaders ) ); // set resource dictionaries sort context - for ( int i = 0; i < RESOURCEPRELOAD_COUNT; i++ ) + for ( intp i = 0; i < RESOURCEPRELOAD_COUNT; i++ ) { m_ResourceNames[i].SetLessContext( (void *)i ); } @@ -643,7 +643,7 @@ FileNameHandle_t CQueuedLoader::FindFilename( const char *pFilename ) //----------------------------------------------------------------------------- bool CQueuedLoader::CResourceNameLessFunc::Less( const FileNameHandle_t &hFilenameLHS, const FileNameHandle_t &hFilenameRHS, void *pCtx ) { - switch ( (int)pCtx ) + switch ( (intp)pCtx ) { case RESOURCEPRELOAD_MATERIAL: { diff --git a/filesystem/basefilesystem.cpp b/filesystem/basefilesystem.cpp index c33b9582..8a371b17 100644 --- a/filesystem/basefilesystem.cpp +++ b/filesystem/basefilesystem.cpp @@ -1804,7 +1804,7 @@ const char *CBaseFileSystem::GetWritePath( const char *pFilename, const char *pa //----------------------------------------------------------------------------- // Reads/writes files to utlbuffers. Attempts alignment fixups for optimal read //----------------------------------------------------------------------------- -CThreadLocal g_pszReadFilename; +CTHREADLOCAL(char *) g_pszReadFilename; bool CBaseFileSystem::ReadToBuffer( FileHandle_t fp, CUtlBuffer &buf, int nMaxBytes, FSAllocFunc_t pfnAlloc ) { SetBufferSize( fp, 0 ); // TODO: what if it's a pack file? restore buffer size? @@ -3445,7 +3445,7 @@ void CBaseFileSystem::EnableWhitelistFileTracking( bool bEnable, bool bCacheAllV { Error( "CBaseFileSystem::EnableWhitelistFileTracking called more than once." ); } - + m_WhitelistFileTrackingEnabled = bEnable; if ( m_WhitelistFileTrackingEnabled && bCacheAllVPKHashes ) { @@ -3619,6 +3619,9 @@ void CBaseFileSystem::NotifyFileUnloaded( const char *pszFilename, const char *p void CBaseFileSystem::SetSearchPathIsTrustedSource( CSearchPath *pSearchPath ) { +#if 1 + pSearchPath->m_bIsTrustedForPureServer = true; +#else // Broken, I am lazy to fix this // Most paths are not considered trusted pSearchPath->m_bIsTrustedForPureServer = false; @@ -3675,6 +3678,7 @@ void CBaseFileSystem::SetSearchPathIsTrustedSource( CSearchPath *pSearchPath ) Msg( "Setting %s as untrusted. (Key not in trusted key list)\n", pSearchPath->GetDebugString() ); #endif #endif +#endif } diff --git a/filesystem/filesystem_async.cpp b/filesystem/filesystem_async.cpp index 4196e090..adce661c 100644 --- a/filesystem/filesystem_async.cpp +++ b/filesystem/filesystem_async.cpp @@ -122,11 +122,11 @@ public: Q_strncpy( szFixedName, pszFilename, sizeof( szFixedName ) ); Q_FixSlashes( szFixedName ); - Assert( (int)FS_INVALID_ASYNC_FILE == m_map.InvalidIndex() ); + Assert( (intp)FS_INVALID_ASYNC_FILE == m_map.InvalidIndex() ); AUTO_LOCK( m_mutex ); - int iEntry = m_map.Find( szFixedName ); + intp iEntry = m_map.Find( szFixedName ); if ( iEntry == m_map.InvalidIndex() ) { iEntry = m_map.Insert( strdup( szFixedName ), new AsyncOpenedFile_t ); @@ -146,7 +146,7 @@ public: AUTO_LOCK( m_mutex ); - int iEntry = m_map.Find( szFixedName ); + intp iEntry = m_map.Find( szFixedName ); if ( iEntry != m_map.InvalidIndex() ) { m_map[iEntry]->AddRef(); @@ -164,7 +164,7 @@ public: AUTO_LOCK( m_mutex ); - int iEntry = (CUtlMap::IndexType_t)(int)item; + int iEntry = (CUtlMap::IndexType_t)(intp)item; Assert( m_map.IsValidIndex( iEntry ) ); m_map[iEntry]->AddRef(); return m_map[iEntry]; @@ -179,7 +179,7 @@ public: AUTO_LOCK( m_mutex ); - int iEntry = (CUtlMap::IndexType_t)(int)item; + int iEntry = (CUtlMap::IndexType_t)(intp)item; Assert( m_map.IsValidIndex( iEntry ) ); m_map[iEntry]->AddRef(); } @@ -193,7 +193,7 @@ public: AUTO_LOCK( m_mutex ); - int iEntry = (CUtlMap::IndexType_t)(int)item; + int iEntry = (CUtlMap::IndexType_t)(intp)item; Assert( m_map.IsValidIndex( iEntry ) ); if ( m_map[iEntry]->Release() == 0 ) { @@ -488,7 +488,7 @@ public: { if ( m_pData && m_bFreeMemory ) { - free( (void*) m_pData ); + delete[] (char*)m_pData; } } diff --git a/filesystem/filetracker.cpp b/filesystem/filetracker.cpp index 056af151..2956d4c6 100644 --- a/filesystem/filetracker.cpp +++ b/filesystem/filetracker.cpp @@ -14,7 +14,7 @@ #ifdef SUPPORT_PACKED_STORE -unsigned ThreadStubProcessMD5Requests( void *pParam ) +uintp ThreadStubProcessMD5Requests( void *pParam ) { return ((CFileTracker2 *)pParam)->ThreadedProcessMD5Requests(); } diff --git a/filesystem/linux_support.cpp b/filesystem/linux_support.cpp index c68967c4..81988846 100644 --- a/filesystem/linux_support.cpp +++ b/filesystem/linux_support.cpp @@ -102,7 +102,7 @@ HANDLE FindFirstFile( const char *fileName, FIND_DATA *dat) { char nameStore[PATH_MAX]; char *dir=NULL; - int n,iret=-1; + intp n,iret=-1; Q_strncpy(nameStore,fileName, sizeof( nameStore ) ); diff --git a/filesystem/wscript b/filesystem/wscript index 5a8ae946..6f8d9c50 100755 --- a/filesystem/wscript +++ b/filesystem/wscript @@ -46,8 +46,8 @@ def build(bld): defines = [] - libs = ['tier0','tier1','tier2','vstdlib','vpklib'] - + libs = ['tier0','vpklib','tier1','tier2','vstdlib'] + if bld.env.DEST_OS == 'win32': libs += ['SHELL32'] diff --git a/game/client/abuse_report.cpp b/game/client/abuse_report.cpp deleted file mode 100644 index 285a633b..00000000 --- a/game/client/abuse_report.cpp +++ /dev/null @@ -1,720 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: Generic in-game abuse reporting -// -// $NoKeywords: $ -//=============================================================================// - -#include "cbase.h" -#include "abuse_report.h" -#include "abuse_report_ui.h" -#include "filesystem.h" -#include "imageutils.h" -#include "econ/confirm_dialog.h" -#include "econ/econ_notifications.h" - -inline bool IsLoggedOnToSteam() -{ - return steamapicontext != NULL && steamapicontext->SteamUser() != NULL && steamapicontext->SteamUser()->BLoggedOn(); -} - -const char CAbuseReportManager::k_rchScreenShotFilenameBase[] = "abuse_report"; -const char CAbuseReportManager::k_rchScreenShotFilename[] = "screenshots\\abuse_report.jpg"; - -//----------------------------------------------------------------------------- -class CEconNotification_AbuseReportReady : public CEconNotification -{ -public: - CEconNotification_AbuseReportReady() : CEconNotification() - { - m_bHasTriggered = false; - m_bShowInGame = false; - } - - ~CEconNotification_AbuseReportReady() - { - //if ( !m_bHasTriggered ) - //{ - // ReallyTrigger(); - //} - } - - virtual void MarkForDeletion() - { - m_bHasTriggered = true; - - CEconNotification::MarkForDeletion(); - } - - virtual bool BShowInGameElements() const { return m_bShowInGame; } - virtual EType NotificationType() { return eType_Trigger; } - virtual void Trigger() - { - ReallyTrigger(); - MarkForDeletion(); - } - - virtual const char *GetUnlocalizedHelpText() - { - return "#AbuseReport_Notification_Help"; - } - - static bool IsNotificationType( CEconNotification *pNotification ) { return dynamic_cast< CEconNotification_AbuseReportReady *>( pNotification ) != NULL; } - static bool IsInGameNotificationType( CEconNotification *pNotification ) - { - CEconNotification_AbuseReportReady *n = dynamic_cast< CEconNotification_AbuseReportReady *>( pNotification ); - return n != NULL && n->BShowInGameElements(); - } - - bool m_bShowInGame; - -private: - - void ReallyTrigger() - { - Assert( !m_bHasTriggered ); - m_bHasTriggered = true; - engine->ClientCmd_Unrestricted( "abuse_report_submit" ); - } - - bool m_bHasTriggered; -}; - -AbuseIncidentData_t::AbuseIncidentData_t() -{ - m_nScreenShotWaitFrames = 5; -} - -AbuseIncidentData_t::~AbuseIncidentData_t() -{ -} - -bool AbuseIncidentData_t::Poll() -{ - bool bReady = true; - - // Poll player data - for ( int i = 0 ; i < m_vecPlayers.Count() ; ++i ) - { - - // Make sure sure Steam knows we want the Avatar - PlayerData_t *p = &m_vecPlayers[i]; - if ( p->m_iSteamAvatarIndex < 0 ) - { - if ( steamapicontext && steamapicontext->SteamUser() ) - { - - p->m_iSteamAvatarIndex = steamapicontext->SteamFriends()->GetLargeFriendAvatar( p->m_steamID ); - if ( p->m_iSteamAvatarIndex < 0 ) - { - bReady = false; - } - } - else - { - p->m_iSteamAvatarIndex = 0; - } - } - } - - // Screenshot ready? - if ( !m_bitmapScreenshot.IsValid() && m_nScreenShotWaitFrames > 0 ) - { - --m_nScreenShotWaitFrames; - - // Just load the whole file into a memory buffer - char szFullPath[ MAX_PATH ] = ""; - if ( !g_pFullFileSystem->RelativePathToFullPath( CAbuseReportManager::k_rchScreenShotFilename, NULL, szFullPath, ARRAYSIZE(szFullPath) ) ) - { - Assert( false ); // ??? - } - - // Load it - - if ( g_pFullFileSystem->FileExists( szFullPath ) ) - { - - // Load the screenshot into a local buffer - if ( !g_pFullFileSystem->ReadFile( CAbuseReportManager::k_rchScreenShotFilename, NULL, m_bufScreenshotFileData ) ) - { - Warning( "Failed to read back %s\n", CAbuseReportManager::k_rchScreenShotFilename ); - m_nScreenShotWaitFrames = 0; - } - else - { - ConversionErrorType nErrorCode = ImgUtl_LoadBitmap( szFullPath, m_bitmapScreenshot ); - if ( nErrorCode != CE_SUCCESS ) - { - Warning( "Abuse report screenshot %s failed to load with error code %d\n", CAbuseReportManager::k_rchScreenShotFilename, nErrorCode ); - Assert( nErrorCode == CE_SUCCESS ); - m_nScreenShotWaitFrames = 0; - } - else - { - // !KLUDGE! Resize to power of two dimensions, since VGUI doesn't like odd sizes - ImgUtl_ResizeBitmap( m_bitmapScreenshot, 1024, 1024, &m_bitmapScreenshot ); - } - } - g_pFullFileSystem->RemoveFile( CAbuseReportManager::k_rchScreenShotFilename ); - } - } - - return bReady; -} - -CAbuseReportManager *g_AbuseReportMgr; - -CAbuseReportManager::CAbuseReportManager() -{ - m_pIncidentData = NULL; - m_bTestReport = false; - m_eIncidentDataStatus = k_EIncidentDataStatus_None; - m_bReportUIPending = false; - - // We're the singleton --- set global pointer - Assert( g_AbuseReportMgr == NULL ); - g_AbuseReportMgr = this; - m_timeLastReportReadyNotification = 0.0; - m_adrCurrentServer.Clear(); -} - -CAbuseReportManager::~CAbuseReportManager() -{ - Assert( m_pIncidentData == NULL ); -} - -char const *CAbuseReportManager::Name() -{ - return "AbuseRepotManager"; -} - -bool CAbuseReportManager::Init() -{ - // Clean out any temporary files - Assert( m_pIncidentData == NULL ); - DestroyIncidentData(); - - ListenForGameEvent( "teamplay_round_win" ); - ListenForGameEvent( "tf_game_over" ); - ListenForGameEvent( "player_death" ); - ListenForGameEvent( "server_spawn" ); - - return true; -} - -void CAbuseReportManager::LevelShutdownPreEntity() -{ - - // Don't keep the dialog open across a level transition. Don't discard their - // report data, but let's kill the dialog - if ( g_AbuseReportDlg.Get() != NULL ) - { - Warning( "Abuse report dialog open during level shutdown. Closing it.\n" ); - g_AbuseReportDlg.Get()->Close(); - } - - // And clear the 'pending' flag - m_bReportUIPending = false; -} - -void CAbuseReportManager::FireGameEvent( IGameEvent *event ) -{ - //C_BasePlayer *pLocalPlayer = C_BasePlayer::GetLocalPlayer(); - - const char *eventname = event->GetName(); - - if ( !eventname || !eventname[0] ) - return; - - if ( - !Q_strcmp( "teamplay_round_win", eventname ) - || !Q_strcmp( "tf_game_over", eventname ) - ) { - // Periodically remind them that they have a report ready to file - CheckCreateReportReadyNotification( 60.0 * 5.0, true, 10.0f ); - } - else if ( !Q_strcmp( "player_death", eventname ) ) - { - // In some maps, the round just never ends. - // So make sure we do remind them every now and then about this. - // Just not too often - CheckCreateReportReadyNotification( 60.0 * 20.0, true, 5.0f ); - } - else if ( !Q_strcmp( "server_spawn", eventname ) ) - { - m_adrCurrentServer.Clear(); - m_adrCurrentServer.SetFromString( event->GetString( "address", "" ), false ); - m_adrCurrentServer.SetPort( event->GetInt( "port", 0 ) ); - - m_steamIDCurrentServer = CSteamID(); - if ( steamapicontext && steamapicontext->SteamUser() && GetUniverse() != k_EUniverseInvalid ) - { - m_steamIDCurrentServer.SetFromString( event->GetString( "steamid", "" ), GetUniverse() ); - } - } -} - -void CAbuseReportManager::Shutdown() -{ - // Close the dialog, if any - LevelShutdownPreEntity(); - - DestroyIncidentData(); - - // Clear global pointer - Assert( g_AbuseReportMgr == this ); - if ( g_AbuseReportMgr == this ) - { - g_AbuseReportMgr = NULL; - } -} - -void CAbuseReportManager::Update( float frametime ) -{ - - // if a dialog is already displayed, make sure we don't try to activate another - if ( g_AbuseReportDlg.Get() != NULL ) - { - m_bReportUIPending = false; - } - - // Poll report data, if any - if ( m_pIncidentData != NULL ) - { - if ( m_eIncidentDataStatus == k_EIncidentDataStatus_Preparing ) - { - if ( m_pIncidentData->Poll() ) - { - m_eIncidentDataStatus = k_EIncidentDataStatus_Ready; - CheckCreateReportReadyNotification( 1.0f, true, 7.0f ); - } - } - else - { - Assert( m_eIncidentDataStatus == k_EIncidentDataStatus_Ready ); - } - - if ( m_eIncidentDataStatus == k_EIncidentDataStatus_Ready && m_bReportUIPending ) - { - m_bReportUIPending = false; - ActivateSubmitReportUI(); - } - } - else - { - m_bReportUIPending = false; - } - - // Re-create notification constantly in the menu. - // While in game, we will only popup notifications - // periodically at round end or player death - CheckCreateReportReadyNotification( 10.0, false, 999.0f ); -} - -void CAbuseReportManager::SubmitReportUIRequested() -{ - if ( g_AbuseReportDlg.Get() != NULL ) - { - Assert( g_AbuseReportDlg.Get() == NULL ); - return; - } - - // If no report data already, then create some - if ( m_pIncidentData == NULL ) - { - QueueReport(); - if ( m_pIncidentData == NULL ) - { - // Failed - return; - } - } - - // Set flag to bring up the reporting UI at earliest opportunity, - // once all data has been fetched asynchronously - m_bReportUIPending = true; -} - -bool CAbuseReportManager::CreateAndPopulateIncident() -{ - Assert( m_pIncidentData == NULL ); - - // by default, just create the base class version - m_pIncidentData = new AbuseIncidentData_t; - - // And populate it - return PopulateIncident(); -} - -bool CAbuseReportManager::PopulateIncident() -{ - if ( m_pIncidentData == NULL ) - { - Assert( m_pIncidentData ); - return false; - } - - // Queue a screenshot - CUtlString cmd; - cmd.Format( "__screenshot_internal \"%s\"", k_rchScreenShotFilenameBase ); - engine->ClientCmd_Unrestricted( cmd ); - - // Set status as preparing - m_eIncidentDataStatus = k_EIncidentDataStatus_Preparing; - - m_pIncidentData->m_bCanReportGameServer = false; - - m_pIncidentData->m_adrGameServer.Clear(); - if ( - m_adrCurrentServer.IsValid() - && !m_adrCurrentServer.IsLocalhost() - && m_steamIDCurrentServer.IsValid() - && ( !m_adrCurrentServer.IsReservedAdr() || m_steamIDCurrentServer.GetEUniverse() != k_EUniversePublic ) - ) - { - m_pIncidentData->m_adrGameServer = m_adrCurrentServer; - m_pIncidentData->m_steamIDGameServer = m_steamIDCurrentServer; - m_pIncidentData->m_bCanReportGameServer = true; - } - - m_pIncidentData->m_matWorldToClip = engine->WorldToScreenMatrix(); - - // Add in players - for (int i = 1 ; i <= gpGlobals->maxClients ; ++i ) - { - CBasePlayer *player = UTIL_PlayerByIndex( i ); - - #ifndef _DEBUG - // Skip local players - if ( player != NULL && player->IsLocalPlayer() ) - { - continue; - } - #endif - - // Get player info from the engine. This works even if they haven't spawned yet. - player_info_t pi; - if ( !engine->GetPlayerInfo( i, &pi ) ) - { - continue; - } - - if ( pi.fakeplayer ) - { - continue; - } - if ( pi.friendsID == 0 ) - { - continue; - } - CSteamID steamID( pi.friendsID, 1, GetUniverse(), k_EAccountTypeIndividual ); - if ( !steamID.IsValid() ) - { - Assert( steamID.IsValid() ); - continue; - } - - int arrayIndex = m_pIncidentData->m_vecPlayers.AddToTail(); - AbuseIncidentData_t::PlayerData_t *p = &m_pIncidentData->m_vecPlayers[ arrayIndex ]; - - p->m_iClientIndex = i; - p->m_steamID = steamID; - p->m_sPersona = pi.name; - p->m_bHasEntity = false; - p->m_bRenderBoundsValid = false; - p->m_screenBoundsMin.x = p->m_screenBoundsMin.y = 1.0f; - p->m_screenBoundsMax.x = p->m_screenBoundsMax.y = 0.0f; - - if ( player==NULL ) - { - continue; - } - - p->m_bHasEntity = true; - player->GetRenderBounds( p->m_vecRenderBoundsMin, p->m_vecRenderBoundsMax ); - p->m_matModelToWorld.CopyFrom3x4( player->RenderableToWorldTransform() ); - MatrixMultiply( m_pIncidentData->m_matWorldToClip, p->m_matModelToWorld, p->m_matModelToClip ); - - // Gather up screen extents - p->m_bRenderBoundsValid = false; - for ( int j = 0 ; j < 8 ; ++j ) - { - - // Get corner point in model space - Vector4D modelCorner( - ( j & 1 ) ? p->m_vecRenderBoundsMax.x : p->m_vecRenderBoundsMin.x, - ( j & 2 ) ? p->m_vecRenderBoundsMax.y : p->m_vecRenderBoundsMin.y, - ( j & 4 ) ? p->m_vecRenderBoundsMax.z : p->m_vecRenderBoundsMin.z, - 1.0f - ); - - // Transform to clip space - Vector4D clipCorner; - Vector4DMultiply( p->m_matModelToClip, modelCorner, clipCorner ); - - //Msg( "%6.3f, %6.3f, %6.3f, %6.3f\n", clipCorner[0], clipCorner[1], clipCorner[2], clipCorner[3] ); - - // If all points behind near clip plane, don't try to - // figure out screen space bounds - if ( clipCorner[3] > .1f ) - { - p->m_bRenderBoundsValid = true; - } - - // Push w forward to "near clip plane" - float w = MAX( clipCorner[3], .1f ); - - // Divide by w to project, and convert normalized device coordinates - // where the view volume is (-1...1), to normalized screen coords, where - // they are from 0...1 - float x = ( clipCorner[0] / w + 1.0f ) / 2.0f; - float y = ( -clipCorner[1] / w + 1.0f ) / 2.0f; - p->m_screenBoundsMin.x = MIN( p->m_screenBoundsMin.x, x ); - p->m_screenBoundsMax.x = MAX( p->m_screenBoundsMax.x, x ); - p->m_screenBoundsMin.y = MIN( p->m_screenBoundsMin.y, y ); - p->m_screenBoundsMax.y = MAX( p->m_screenBoundsMax.y, y ); - } - - // Clip projected rect to the screen - if ( p->m_bRenderBoundsValid ) - { - p->m_screenBoundsMin.x = MAX( p->m_screenBoundsMin.x, 0.0f ); - p->m_screenBoundsMax.x = MIN( p->m_screenBoundsMax.x, 1.0f ); - p->m_screenBoundsMin.y = MAX( p->m_screenBoundsMin.y, 0.0f ); - p->m_screenBoundsMax.y = MIN( p->m_screenBoundsMax.y, 1.0f ); - - p->m_bRenderBoundsValid = - p->m_screenBoundsMin.x + .01f < p->m_screenBoundsMax.x - && p->m_screenBoundsMin.y + .01f < p->m_screenBoundsMax.y; - } - - // Sanity check that we agree on what their steam ID is! - if ( player->GetSteamID( &steamID ) ) - { - Assert( p->m_steamID == steamID ); - } - } - - // Test harness: add in a handful of fake players - #ifdef _DEBUG - if ( m_bTestReport ) - { - int arrayIndex = m_pIncidentData->m_vecPlayers.AddToTail(); - AbuseIncidentData_t::PlayerData_t *p = &m_pIncidentData->m_vecPlayers[ arrayIndex ]; - - p->m_iClientIndex = -1; - p->m_sPersona = "Lippencott"; - p->m_steamID.SetFromUint64( 148618791998333672 ); - - arrayIndex = m_pIncidentData->m_vecPlayers.AddToTail(); - p = &m_pIncidentData->m_vecPlayers[ arrayIndex ]; - - p->m_iClientIndex = -1; - p->m_sPersona = "EricS"; - p->m_steamID.SetFromUint64( 148618791998195668 ); - - arrayIndex = m_pIncidentData->m_vecPlayers.AddToTail(); - p = &m_pIncidentData->m_vecPlayers[ arrayIndex ]; - - p->m_iClientIndex = -1; - p->m_sPersona = "Sarenya"; - p->m_steamID.SetFromUint64( 148618791998429832 ); - - arrayIndex = m_pIncidentData->m_vecPlayers.AddToTail(); - p = &m_pIncidentData->m_vecPlayers[ arrayIndex ]; - - - p->m_iClientIndex = -1; - p->m_sPersona = "fletch"; - p->m_steamID.SetFromUint64( 148618791998436114 ); - { - AbuseIncidentData_t::PlayerImage_t img; - img.m_eType = AbuseIncidentData_t::k_PlayerImageType_UGC; - img.m_hUGCHandle = 6978249415967519; - p->m_vecImages.AddToTail( img ); - } - - if ( !m_pIncidentData->m_bCanReportGameServer) - { - m_pIncidentData->m_adrGameServer.SetFromString( "123.45.67.89:27015", false ); - m_pIncidentData->m_steamIDGameServer = CSteamID( 12345, 0, GetUniverse(), k_EAccountTypeAnonGameServer ); - m_pIncidentData->m_bCanReportGameServer = true; - } - } - #endif - - // Make sure there is at least one other person we could file a report against! - if ( m_pIncidentData->m_vecPlayers.Count() < 1 ) - { - Warning( "No players to accuse of abuse, cannot file report\n" ); - return false; - } - - return true; -} - -void CAbuseReportManager::DestroyIncidentData() -{ - if ( m_pIncidentData != NULL ) - { - delete m_pIncidentData; - m_pIncidentData = NULL; - } - m_eIncidentDataStatus = k_EIncidentDataStatus_None; - - // Get rid of any existing screenshot file, both locally - // and in the cloud. We don't want this to count against - // our quota - if ( steamapicontext && steamapicontext->SteamRemoteStorage() && steamapicontext->SteamRemoteStorage()->FileExists( k_rchScreenShotFilename ) ) - { - steamapicontext->SteamRemoteStorage()->FileDelete( k_rchScreenShotFilename ); - } - - if ( g_pFullFileSystem->FileExists( k_rchScreenShotFilename ) ) // !KLUDGE! To prevent warning if the file doesn't exist! - { - g_pFullFileSystem->RemoveFile( k_rchScreenShotFilename ); - } - - m_timeLastReportReadyNotification = 0.0; - - // Make sure we don't have any notifications queued - NotificationQueue_Remove( &CEconNotification_AbuseReportReady::IsNotificationType ); -} - -void CAbuseReportManager::QueueReport() -{ - // Dialog is already active? - if ( g_AbuseReportDlg.Get() != NULL ) - { - Warning( "Cannot capture another incident report. Submission dialog is active.\n" ); - return; - } - - // Destroy any existing data - DestroyIncidentData(); - - // Make sure we're logged on to Steam - if ( !IsLoggedOnToSteam() ) - { - g_AbuseReportMgr->ShowNoSteamErrorMessage(); - return; - } - - if ( CreateAndPopulateIncident() ) - { - Msg( "Captured data for abuse report.\n"); - } - else - { - Warning( "Failed to captured data for abuse report.\n"); - DestroyIncidentData(); - } -} - -void CAbuseReportManager::ShowNoSteamErrorMessage() -{ - ShowMessageBox( "#AbuseReport_NoSteamTitle", "#AbuseReport_NoSteamMessage", "#GameUI_OK" ); -} - -void CAbuseReportManager::CheckCreateReportReadyNotification( float flMinSecondsSinceLastNotification, bool bInGame, float flLifetime ) -{ - // We have to have some data ready - if ( m_pIncidentData == NULL || m_eIncidentDataStatus != k_EIncidentDataStatus_Ready ) - { - return; - } - - // Don't pester them if they are already trying to do something about it - if ( g_AbuseReportDlg.Get() != NULL || m_bReportUIPending ) - { - return; - } - - // Already notified them too recently? - if ( m_timeLastReportReadyNotification != 0.0 && Plat_FloatTime() < m_timeLastReportReadyNotification + flMinSecondsSinceLastNotification ) - { - return; - } - - // Already a notification in the queue? - if ( bInGame ) - { - if ( NotificationQueue_Count( &CEconNotification_AbuseReportReady::IsInGameNotificationType ) > 0 ) - { - return; - } - } - else - { - if ( NotificationQueue_Count( &CEconNotification_AbuseReportReady::IsNotificationType ) > 0 ) - { - return; - } - } - - CreateReportReadyNotification( bInGame, flLifetime ); -} - -void CAbuseReportManager::CreateReportReadyNotification( bool bInGame, float flLifetime ) -{ - NotificationQueue_Remove( &CEconNotification_AbuseReportReady::IsNotificationType ); - CEconNotification_AbuseReportReady *pNotification = new CEconNotification_AbuseReportReady(); - pNotification->SetText( "AbuseReport_Notification" ); - pNotification->SetLifetime( flLifetime ); - pNotification->m_bShowInGame = bInGame; - NotificationQueue_Add( pNotification ); - - m_timeLastReportReadyNotification = Plat_FloatTime(); -} - -CON_COMMAND_F( abuse_report_queue, "Capture data for abuse report and queue for submission. Use abose_report_submit to activate UI to submit the report", FCVAR_DONTRECORD ) -{ - if ( !g_AbuseReportMgr ) - { - Warning( "abuse_report_queue: No abuse report manager, cannot create report.\n" ); - return; - } - - g_AbuseReportMgr->QueueReport(); -} - -CON_COMMAND_F( abuse_report_submit, "Activate UI to submit queued report. Use abuse_report_queue to capture data for the report the report", FCVAR_DONTRECORD ) -{ - if ( !g_AbuseReportMgr ) - { - Warning( "abuse_report_submit: No abuse report manager, cannot submit report.\n" ); - return; - } - - // Make sure we're logged on to Steam - if ( !IsLoggedOnToSteam() ) - { - g_AbuseReportMgr->ShowNoSteamErrorMessage(); - return; - } - - if ( g_AbuseReportDlg.Get() != NULL ) - { - // Dialog is already active - return; - } - g_AbuseReportMgr->SubmitReportUIRequested(); -} - -// Test harness -#ifdef _DEBUG - -CON_COMMAND_F( abuse_report_test, "Make a test abuse incident and activate UI", FCVAR_DONTRECORD ) -{ - if ( !g_AbuseReportMgr ) - { - Assert( g_AbuseReportMgr ); - return; - } - g_AbuseReportMgr->m_bTestReport = true; - g_AbuseReportMgr->QueueReport(); - g_AbuseReportMgr->m_bTestReport = false; - engine->ClientCmd_Unrestricted( "abuse_report_submit" ); -} - -#endif diff --git a/game/client/abuse_report.h b/game/client/abuse_report.h deleted file mode 100644 index 43410864..00000000 --- a/game/client/abuse_report.h +++ /dev/null @@ -1,274 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: Generic in-game abuse reporting -// -// $NoKeywords: $ -//=============================================================================// - -#ifndef ABUSE_REPORT_H -#define ABUSE_REPORT_H -#ifdef _WIN32 -#pragma once -#endif - -#include -#include -#include -#include - -/// Different content types that can be reported as abusive. -/// -/// WARNING: These enum values MUST MATCH the values in Steam's -/// ECommunityContentType! -enum EAbuseReportContentType -{ - k_EAbuseReportContentNoSelection = -1, // dummy ilegal value: the user has not made a selection - k_EAbuseReportContentUnspecified = 0, // we use this to mean "other" - //k_EAbuseReportContentAll = 1, // reset all community content - k_EAbuseReportContentAvatarImage = 2, // clear avatar image - //k_EAbuseReportContentProfileText = 3, // reset profile text - //k_EAbuseReportContentWebLinks = 4, // delete web links - //k_EAbuseReportContentAnnouncement = 5, - //k_EAbuseReportContentEventText = 6, - //k_EAbuseReportContentCustomCSS = 7, - //k_EAbuseReportContentProfileURL = 8, // delete community URL ID - k_EAbuseReportContentComments = 9, // just comments this guy has written - k_EAbuseReportContentPersonaName = 10, // persona name - //k_EAbuseReportContentScreenshot = 11, // screenshot - //k_EAbuseReportContentVideo = 12, // videos - k_EAbuseReportContentCheating = 13, // cheating - k_EAbuseReportContentUGCImage = 14, // Image stored in UGC --- the report is accusing the image of being offensive - k_EAbuseReportContentActorUGCImage = 15, // Abuse report actor has uploaded a UGC image to server as supporting documentation of their claim -}; - - -/// Types of reasons why a violation report was issued -/// -/// WARNING: These enum values MUST MATCH the values in Steam's -/// EAbuseReportType! -enum EAbuseReportType -{ - k_EAbuseReportTypeNoSelection = -1, // dummy ilegal value: the user has not made a selection - k_EAbuseReportTypeUnspecified = 0, - k_EAbuseReportTypeInappropriate = 1, // just not ok to post - k_EAbuseReportTypeProhibited = 2, // prohibited by EULA or general law - k_EAbuseReportTypeSpamming = 3, // excessive spamming - k_EAbuseReportTypeAdvertisement = 4, // unwanted advertisement - //k_EAbuseReportTypeExploit = 5, // content data attempts to exploit code issue - k_EAbuseReportTypeSpoofing = 6, // user/group is impersonating an official contact - k_EAbuseReportTypeLanguage = 7, // bad language - k_EAbuseReportTypeAdultContent = 8, // any kind of adult material, references etc - k_EAbuseReportTypeHarassment = 9, // harassment, discrimination, racism etc - k_EAbuseReportTypeCheating = 10, // cheating -}; - -/// Container class that has everything we need to know in order to file -/// an abuse report, which is significantly more than the data we actually -/// include in a particular abuse report. It's everything we save off at the -/// time the user initiates the abuse reporting mechanism. Games can derive -/// their own report types and put game-specific data in here. -struct AbuseIncidentData_t -{ - AbuseIncidentData_t(); - virtual ~AbuseIncidentData_t(); - - enum EPlayerImageType - { - k_PlayerImageType_UGC, - k_PlayerImageType_Spray, - }; - - /// A custom image of the player's that could be considered offensive - struct PlayerImage_t - { - - /// What kind of image is it? - EPlayerImageType m_eType; - - /// For UGC images, what's the handle? - uint64 m_hUGCHandle; - }; - - /// Info we remember for one player. - struct PlayerData_t - { - PlayerData_t() - { - m_iClientIndex = -1; - m_iSteamAvatarIndex = -1; - } - - /// The client index. (See UTIL_PlayerByIndex). Note that this - /// index is really only valid at the time the incident is captured. - /// Because players can leave after the incident is captured. - int m_iClientIndex; - - /// The name they were going by at the time - CUtlString m_sPersona; - - /// Their steam ID. This is essential so we can file - /// an abuse report! - CSteamID m_steamID; - - /// Index of steam friends icon for their avatar. - /// 0 if they don't have one! - int m_iSteamAvatarIndex; - - /// Do we have an entity for this player? They might not have spawned, - /// or might be outside our PVS, etc. - bool m_bHasEntity; - - /// Model transform for the player's render stuff - VMatrix m_matModelToWorld; - - /// Model->clip matrix for the player's render stuff - VMatrix m_matModelToClip; - - /// True if the render bounds are approximately correct, false if not - bool m_bRenderBoundsValid; - - /// Bounds (in model space) of the player's renderable stuff - Vector m_vecRenderBoundsMin, m_vecRenderBoundsMax; - - /// Bounds (in normalized screen space coords 0...1) of the player's - /// renderable stuff - Vector2D m_screenBoundsMin, m_screenBoundsMax; - - /// List of his images - CUtlVector m_vecImages; - }; - - /// List of base player data. You got more data per player in your derived - /// incident type? Store it in a parallel array. - CUtlVector m_vecPlayers; - - /// Camera world -> clip matrix. - VMatrix m_matWorldToClip; - - /// Screenshot - Bitmap_t m_bitmapScreenshot; - - // Screenshot file data - CUtlBuffer m_bufScreenshotFileData; - - /// Number of frames we're willing to wait for the engine to write out a screenshot. - /// Zero if we already failed - int m_nScreenShotWaitFrames; - - /// Is it possible to report the game server itself for abuse? - bool m_bCanReportGameServer; - - /// What Game Server/IP are we on? Will be an invalid address if we don't know - netadr_t m_adrGameServer; - - /// Steam ID of the game server / IP we are on - CSteamID m_steamIDGameServer; - - /// Poll report (some data may have to be fetched asynchronously), - /// return true if everything is ready - virtual bool Poll(); -}; - -/// Generic abuse reporting panel. Your -class CAbuseReportManager : public CBaseGameSystemPerFrame, public CGameEventListener -{ -public: - CAbuseReportManager(); - virtual ~CAbuseReportManager(); - - // - // CAutoGameSystemPerFrame overrides - // - virtual char const *Name(); - virtual bool Init(); - virtual void Shutdown(); - virtual void LevelShutdownPreEntity(); - - // - // CGameEventListener overrides - // - virtual void FireGameEvent( IGameEvent *event ); - -// CAutoGameSystemPerFrame defines different stuff depending on which DLL we're building -#ifdef CLIENT_DLL - - // Do our frame-time processing - virtual void Update( float frametime ); - -#else - #error "Why is this being included?" -#endif - - /// Called when the console command is executed to capture data for a report - virtual void QueueReport(); - - /// Called when the console command is executed to submit data for a report - virtual void SubmitReportUIRequested(); - - /// Called to actually trigger the report UI, after all data is ready - virtual void ActivateSubmitReportUI() = 0; - - /// Fetch the incident that's queued to be reported - AbuseIncidentData_t *GetIncidentData() const { return m_pIncidentData; } - - /// Delete any current report incident. Also should clean - /// out any temporary files used by the incident system. - virtual void DestroyIncidentData(); - - /// Show a message box complaining about lack of steam - /// connection - virtual void ShowNoSteamErrorMessage(); - - /// Insert a a notification into the queue indicating that an unfiled report is ready - virtual void CreateReportReadyNotification( bool bInGame, float flLifetime ); - - /// Test harness. Set this to true, to generate fake data - bool m_bTestReport; - - static const char k_rchScreenShotFilenameBase[]; - static const char k_rchScreenShotFilename[]; - -protected: - - /// Your app will probably define its own abuse report types. - /// if so, you will need to override this function. - /// The base class just calls new to create an object, then calls - /// PopulateIncident() - virtual bool CreateAndPopulateIncident(); - - /// Fill in the details about the current incident. This just fills in the - /// base class data, and it should be called from CreateAndPopulateIncident - bool PopulateIncident(); - - /// Current incident that is pending to be reported or is being generated. - /// Might be NULL. - AbuseIncidentData_t *m_pIncidentData; - - /// Status of incident data. - enum EIncidentDataStatus - { - k_EIncidentDataStatus_None, - k_EIncidentDataStatus_Preparing, // we shuld call Poll() until it's ready - k_EIncidentDataStatus_Ready, // it's ready - }; - EIncidentDataStatus m_eIncidentDataStatus; - - /// Do we want to show the report UI as soon as the report is ready? - bool m_bReportUIPending; - - void CheckCreateReportReadyNotification( float flMinSecondsSinceLastNotification, bool bInGame, float flLifetime ); - - /// Time when we last pestered them about filing their report - double m_timeLastReportReadyNotification; - - /// Address of the lasts server we connected to - netadr_t m_adrCurrentServer; - CSteamID m_steamIDCurrentServer; - -}; - -/// Pointer to the app-specific instance. This pointer mght be NULL! Your -/// app should define set this pointer if it uses the system -extern CAbuseReportManager *g_AbuseReportMgr; - -#endif // ABUSE_REPORT_H diff --git a/game/client/abuse_report_ui.cpp b/game/client/abuse_report_ui.cpp deleted file mode 100644 index 0d1ab592..00000000 --- a/game/client/abuse_report_ui.cpp +++ /dev/null @@ -1,949 +0,0 @@ -//========= Copyright Valve Corporation, All rights reserved. ============// -// -// Purpose: Generic in-game abuse reporting -// -// $NoKeywords: $ -//=============================================================================// - -#include "cbase.h" -#include "abuse_report_ui.h" -#include "econ/econ_controls.h" -#include "ienginevgui.h" -#include "vgui/ISurface.h" -#include -#include -#include -#include "vgui_bitmappanel.h" -#include "vgui_avatarimage.h" -#include "gc_clientsystem.h" -#include "econ/tool_items/tool_items.h" -#include "econ/econ_gcmessages.h" -#include "econ/confirm_dialog.h" -#include "tool_items/custom_texture_cache.h" - -vgui::DHANDLE g_AbuseReportDlg; - -CAbuseReportDlg::CAbuseReportDlg( vgui::Panel *parent, AbuseIncidentData_t *pIncidentData ) -: EditablePanel( parent, "AbuseReportSubmitDialog" ) -, m_pSubmitButton( NULL ) -, m_pScreenShot( NULL ) -, m_pScreenShotAttachCheckButton( NULL ) -, m_pOffensiveImage( NULL ) -, m_pDescriptionTextEntry( NULL ) -, m_pPlayerLabel( NULL ) -, m_pPlayerRadio( NULL ) -, m_pGameServerRadio( NULL ) -, m_pPlayerCombo( NULL ) -, m_pAbuseContentLabel( NULL ) -, m_pAbuseContentCombo( NULL ) -, m_pAbuseTypeLabel( NULL ) -, m_pAbuseTypeCombo( NULL ) -, m_pScreenShotBitmap( NULL ) -, m_pAvatarImage( NULL ) -, m_pNoAvatarLabel( NULL ) -, m_pCustomTextureImagePanel( NULL ) -, m_pNoCustomTexturesLabel( NULL ) -, m_pCustomTextureNextButton( NULL ) -, m_pCustomTexturePrevButton( NULL ) -, m_iUserImageIndex( 0 ) -, m_pIncidentData( pIncidentData ) -{ - vgui::HScheme scheme = vgui::scheme()->LoadSchemeFromFileEx( enginevgui->GetPanel( PANEL_CLIENTDLL ), "resource/ClientScheme.res", "ClientScheme" ); - SetScheme(scheme); - SetProportional( true ); - //m_pContainer = new vgui::EditablePanel( this, "Container" ); - - Assert( g_AbuseReportDlg.Get() == NULL ); - g_AbuseReportDlg.Set( this ); - - engine->ExecuteClientCmd("gameui_preventescape"); -} - -CAbuseReportDlg::~CAbuseReportDlg() -{ - Assert( g_AbuseReportDlg.Get() == this ); - if ( g_AbuseReportDlg.Get() == this ) - { - engine->ExecuteClientCmd("gameui_allowescape"); - g_AbuseReportDlg = NULL; - } -} - -void CAbuseReportDlg::OnCommand( const char *command ) -{ - if ( !Q_stricmp( command, "cancel" ) ) - { - Close(); - return; - } - if ( !Q_stricmp( command, "discard" ) ) - { - Close(); - g_AbuseReportMgr->DestroyIncidentData(); - return; - } - if ( !Q_stricmp( command, "submit" ) ) - { - OnSubmitReport(); - return; - } - if ( !Q_stricmp( command, "nextcustomtexture" ) ) - { - ++m_iUserImageIndex; - UpdateCustomTextures(); - return; - } - - if ( !Q_stricmp( command, "prevcustomtexture" ) ) - { - --m_iUserImageIndex; - UpdateCustomTextures(); - return; - } - -} - -void CAbuseReportDlg::MakeModal() -{ - TFModalStack()->PushModal( this ); - MakePopup(); - MoveToFront(); - SetKeyBoardInputEnabled( true ); - SetMouseInputEnabled( true ); - - // !KLUDGE! Initially set the dialog to be hidden, so we can take a screenshot! - SetEnabled( m_pIncidentData != NULL ); - //SetVisible( m_pIncidentData != NULL ); -} - -void CAbuseReportDlg::Close() -{ - TFModalStack()->PopModal( this ); - SetVisible( false ); - MarkForDeletion(); -} - -const char *CAbuseReportDlg::GetResFilename() -{ - return "Resource/UI/AbuseReportSubmitDialog.res"; - //return "Resource/UI/QuickplayDialog.res"; -} - -void CAbuseReportDlg::PerformLayout() -{ - BaseClass::PerformLayout(); - - // Center it, keeping requested size - int x, y, ww, wt, wide, tall; - vgui::surface()->GetWorkspaceBounds( x, y, ww, wt ); - GetSize(wide, tall); - SetPos(x + ((ww - wide) / 2), y + ((wt - tall) / 2)); - - // @todo setup -} - -class CCustomTextureImagePanel : public vgui::Panel -{ -public: - CCustomTextureImagePanel( Panel *parent, const char *panelName ) : vgui::Panel( parent, panelName ) - { - m_ugcHandle = 0; - } - - uint64 m_ugcHandle; - - virtual void Paint() - { - if ( m_ugcHandle == 0 ) - { - return; - } - int iTextureHandle = GetCustomTextureGuiHandle( m_ugcHandle ); - if ( iTextureHandle <= 0) - { - return; - } - - vgui::surface()->DrawSetColor(COLOR_WHITE); - vgui::surface()->DrawSetTexture( iTextureHandle ); - int iWide, iTall; - GetSize( iWide, iTall ); - - vgui::Vertex_t verts[4]; - verts[0].Init( Vector2D( 0, 0 ), Vector2D( 0.0f, 0.0f ) ); - verts[1].Init( Vector2D( iWide, 0 ), Vector2D( 1.0f, 0.0f ) ); - verts[2].Init( Vector2D( iWide, iTall ), Vector2D( 1.0f, 1.0f ) ); - verts[3].Init( Vector2D( 0, iTall ), Vector2D( 0.0f, 1.0f ) ); - - vgui::surface()->DrawTexturedPolygon( 4, verts ); - vgui::surface()->DrawSetColor(COLOR_WHITE); - } - -}; - -class CAbuseReportScreenShotPanel : public CBitmapPanel -{ -public: - CAbuseReportScreenShotPanel( CAbuseReportDlg *pDlg, const char *panelName ) - : CBitmapPanel( pDlg, panelName ) - , m_pDlg( pDlg ) - {} - - CAbuseReportDlg *m_pDlg; - - virtual void Paint() - { - CBitmapPanel::Paint(); - - const AbuseIncidentData_t::PlayerData_t *p = m_pDlg->GetAccusedPlayerPtr(); - if ( p == NULL || !p->m_bRenderBoundsValid ) - { - return; - } - int w, t; - GetSize( w, t ); - - int x0 = int( p->m_screenBoundsMin.x * (float)w ); - int y0 = int( p->m_screenBoundsMin.y * (float)t ); - int x1 = int( p->m_screenBoundsMax.x * (float)w ); - int y1 = int( p->m_screenBoundsMax.y * (float)t ); - - vgui::surface()->DrawSetColor( Color(200, 10, 10, 200 ) ); - vgui::surface()->DrawOutlinedRect( x0, y0, x1, y1 ); - vgui::surface()->DrawSetColor( COLOR_WHITE ); - } -}; - -void CAbuseReportDlg::ApplySchemeSettings( vgui::IScheme *pScheme ) -{ - EditablePanel::ApplySchemeSettings( pScheme ); - - m_pScreenShotBitmap = new CAbuseReportScreenShotPanel( this, "ScreenShotBitmap" ); - m_pCustomTextureImagePanel = new CCustomTextureImagePanel( this, "CustomTextureImage" ); - - LoadControlSettings( GetResFilename() ); - - m_pPlayerRadio = dynamic_cast(FindChildByName( "PlayerRadio", true )); - Assert( m_pPlayerRadio ); - if ( m_pPlayerRadio ) - { - m_pPlayerRadio->SetVisible( m_pIncidentData->m_bCanReportGameServer ); - } - - m_pGameServerRadio = dynamic_cast(FindChildByName( "GameServerRadio", true )); - Assert( m_pGameServerRadio ); - if ( m_pGameServerRadio ) - { - m_pGameServerRadio->SetVisible( m_pIncidentData->m_bCanReportGameServer ); - } - - m_pPlayerLabel = FindChildByName( "PlayerLabel", true ); - Assert( m_pPlayerLabel ); - - m_pScreenShotAttachCheckButton = dynamic_cast(FindChildByName( "ScreenShotAttachCheckButton", true )); - Assert( m_pScreenShotAttachCheckButton ); - if ( m_pScreenShotAttachCheckButton ) - { - m_pScreenShotAttachCheckButton->SetSelected( true ); - } - - m_pSubmitButton = dynamic_cast(FindChildByName( "SubmitButton", true )); - Assert( m_pSubmitButton ); - - m_pDescriptionTextEntry = dynamic_cast(FindChildByName( "DescriptionTextEntry", true )); - Assert( m_pDescriptionTextEntry ); - if ( m_pDescriptionTextEntry ) - { - m_pDescriptionTextEntry->SetMultiline( true ); - } - - m_pAvatarImage = dynamic_cast(FindChildByName( "AvatarImage", true )); - Assert( m_pAvatarImage ); - - m_pNoAvatarLabel = FindChildByName( "NoAvatarLabel", true ); - Assert( m_pNoAvatarLabel ); - - m_pNoCustomTexturesLabel = FindChildByName( "NoCustomTexturesLabel", true ); - Assert( m_pNoCustomTexturesLabel ); - - m_pCustomTextureNextButton = dynamic_cast(FindChildByName( "CustomTextureNextButton", true )); - Assert( m_pCustomTextureNextButton ); - - m_pCustomTexturePrevButton = dynamic_cast(FindChildByName( "CustomTexturePrevButton", true )); - Assert( m_pCustomTexturePrevButton ); - - m_pPlayerCombo = dynamic_cast(FindChildByName( "PlayerComboBox", true )); - Assert( m_pPlayerCombo ); - - m_pAbuseContentLabel = FindChildByName( "AbuseContentLabel", true ); - Assert( m_pAbuseContentLabel ); - - m_pAbuseContentCombo = dynamic_cast(FindChildByName( "AbuseContentComboBox", true )); - Assert( m_pAbuseContentCombo ); - if ( m_pAbuseContentCombo ) - { - m_pAbuseContentCombo->AddItem( "#AbuseReport_SelectOne", new KeyValues( "AbuseContent", "code", k_EAbuseReportContentNoSelection ) ); - m_pAbuseContentCombo->AddItem( "#AbuseReport_ContentAvatarImage", new KeyValues( "AbuseContent", "code", k_EAbuseReportContentAvatarImage ) ); - m_pAbuseContentCombo->AddItem( "#AbuseReport_ContentPlayerName", new KeyValues( "AbuseContent", "code", k_EAbuseReportContentPersonaName ) ); - m_pAbuseContentCombo->AddItem( "#AbuseReport_ContentItemDecal", new KeyValues( "AbuseContent", "code", k_EAbuseReportContentUGCImage ) ); - m_pAbuseContentCombo->AddItem( "#AbuseReport_ContentChatText", new KeyValues( "AbuseContent", "code", k_EAbuseReportContentComments ) ); - m_pAbuseContentCombo->AddItem( "#AbuseReport_ContentCheating", new KeyValues( "AbuseContent", "code", k_EAbuseReportContentCheating ) ); - m_pAbuseContentCombo->AddItem( "#AbuseReport_ContentOther", new KeyValues( "AbuseContent", "code", k_EAbuseReportContentUnspecified ) ); - m_pAbuseContentCombo->SilentActivateItemByRow( 0 ); - m_pAbuseContentCombo->SetNumberOfEditLines( m_pAbuseContentCombo->GetItemCount() ); - } - - m_pAbuseTypeLabel = FindChildByName( "AbuseTypeLabel", true ); - Assert( m_pAbuseTypeLabel ); - - m_pAbuseTypeCombo = dynamic_cast(FindChildByName( "AbuseTypeComboBox", true )); - Assert( m_pAbuseTypeCombo ); - - Assert( m_pScreenShotBitmap ); - if ( m_pScreenShotBitmap && m_pIncidentData->m_bitmapScreenshot.IsValid() ) - { - m_pScreenShotBitmap->SetBitmap( m_pIncidentData->m_bitmapScreenshot ); - } - - PopulatePlayerList(); - SetIsAccusingGameServer( false ); - - SetEnabled( true ); - SetVisible( true ); -} - -bool CAbuseReportDlg::IsAccusingGameServer() -{ - return m_pIncidentData && m_pIncidentData->m_bCanReportGameServer && m_pGameServerRadio && m_pGameServerRadio->IsSelected(); -} - -EAbuseReportContentType CAbuseReportDlg::GetAbuseContentType() -{ - if ( m_pAbuseContentCombo == NULL || IsAccusingGameServer() ) - { - Assert( m_pAbuseContentCombo ); - return k_EAbuseReportContentNoSelection; - } - KeyValues *pUserData = m_pAbuseContentCombo->GetActiveItemUserData(); - if ( pUserData == NULL ) - { - return k_EAbuseReportContentNoSelection; - } - return (EAbuseReportContentType)pUserData->GetInt( "code", k_EAbuseReportContentNoSelection ); -} - -EAbuseReportType CAbuseReportDlg::GetAbuseType() -{ - if ( m_pAbuseTypeCombo == NULL || IsAccusingGameServer() ) - { - Assert( m_pAbuseTypeCombo ); - return k_EAbuseReportTypeNoSelection; - } - KeyValues *pUserData = m_pAbuseTypeCombo->GetActiveItemUserData(); - if ( pUserData == NULL ) - { - return k_EAbuseReportTypeNoSelection; - } - return (EAbuseReportType)pUserData->GetInt( "code", k_EAbuseReportTypeNoSelection ); -} - -CUtlString CAbuseReportDlg::GetAbuseDescription() -{ - char buf[ 1024 ] = ""; - if ( m_pDescriptionTextEntry ) - { - m_pDescriptionTextEntry->GetText( buf, ARRAYSIZE(buf) ); - } - - return CUtlString( buf ); -} - -int CAbuseReportDlg::GetAccusedPlayerIndex() -{ - // If accusing a game server, then there's no player - if ( IsAccusingGameServer() ) - { - return -1; - } - - if ( m_pPlayerCombo == NULL ) - { - Assert( m_pPlayerCombo ); - return -1; - } - - // Item 0 is the "