[
  {
    "path": ".gitignore",
    "content": "*.iml\n.gradle\n/local.properties\n.idea/\n.DS_Store\n/build\n/captures\n.externalNativeBuild\n.cxx\nlocal.properties\n"
  },
  {
    "path": "README.md",
    "content": "# MyMp3Convert\nmp3Convert\n一个mp3转换库，基于lame3来实现\n\n模块简介：\n================================================\n主要实现了wav格式向mp3格式的转投；  \n只需要关注3个方法就好；  \n为了项目简单直观实用，节省代码空间，本模块遵循单一职责原则，只做格式转换，把wav格式音频转换成mp3格式\n\n使用场景:\n================================================\n 用于在客户端需要把编辑好的wav转换成mp3格式，这样可以在不过大损失音频效果的同时有效节省空间，通常情况下，10M大小的wav文件通过转换后可以生成1M大小的mp3文件；  \n 比如：用户在客户端录制好pcm音频文件，并由该文件编辑得到了可播放的wav文件，又需要把wav文件上传服务器，或者存在本地，但是wav文件过大，需要占用过大网络，在增加耗电量的同时，也给了服务器带来了压力，这个时候可以把文件转换成mp3格式文件（至于pcm到wav格式的转换，wav文件的编辑、剪切、拼接、混音合成可以使用另一模块来实现 链接：https://github.com/fanyuan/AudioUtil ）\n\n\n 使用：\n ================================================\n只需要调用Mp3ConvertUtilHelper里的3个公开方法即可；   \n使用很简单，只要把本module下载后以Android studio导入工程项目，设为library估其他module依赖就好  \n对于和native c语言的交互已在Mp3ConvertUtil中封装好，采用了外观模式；  \n使用时只需要调用Mp3ConvertUtilHelper类的相3个关公开方法  \n\n=====================华丽丽的分割线========================\n\n3个相关方法如下：\n================================================\n\n    /**\n     * wav转换成mp3\n     * @param wavInPath    需要转换的wav源文件输入路径\n     * @param mp3OutPath   转换完成后的mp3目标文件输出路径\n     */\n    public static void convertmp3(String wavInPath, String mp3OutPath)\n\n    /**\n     * wav转换成mp3\n     * @param wavInPath    需要转换的wav源文件输入路径\n     * @param mp3OutPath   转换完成后的mp3目标文件输出路径\n     * @param callback     转换相关的回调\n     */\n    public static void convertmp3(String wavInPath, String mp3OutPath, Mp3ConvertUtil.ConvertListener callback)}\n\n    /**\n     * 获取转换进度\n     * @param outPath  在多个任务并行时以输出路径为token来查询相关转换文件的转换进度\n     * @return\n     */\n    public static int getProgress(String outPath)\n\n =====================华丽丽的分割线==========================\n \n使用示例如下：  \n\n温馨提示：使用时请在子线程中使用，为了演示方便直观就不过多封装了\n\n不带转换回调的使用示例：\n================================================\nnew Thread(){\n            @Override\n            public void run() {\n\n                String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + \"temp/姑娘我爱你convert.wav\";//\"temp/test123.wav\";\n                String pathTaret = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + \"temp/姑娘我爱你out123.mp3\";\n                Mp3ConvertUtilHelper.convertmp3(path,pathTaret);\n\n            }\n        }.start();\n        \n不带回调的获取转换进度的方式： \n================================================\nString pathTaret = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + \"temp/姑娘我爱你out123.mp3\";\n\nint progress = Mp3ConvertUtilHelper.getProgress(pathTaret);\n\n带转换回调的使用示例：\n================================================\nnew Thread(){\n            @Override\n            public void run() {\n\n                String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + \"temp/out测试.wav\";//\"temp/test123.wav\";\n                String pathTaret = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + \"temp/out测试789.mp3\";\n                Mp3ConvertUtilHelper.convertmp3(path, pathTaret, new Mp3ConvertUtil.ConvertListener() {\n                    @Override\n                    public void notifyConvertProgress(int progress) {\n                        Log.d(\"ddebug\",\"convertByHelper02 --- notifyConvertProgress = \" + progress);\n                    }\n\n                    @Override\n                    public void convertFinish() {\n                        Log.d(\"ddebug\",\"convertByHelper02 --- convertFinish\");\n                    }\n\n                    @Override\n                    public void convertError(String errorMsg) {\n                        Log.d(\"ddebug\",\"convertByHelper02 --- convertError --- \" + errorMsg);\n                    }\n                });\n                \n\n            }\n\n        }.start();\n        \n        \n\n简单实用^_^\n\n"
  },
  {
    "path": "app/.gitignore",
    "content": "/build"
  },
  {
    "path": "app/CMakeLists.txt",
    "content": "\n#指定CMake构建本地库时所需的最小版本\ncmake_minimum_required(VERSION 3.4.1)\n\n#该变量为真时会创建完整版本的Makefile\nset(CMAKE_VERBOSE_MAKEFILE on)\nset(LAME_LIBMP3_DIR ${CMAKE_SOURCE_DIR}/src/main/jni/libmp3lame)\nset(CMAKE_CXX_FLAGS \"${CMAKE_CXX_FLAGS} -DLOGTEST\")\ninclude_directories(${CMAKE_SOURCE_DIR}/src/main/jni/libmp3lame)\ninclude_directories(${CMAKE_SOURCE_DIR}/src/main/jni)\n\ninclude_directories(E/work/sdk/ndk-bundle/toolchains/llvm/prebuilt/windows-x86_64/sysroot/usr/include)\nadd_library( # Sets the name of the library. 将资源文件生成动态链接库（so文件）的库名称(文件名称：“lib\" +设置的名称)\n        hello\n\n        # Sets the library as a shared library.\n        SHARED\n\n        # Provides a relative path to your source file(s).资源文件（C或C++）的相对位置\n        src/main/jni/NativeMp3ConvertUtil.cpp\n        src/main/jni/NativeMyTest.cpp)\n# 这里用来添加一个库\nadd_library(# 这里设置so库的名称为native-lib\n        libmp3lame\n        # 这里设置该库为共享\n        SHARED\n        #源码文件\n        ${LAME_LIBMP3_DIR}/bitstream.c\n        ${LAME_LIBMP3_DIR}/encoder.c\n        ${LAME_LIBMP3_DIR}/fft.c\n        ${LAME_LIBMP3_DIR}/gain_analysis.c\n        ${LAME_LIBMP3_DIR}/id3tag.c\n        ${LAME_LIBMP3_DIR}/lame.c\n        ${LAME_LIBMP3_DIR}/mpglib_interface.c\n        ${LAME_LIBMP3_DIR}/newmdct.c\n        ${LAME_LIBMP3_DIR}/presets.c\n        ${LAME_LIBMP3_DIR}/psymodel.c\n        ${LAME_LIBMP3_DIR}/quantize.c\n        ${LAME_LIBMP3_DIR}/quantize_pvt.c\n        ${LAME_LIBMP3_DIR}/reservoir.c\n        ${LAME_LIBMP3_DIR}/set_get.c\n        ${LAME_LIBMP3_DIR}/tables.c\n        ${LAME_LIBMP3_DIR}/takehiro.c\n        ${LAME_LIBMP3_DIR}/util.c\n        ${LAME_LIBMP3_DIR}/vbrquantize.c\n        ${LAME_LIBMP3_DIR}/VbrTag.c\n        ${LAME_LIBMP3_DIR}/version.c\n        )\nfind_library( # Sets the name of the path variable.\n        log-lib\n\n        # Specifies the name of the NDK library that\n        # you want CMake to locate.\n        log )\n\ntarget_link_libraries( # Specifies the target library.将所有的add_library中的库链接起来，有多少个add_library成的库就将其添加到这里\n        hello  #这个和add_library中的指定的so库名称一致\n        libmp3lame\n        # Links the target library to the log library\n        # included in the NDK.\n        ${log-lib} )\n"
  },
  {
    "path": "app/build.gradle",
    "content": "//plugins {\n//    id 'com.android.application'\n//}\nif(isAppLibrary.toBoolean()){\n    apply plugin: 'com.android.library'\n}else {\n    apply plugin: 'com.android.application'\n}\napply plugin: 'kotlin-android'\nandroid {\n    externalNativeBuild { cmake { version \"3.10.2\" } }\n    compileSdkVersion 30\n    buildToolsVersion \"30.0.3\"\n\n    defaultConfig {\n\n        if(!isAppLibrary.toBoolean()){\n            applicationId \"com.convert.mymp3convert\"\n        }\n\n        minSdkVersion 18\n        targetSdkVersion 30\n        versionCode 1\n        versionName \"1.0\"\n\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n        externalNativeBuild {\n            cmake {\n                // 指定一些编译选项\n                cppFlags \"-std=c++11 -frtti -fexceptions\"\n                cFlags \"-DSTDC_HEADERS\"\n                abiFilters 'armeabi-v7a','arm64-v8a','x86'//'armeabi',\n            }\n        }\n        ndk{\n            //moduleName\"hello\"       //生成的so文件名字，调用C程序的代码中会用到该名字\n            abiFilters 'armeabi-v7a','arm64-v8a' , 'x86'//,'arm64-v8a',  'x86_64'//'armeabi',\n        }\n        signingConfigs {\n            release {\n                storeFile file(\"key02.keystore\")\n                storePassword \"1qazxsw2\"\n                keyAlias \"key02\"\n                keyPassword \"1qazxsw2\"\n                v1SigningEnabled true\n                v2SigningEnabled true\n            }\n        }\n    }\n    externalNativeBuild {\n        cmake {\n            path \"CMakeLists.txt\"\n        }\n    }\n    signingConfigs {\n        dev {\n            storeFile file('E:\\\\work\\\\keyStore\\\\demo\\\\key02.keystore')\n            storePassword '1qazxsw2'\n            keyAlias 'key02'\n            keyPassword '1qazxsw2'\n        }\n    }\n    sourceSets{\n        main{\n            if(isAppLibrary.toBoolean()){\n                manifest.srcFile 'src/main/library/AndroidManifest.xml'\n            }else {\n                manifest.srcFile 'src/main/AndroidManifest.xml'\n            }\n\n        }\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n            jniDebuggable true\n            signingConfig signingConfigs.release\n        }\n        dev {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n            jniDebuggable true\n            debuggable true\n            signingConfig signingConfigs.release\n        }\n    }\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n}\n\ndependencies {\n\n    implementation 'androidx.appcompat:appcompat:1.2.0'\n    implementation 'com.google.android.material:material:1.2.1'\n    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'\n    implementation \"org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version\"\n    testImplementation 'junit:junit:4.+'\n    androidTestImplementation 'androidx.test.ext:junit:1.1.2'\n    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'\n}"
  },
  {
    "path": "app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile"
  },
  {
    "path": "app/src/androidTest/java/com/convert/mymp3convert/ExampleInstrumentedTest.java",
    "content": "package com.convert.mymp3convert;\n\nimport android.content.Context;\n\nimport androidx.test.platform.app.InstrumentationRegistry;\nimport androidx.test.ext.junit.runners.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();\n        assertEquals(\"com.convert.mymp3convert\", appContext.getPackageName());\n    }\n}"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.convert.mymp3convert\">\n\n    <uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\" />\n    <uses-permission android:name=\"android.permission.RECORD_AUDIO\" />\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:requestLegacyExternalStorage=\"true\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/Theme.MyMp3Convert\">\n        <activity android:name=\".MainActivity2\"></activity>\n        <activity android:name=\".MainActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "app/src/main/java/com/convert/mymp3convert/MainActivity.java",
    "content": "package com.convert.mymp3convert;\n\nimport android.Manifest;\nimport android.os.Bundle;\nimport android.os.Environment;\nimport android.util.Log;\nimport android.view.View;\nimport android.widget.TextView;\n\nimport androidx.appcompat.app.AppCompatActivity;\nimport androidx.core.app.ActivityCompat;\n\nimport java.io.File;\n\npublic class MainActivity extends AppCompatActivity {\n\n    TextView tv;\n    String [] perms = {Manifest.permission.MODIFY_AUDIO_SETTINGS,Manifest.permission.RECORD_AUDIO,\n            Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE};\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_main);\n        tv = findViewById(R.id.tv);\n        String msg = Mp3ConvertUtil.hello(\"test\");\n        tv.setText(msg);\n        Log.d(\"ddebug\",\"hello jni = \" + msg);\n\n        ActivityCompat.requestPermissions(this, perms, 123);\n    }\n    public void test(View v){\n        String str = MyTest.test();\n        tv.append(\"\\n\"+str);\n        Log.d(\"ddebug\",\"test str = \" + \"str\" + \"----\" + Mp3ConvertUtil.getLameVer());\n        //Mp3ConvertUtil.convertmp3(\"test.wav\",\"demo.mp3\");\n    }\n    public void convert(View v){\n        String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + \"temp/out.wav\";//\"temp/test123.wav\";\n        String pathTaret = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + \"temp/out123.mp3\";\n        Mp3ConvertUtil.convertmp3(path,pathTaret);\n    }\n    public void convertByHelper01(View v){\n//        String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + \"temp/out.wav\";//\"temp/test123.wav\";\n//        String pathTaret = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + \"temp/out456.mp3\";\n//        Mp3ConvertUtilHelper.convertmp3(path,pathTaret);\n\n        new Thread(){\n            @Override\n            public void run() {\n\n                String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + \"temp/姑娘我爱你convert.wav\";//\"temp/test123.wav\";\n                String pathTaret = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + \"temp/姑娘我爱你out123.mp3\";\n                Mp3ConvertUtilHelper.convertmp3(path,pathTaret);\n\n            }\n        }.start();\n    }\n    public void convertByHelper02(View v){\n        new Thread(){\n            @Override\n            public void run() {\n\n                String path = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + \"temp/out测试.wav\";//\"temp/test123.wav\";\n                String pathTaret = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + \"temp/out测试789.mp3\";\n                Mp3ConvertUtilHelper.convertmp3(path, pathTaret, new Mp3ConvertUtil.ConvertListener() {\n                    @Override\n                    public void notifyConvertProgress(int progress) {\n                        Log.d(\"ddebug\",\"convertByHelper02 --- notifyConvertProgress = \" + progress);\n                    }\n\n                    @Override\n                    public void convertFinish() {\n                        Log.d(\"ddebug\",\"convertByHelper02 --- convertFinish\");\n                    }\n\n                    @Override\n                    public void convertError(String errorMsg) {\n                        Log.d(\"ddebug\",\"convertByHelper02 --- convertError --- \" + errorMsg);\n                    }\n                });\n\n            }\n        }.start();\n\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/convert/mymp3convert/MainActivity2.kt",
    "content": "package com.convert.mymp3convert\n\nimport androidx.appcompat.app.AppCompatActivity\nimport android.os.Bundle\n\nclass MainActivity2 : AppCompatActivity() {\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContentView(R.layout.activity_main2)\n    }\n}"
  },
  {
    "path": "app/src/main/java/com/convert/mymp3convert/Mp3ConvertUtil.java",
    "content": "package com.convert.mymp3convert;\n\nimport android.util.Log;\n\nimport java.util.concurrent.ConcurrentHashMap;\n\npublic class Mp3ConvertUtil {\n    static {\n        System.loadLibrary(\"hello\");\n        System.loadLibrary(\"libmp3lame\");\n    }\n\n    public static native String hello(String msg);\n    /**\n     * 获取LAME的版本信息\n     *\n     * @return\n     */\n    public static native String getLameVer();\n    /**\n     * wav转换成mp3的本地方法\n     *\n     * @param wav\n     * @param mp3\n     */\n    public static native void convertmp3(String wav, String mp3);\n\n    /**\n     * 转换接口回调\n     */\n    public interface ConvertListener{\n        public void notifyConvertProgress(int progress);\n        /**\n         * 转换完成回调\n         */\n        public  void convertFinish();\n\n        /**\n         * 转换完成回调\n         * @param errorMsg\n         */\n        public  void convertError(String errorMsg);\n    }\n\n    /**\n     * 提供的一个空实现\n     */\n    public static class SimpleConvertListener implements ConvertListener{\n\n        @Override\n        public void notifyConvertProgress(int progress) {\n\n        }\n\n        @Override\n        public void convertFinish() {\n\n        }\n\n        @Override\n        public void convertError(String errorMsg) {\n\n        }\n    }\n    /**\n     * 保存进度的地方\n     */\n    static ConcurrentHashMap<String,ConvertListener> mConvertCallbacks;\n    /**\n     * 保存进度的地方\n     */\n    static ConcurrentHashMap<String,Integer> mProgresses;\n\n\n    /**\n     * 注册转换回调类\n     * @param mp3TargetPath\n     * @param callback\n     */\n    protected static void registerCallback(String mp3TargetPath,ConvertListener callback){\n        if(mConvertCallbacks == null){\n            mConvertCallbacks = new ConcurrentHashMap<String, ConvertListener>();\n        }\n        mConvertCallbacks.put(mp3TargetPath,callback);\n    }\n\n    /**\n     * 移除转换回调类\n     * @param mp3TargetPath\n     */\n    private static void removeCallback(String mp3TargetPath){\n        if(mConvertCallbacks == null){\n            return;\n        }\n        if(mConvertCallbacks.containsKey(mp3TargetPath)){\n            mConvertCallbacks.remove(mp3TargetPath);\n        }\n    }\n    /**\n     * 设置进度的方法\n     * @param outPath\n     */\n    private static void setProgress(String outPath,int progress){\n        if(mProgresses == null){\n            mProgresses = new ConcurrentHashMap<String, Integer>();\n        }\n        mProgresses.put(outPath,progress);\n        Log.d(\"ddebug\",\"---setProgress---\" + outPath + \"=\" + progress);\n    }\n    /**\n     * 获取进度的方法\n     * @param outPath\n     * @return\n     */\n    protected static int getProgress(String outPath){\n        if(mProgresses == null){\n            return -1;\n        }\n        if(!mProgresses.containsKey(outPath)){\n            return -1;\n        }\n        int progress = mProgresses.get(outPath);\n        Log.d(\"ddebug\",\"---getProgress---\" + outPath + \"=\" + progress);\n        return progress;\n    }\n\n    /**\n     * 移除相关进度条目的方法\n     *\n     * @param outPath\n     */\n    private static void removeProgress(String outPath){\n        if(mProgresses == null){\n            return;\n        }\n        mProgresses.remove(outPath);\n        Log.d(\"ddebug\",\"---removeProgress---\" + outPath);\n    }\n    /**\n     * 日志打印方法，提供给C语言调用\n     *\n     * @param\n     */\n    public static void nativeLog(String logTag,String logMsg) {\n        Log.d(logTag,\"java nativeLog:\" + logMsg);\n    }\n    /**\n     * 设置进度条的进度，提供给C语言调用\n     *\n     * @param progress\n     */\n    public static void setConvertProgress(int progress,String outPath) {\n        setProgress(outPath,progress);\n        if(mConvertCallbacks == null){\n            mConvertCallbacks = new ConcurrentHashMap<String, ConvertListener>();\n        }\n        if(mConvertCallbacks.containsKey(outPath)){\n            mConvertCallbacks.get(outPath).notifyConvertProgress(progress);\n        }\n        Log.d(\"ddebug\",\"转换进度为：\"+ progress);\n    }\n    /**\n     * 转换完成回调，提供给C语言调用\n     *\n     * @param outPath\n     */\n    public static void convertFinish(String outPath) {\n        removeProgress(outPath);\n        if(mConvertCallbacks == null){\n            return;\n        }\n        if(mConvertCallbacks.containsKey(outPath)){\n            mConvertCallbacks.get(outPath).convertFinish();\n            removeCallback(outPath);\n        }\n        Log.d(\"ddebug\",\"转换完成  convertFinish:\"+ outPath);\n    }\n    /**\n     * 转换完成回调，提供给C语言调用\n     *\n     * @param outPath\n     */\n    public static void convertError(String errorMsg,String outPath) {\n        removeProgress(outPath);\n\n        if(mConvertCallbacks == null){\n            return;\n        }\n        if(mConvertCallbacks.containsKey(outPath)){\n            mConvertCallbacks.get(outPath).convertError(errorMsg);\n            removeCallback(outPath);\n        }\n        Log.d(\"ddebug\",\"java convertError:\" + errorMsg + \" --- \" + outPath);\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/convert/mymp3convert/Mp3ConvertUtilHelper.java",
    "content": "package com.convert.mymp3convert;\n\npublic class Mp3ConvertUtilHelper {\n    /**\n     * 获取版本号\n     * @return\n     */\n    public static String getVer(){\n        return Mp3ConvertUtil.getLameVer();\n    }\n\n    /**\n     * wav转换成mp3\n     * @param wavInPath   需要转换的wav源文件输入路径\n     * @param mp3OutPath  转换完成后的mp3目标文件输出路径\n     */\n    public static void convertmp3(String wavInPath, String mp3OutPath){\n        Mp3ConvertUtil.convertmp3(wavInPath,mp3OutPath);\n    }\n\n    /**\n     * wav转换成mp3\n     * @param wavInPath   需要转换的wav源文件输入路径\n     * @param mp3OutPath  转换完成后的mp3目标文件输出路径\n     * @param callback    转换相关的回调\n     */\n    public static void convertmp3(String wavInPath, String mp3OutPath, Mp3ConvertUtil.ConvertListener callback){\n        Mp3ConvertUtil.registerCallback(mp3OutPath,callback);\n        Mp3ConvertUtil.convertmp3(wavInPath,mp3OutPath);\n    }\n    /**\n     * 获取转换进度\n     * @param outPath  在多个任务并行时以输出路径为token来查询相关转换文件的转换进度\n     * @return\n     */\n    public static int getProgress(String outPath){\n        return Mp3ConvertUtil.getProgress(outPath);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/convert/mymp3convert/MyTest.java",
    "content": "package com.convert.mymp3convert;\n\npublic class MyTest {\n    public static native String test();\n}\n"
  },
  {
    "path": "app/src/main/java/com/convert/mymp3convert/test/Demo.java",
    "content": "package com.convert.mymp3convert.test;\n\nimport com.convert.mymp3convert.Mp3ConvertUtil;\n\npublic class Demo {\n    private void test(){\n        //Mp3ConvertUtil.registerCallback(\"\",null);\n    }\n}\n"
  },
  {
    "path": "app/src/main/jni/NativeMp3ConvertUtil.cpp",
    "content": "//\n// Created by shaomingfa on 2021/1/14.\n//\n\n#include <string>\n#include \"libmp3lame/lame.h\"\n\n#include <jni.h>\n\n#include<stdio.h>\n#include<malloc.h>\n#include<lame.h>\n#include<android/log.h>\n#include \"libmp3lame/lame.h\"\n#include <unistd.h>\n#include <fcntl.h>\n#include <sys/stat.h>\n\n\n#include \"NativeMp3ConvertUtil.h\"\n#include \"com_convert_mymp3convert_Mp3ConvertUtil.h\"\n#define LOG_TAG \"System.out.c\"\n/**\n * 日志打印tag\n */\n#define CONVERT_LOG_TAG \"nativeTag\"\n#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)\n#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)\n\n\n\n#ifndef com_convert_mymp3convert_Mp3ConvertUtil\n#define com_convert_mymp3convert_Mp3ConvertUtil\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/**\n* 返回值 char* 这个代表char数组的首地址\n*  Jstring2CStr 把java中的jstring的类型转化成一个c语言中的char 字符串\n*/\nchar* Jstring2CStr(JNIEnv *env, jstring jstr) {\n    char* rtn = NULL;\n    jclass clsstring = (*env).FindClass( \"java/lang/String\"); //String\n    jstring strencode = (*env).NewStringUTF( \"GB2312\"); // 得到一个java字符串 \"GB2312\"\n    jmethodID mid = (*env).GetMethodID(clsstring, \"getBytes\",\n                                       \"(Ljava/lang/String;)[B\"); //[ String.getBytes(\"gb2312\");\n    jbyteArray barr = (jbyteArray)(*env).CallObjectMethod(jstr, mid,\n                                                          strencode); // String .getByte(\"GB2312\");\n    jsize alen = (*env).GetArrayLength( barr); // byte数组的长度\n    jbyte* ba = (*env).GetByteArrayElements( barr, JNI_FALSE);\n    if (alen > 0) {\n        rtn = (char*) malloc(alen + 1); //\"\\0\"\n        memcpy(rtn, ba, alen);\n        rtn[alen] = 0;\n    }\n    (*env).ReleaseByteArrayElements(barr, ba, 0); //\n    (*env).DeleteLocalRef(strencode);\n    return rtn;\n}\n/**==============================================================================================================================================*/\n/**\n * 调用java代码 更新程序的进度条\n */\nvoid publishJavaProgress(JNIEnv * env, jobject obj, jint progress,jstring outPath) {\n    //1.找到java的LameUtils的class          com/example/myjnidemo/\n    jclass clazz = (*env).FindClass(\"com/convert/mymp3convert/Mp3ConvertUtil\");\n    if (clazz == 0) {\n        LOGI(\"can't find clazz\");\n        return;\n    }\n    LOGI(\" convert progress %d\" , progress);\n\n    //2 找到class 里面的方法定义\n\n    jmethodID methodid = (*env).GetStaticMethodID(clazz,\"setConvertProgress\",\"(ILjava/lang/String;)V\");//jmethodID methodid = (*env).GetMethodID(clazz, \"setConvertProgress\",\"(I)V\");\n    if (methodid == 0) {\n        LOGI(\"can't find methodid\");\n        return;\n    }\n    LOGI(\" find methodid\");\n\n    //3 .调用方法\n    (*env).CallStaticVoidMethod(clazz, methodid, progress,outPath);//(*env).CallVoidMethod(obj, methodid, progress);\n    //env -> CallVoidMethod(obj,methodid,progress);\n    env->DeleteLocalRef(clazz);\n    //env->DeleteLocalRef(methodid);\n}\n/**\n * 调用java代码 更新程序的进度条\n */\nvoid convertFinish(JNIEnv * env, jstring mp3Path) {\n    //1.找到java的LameUtils的class          com/example/myjnidemo/\n    jclass clazz = (*env).FindClass(\"com/convert/mymp3convert/Mp3ConvertUtil\");\n    if (clazz == 0) {\n        LOGI(\"can't find clazz\");\n        return;\n    }\n    const char *c = env->GetStringUTFChars(mp3Path, JNI_FALSE);\n    LOGI(\" convert finished %s\" , c);\n    env->ReleaseStringUTFChars(mp3Path,c);\n\n    //2 找到class 里面的方法定义\n    jmethodID methodid = (*env).GetStaticMethodID(clazz,\"convertFinish\",\"(Ljava/lang/String;)V\");\n    if (methodid == 0) {\n        LOGI(\"can't find methodid\");\n        return;\n    }\n    LOGI(\" find convertFinish methodid\");\n\n    //3 .调用方法\n    env -> CallStaticVoidMethod(clazz,methodid,mp3Path);\n    env->DeleteLocalRef(clazz);\n}\n/**\n * 调用java代码 转换失败时调用\n */\nvoid convertError(JNIEnv * env,jstring msg,jstring mp3Path) {\n    //1.找到java的LameUtils的class          com/example/myjnidemo/\n    jclass clazz = (*env).FindClass(\"com/convert/mymp3convert/Mp3ConvertUtil\");\n    if (clazz == 0) {\n        LOGI(\"can't find clazz\");\n        return;\n    }\n\n    const char *c = (*env).GetStringUTFChars(mp3Path, JNI_FALSE);\n    LOGI(\" convert error %s\" , c);\n    (*env).ReleaseStringUTFChars(mp3Path,c);\n\n    //2 找到class 里面的方法定义\n\n    jmethodID methodid = (*env).GetStaticMethodID(clazz,\"convertError\",\n                                                  \"(Ljava/lang/String;Ljava/lang/String;)V\");\n    if (methodid == 0) {\n        LOGI(\"can't find methodid\");\n        return;\n    }\n    LOGI(\" find methodid\");\n\n    //3 .调用方法\n    env -> CallStaticVoidMethod(clazz,methodid,msg,mp3Path);\n    env->DeleteLocalRef(clazz);\n}\n/**\n * 调用java代码 打印日志时调用\n */\nvoid nativeLog(JNIEnv * env, jstring msg) {\n    //1.找到java的LameUtils的class          com/example/myjnidemo/\n    jclass clazz = (*env).FindClass(\"com/convert/mymp3convert/Mp3ConvertUtil\");\n    if (clazz == 0) {\n        LOGI(\"can't find clazz\");\n        return;\n    }\n    //2 找到class 里面的方法定义\n    jmethodID methodid = (*env).GetStaticMethodID(clazz,\"nativeLog\",\n                                                  \"(Ljava/lang/String;Ljava/lang/String;)V\");\n    if (methodid == 0) {\n        LOGI(\"can't find methodid\");\n        return;\n    }\n    LOGI(\" find methodid\");\n    jstring logTag = env->NewStringUTF(CONVERT_LOG_TAG);\n    //3 .调用方法\n    env -> CallStaticVoidMethod(clazz,methodid,logTag,msg);\n    env->DeleteLocalRef(logTag);\n    env->DeleteLocalRef(clazz);\n}\n/**\n * 字符串拼接\n * @param env\n * @param cstr\n * @param jstr\n * @return\n */\njstring jstrCat(JNIEnv *env,char * cstr,jstring jstr){\n    char *c =(char *)(*env).GetStringUTFChars(jstr,JNI_FALSE);\n    char * bf = new char[strlen(cstr) + strlen(c) +1];\n    memcpy(bf, cstr, strlen(cstr) + 1);\n    strcat(bf, c);\n    jstring  js = env->NewStringUTF(bf);\n    delete [] bf;\n    (*env).ReleaseStringUTFChars(jstr,c);\n    return js;\n}\n/**\n * 获取文件的大小\n * @param filename\n * @return\n */\nlong long file_size(char* filename){\n    struct stat statbuf;\n    stat(filename,&statbuf);\n    return statbuf.st_size;\n}\n/*\n * Class:     com_convert_mymp3convert_Mp3ConvertUtil\n * Method:    hello\n * Signature: (Ljava/lang/String;)Ljava/lang/String;\n */\nJNIEXPORT jstring JNICALL Java_com_convert_mymp3convert_Mp3ConvertUtil_hello\n        (JNIEnv *env, jclass obj, jstring str){\n\n    jstring js = env->NewStringUTF(\"/sd/mp3\");\n    publishJavaProgress(env,obj,123,js);\n    env->DeleteLocalRef(js);\n\n    jstring jstr = env->NewStringUTF(\"/sd/m/mp3\");\n    convertFinish(env,jstr);\n    env->DeleteLocalRef(jstr);\n\n    jstring msg = env->NewStringUTF(\"xxx原因导致了未转换成功\");\n    convertError(env,  msg, msg);\n    env->DeleteLocalRef(msg);\n\n    LOGD(\"lame ver = %s\",get_lame_very_short_version());\n    LOGI(\"convertmp3   %S  ===  %S\",\"wav\",\"mp3\");\n    LOGD(\"CONVERT   %S\",\"test\");\n    return env->NewStringUTF(\"Hello From JNI!\");//\n}\n/*\n * Class:     com_convert_mymp3convert_Mp3ConvertUtil\n * Method:    getLameVer\n * Signature: ()Ljava/lang/String;\n */\nJNIEXPORT jstring JNICALL\nJava_com_convert_mymp3convert_Mp3ConvertUtil_getLameVer(JNIEnv *env, jclass obj) {\n    LOGD(\"CONVERT  123321 测试 S \");\n    LOGD(\"CONVERT  123321 测试 S --- %d\",123);\n    LOGD(\"CONVERT  123321 测试 S --- %s\",\"test\");\n    return (*env).NewStringUTF(get_lame_version());\n}\n//int flag = 0;\n/**\n *wav转换mp3\n * @param env\n * @param obj\n * @param wav\n * @param mp3\n */\n/*\n * Class:     com_convert_mymp3convert_Mp3ConvertUtil\n * Method:    convertmp3\n * Signature: (Ljava/lang/String;Ljava/lang/String;)V\n */\nJNIEXPORT void JNICALL\nJava_com_convert_mymp3convert_Mp3ConvertUtil_convertmp3(JNIEnv *env, jclass obj, jstring wav,jstring mp3) {\n\n    char* cwav = const_cast<char *>(env->GetStringUTFChars(wav, JNI_FALSE));//Jstring2CStr(env,wav) ;\n    char* cmp3= const_cast<char *>(env->GetStringUTFChars(mp3, JNI_FALSE));//Jstring2CStr(env,mp3);\n    LOGI(\"wav = %s\", cwav);\n    LOGI(\"mp3 = %s\", cmp3);\n\n    char buf[2048] = {};\n    sprintf(buf, \"source：%s，target：%s \", cwav,cmp3);\n    LOGD(buf,NULL);\n\n    if(access(cwav,F_OK) == -1){\n        free(cwav);\n        free(cmp3);\n        LOGD(\"转换源文件不存在\");\n        jstring msg = jstrCat(env,\"转换源文件不存在:\",mp3);\n        nativeLog(env, msg);\n        convertError(env,msg,mp3);\n        env->DeleteLocalRef(msg);\n        return;\n    }\n    long long fileSize = file_size(cwav);\n    if (fileSize == 0) {\n        free(cwav);\n        free(cmp3);\n        jstring msg = jstrCat(env,\"转换源文件大小为0:\",mp3);\n        nativeLog(env, msg);\n        convertError(env,msg,mp3);\n        env->DeleteLocalRef(msg);\n        return;\n    }\n    //1.打开 wav,MP3文件\n    FILE* fwav = fopen(cwav,\"rb\");\n    FILE* fmp3 = fopen(cmp3,\"wb\");\n\n    short int wav_buffer[8192*2]= {};\n    unsigned char mp3_buffer[8192] = {};\n\n    //1.初始化lame的编码器\n    lame_t lame =  lame_init();\n    //2. 设置lame mp3编码的采样率\n    lame_set_in_samplerate(lame , 44100);\n    lame_set_num_channels(lame,2);\n    // 3. 设置MP3的编码方式\n    lame_set_VBR(lame, vbr_default);\n    lame_init_params(lame);\n    LOGI(\"lame init finish\");\n\n    int read ; int write; //代表读了多少个次 和写了多少次\n    long long total=0; // 当前读的wav文件的byte数目\n\n    LOGD(\"FILE SIZE = %d\",fileSize);\n    int progress = 0;\n    do{\n//        if(flag==404){\n//            return;\n//        }\n        read = fread(wav_buffer,sizeof(short int)*2, 8192,fwav);\n        total +=  read* sizeof(short int)*2;\n        LOGI(\"converting ....%d\", total);\n        int tmpProgress = (total*100)/fileSize;\n        LOGD(\"converting size = %d\",tmpProgress);\n\n        if(tmpProgress != progress){\n            progress = tmpProgress;\n            publishJavaProgress(env,obj,progress,mp3);\n        }\n\n        // 调用java代码 完成进度条的更新\n        if(read!=0){\n            write = lame_encode_buffer_interleaved(lame,wav_buffer,read,mp3_buffer,8192);\n            //把转化后的mp3数据写到文件里\n            fwrite(mp3_buffer,sizeof(unsigned char),write,fmp3);\n        }\n        if(read==0){\n            write = lame_encode_flush(lame,mp3_buffer,8192);\n            fwrite(mp3_buffer,sizeof(unsigned char),write,fmp3);\n        }\n    }while(read!=0);\n\n    lame_close(lame);\n    fclose(fwav);\n    fclose(fmp3);\n    env->ReleaseStringUTFChars(wav,cwav);\n    env->ReleaseStringUTFChars(mp3,cmp3);\n\n    convertFinish(env,mp3);\n    LOGI(\"convert  finish\");\n\n}\n\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "app/src/main/jni/NativeMp3ConvertUtil.cpp.bak",
    "content": "//\n// Created by shaomingfa on 2021/1/14.\n//\n\n#include <string>\n#include \"libmp3lame/lame.h\"\n\n#include <jni.h>\n\n#include<stdio.h>\n#include<malloc.h>\n#include<lame.h>\n#include<android/log.h>\n#include \"libmp3lame/lame.h\"\n#include <unistd.h>\n#include <fcntl.h>\n#include <sys/stat.h>\n\n\n#include \"NativeMp3ConvertUtil.h\"\n#include \"com_convert_mymp3convert_Mp3ConvertUtil.h\"\n#define LOG_TAG \"System.out.c\"\n/**\n * 日志打印tag\n */\n#define CONVERT_LOG_TAG \"nativeTag\"\n#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)\n#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)\n\n\n\n#ifndef com_convert_mymp3convert_Mp3ConvertUtil\n#define com_convert_mymp3convert_Mp3ConvertUtil\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/**\n* 返回值 char* 这个代表char数组的首地址\n*  Jstring2CStr 把java中的jstring的类型转化成一个c语言中的char 字符串\n*/\nchar* Jstring2CStr(JNIEnv *env, jstring jstr) {\n    char* rtn = NULL;\n    jclass clsstring = (*env).FindClass( \"java/lang/String\"); //String\n    jstring strencode = (*env).NewStringUTF( \"GB2312\"); // 得到一个java字符串 \"GB2312\"\n    jmethodID mid = (*env).GetMethodID(clsstring, \"getBytes\",\n                                       \"(Ljava/lang/String;)[B\"); //[ String.getBytes(\"gb2312\");\n    jbyteArray barr = (jbyteArray)(*env).CallObjectMethod(jstr, mid,\n                                                          strencode); // String .getByte(\"GB2312\");\n    jsize alen = (*env).GetArrayLength( barr); // byte数组的长度\n    jbyte* ba = (*env).GetByteArrayElements( barr, JNI_FALSE);\n    if (alen > 0) {\n        rtn = (char*) malloc(alen + 1); //\"\\0\"\n        memcpy(rtn, ba, alen);\n        rtn[alen] = 0;\n    }\n    (*env).ReleaseByteArrayElements(barr, ba, 0); //\n    (*env).DeleteLocalRef(strencode);\n    return rtn;\n}\n/**==============================================================================================================================================*/\n/**\n * 调用java代码 更新程序的进度条\n */\nvoid publishJavaProgress(JNIEnv * env, jobject obj, jint progress,jstring outPath) {\n    //1.找到java的LameUtils的class          com/example/myjnidemo/\n    jclass clazz = (*env).FindClass(\"com/convert/mymp3convert/Mp3ConvertUtil\");\n    if (clazz == 0) {\n        LOGI(\"can't find clazz\");\n        return;\n    }\n    LOGI(\" convert progress %d\" , progress);\n\n    //2 找到class 里面的方法定义\n\n    jmethodID methodid = (*env).GetStaticMethodID(clazz,\"setConvertProgress\",\"(ILjava/lang/String;)V\");//jmethodID methodid = (*env).GetMethodID(clazz, \"setConvertProgress\",\"(I)V\");\n    if (methodid == 0) {\n        LOGI(\"can't find methodid\");\n        return;\n    }\n    LOGI(\" find methodid\");\n\n    //3 .调用方法\n    (*env).CallStaticVoidMethod(clazz, methodid, progress,outPath);//(*env).CallVoidMethod(obj, methodid, progress);\n    //env -> CallVoidMethod(obj,methodid,progress);\n    env->DeleteLocalRef(clazz);\n    //env->DeleteLocalRef(methodid);\n}\n/**\n * 调用java代码 更新程序的进度条\n */\nvoid convertFinish(JNIEnv * env, jstring mp3Path) {\n    //1.找到java的LameUtils的class          com/example/myjnidemo/\n    jclass clazz = (*env).FindClass(\"com/convert/mymp3convert/Mp3ConvertUtil\");\n    if (clazz == 0) {\n        LOGI(\"can't find clazz\");\n        return;\n    }\n    const char *c = env->GetStringUTFChars(mp3Path, JNI_FALSE);\n    LOGI(\" convert finished %s\" , c);\n    env->ReleaseStringUTFChars(mp3Path,c);\n\n    //2 找到class 里面的方法定义\n    jmethodID methodid = (*env).GetStaticMethodID(clazz,\"convertFinish\",\"(Ljava/lang/String;)V\");\n    if (methodid == 0) {\n        LOGI(\"can't find methodid\");\n        return;\n    }\n    LOGI(\" find convertFinish methodid\");\n\n    //3 .调用方法\n    env -> CallStaticVoidMethod(clazz,methodid,mp3Path);\n    env->DeleteLocalRef(clazz);\n}\n/**\n * 调用java代码 转换失败时调用\n */\nvoid convertError(JNIEnv * env,jstring msg,jstring mp3Path) {\n    //1.找到java的LameUtils的class          com/example/myjnidemo/\n    jclass clazz = (*env).FindClass(\"com/convert/mymp3convert/Mp3ConvertUtil\");\n    if (clazz == 0) {\n        LOGI(\"can't find clazz\");\n        return;\n    }\n\n    const char *c = (*env).GetStringUTFChars(mp3Path, JNI_FALSE);\n    LOGI(\" convert error %s\" , c);\n    (*env).ReleaseStringUTFChars(mp3Path,c);\n\n    //2 找到class 里面的方法定义\n\n    jmethodID methodid = (*env).GetStaticMethodID(clazz,\"convertError\",\n                                                  \"(Ljava/lang/String;Ljava/lang/String;)V\");\n    if (methodid == 0) {\n        LOGI(\"can't find methodid\");\n        return;\n    }\n    LOGI(\" find methodid\");\n\n    //3 .调用方法\n    env -> CallStaticVoidMethod(clazz,methodid,msg,mp3Path);\n    env->DeleteLocalRef(clazz);\n}\n/**\n * 调用java代码 打印日志时调用\n */\nvoid nativeLog(JNIEnv * env, jstring msg) {\n    //1.找到java的LameUtils的class          com/example/myjnidemo/\n    jclass clazz = (*env).FindClass(\"com/convert/mymp3convert/Mp3ConvertUtil\");\n    if (clazz == 0) {\n        LOGI(\"can't find clazz\");\n        return;\n    }\n    //2 找到class 里面的方法定义\n    jmethodID methodid = (*env).GetStaticMethodID(clazz,\"nativeLog\",\n                                                  \"(Ljava/lang/String;Ljava/lang/String;)V\");\n    if (methodid == 0) {\n        LOGI(\"can't find methodid\");\n        return;\n    }\n    LOGI(\" find methodid\");\n    jstring logTag = env->NewStringUTF(CONVERT_LOG_TAG);\n    //3 .调用方法\n    env -> CallStaticVoidMethod(clazz,methodid,logTag,msg);\n    env->DeleteLocalRef(logTag);\n    env->DeleteLocalRef(clazz);\n}\n/**\n * 字符串拼接\n * @param env\n * @param cstr\n * @param jstr\n * @return\n */\njstring jstrCat(JNIEnv *env,char * cstr,jstring jstr){\n    char *c =(char *)(*env).GetStringUTFChars(jstr,JNI_FALSE);\n    char * bf = new char[strlen(cstr) + strlen(c) +1];\n    memcpy(bf, cstr, strlen(cstr) + 1);\n    strcat(bf, c);\n    jstring  js = env->NewStringUTF(bf);\n    delete [] bf;\n    (*env).ReleaseStringUTFChars(jstr,c);\n    return js;\n}\n/**\n * 获取文件的大小\n * @param filename\n * @return\n */\nlong long file_size(char* filename){\n    struct stat statbuf;\n    stat(filename,&statbuf);\n    return statbuf.st_size;\n}\n/*\n * Class:     com_convert_mymp3convert_Mp3ConvertUtil\n * Method:    hello\n * Signature: (Ljava/lang/String;)Ljava/lang/String;\n */\nJNIEXPORT jstring JNICALL Java_com_convert_mymp3convert_Mp3ConvertUtil_hello\n        (JNIEnv *env, jclass obj, jstring str){\n\n    jstring js = env->NewStringUTF(\"/sd/mp3\");\n    publishJavaProgress(env,obj,123,js);\n    env->DeleteLocalRef(js);\n\n    jstring jstr = env->NewStringUTF(\"/sd/m/mp3\");\n    convertFinish(env,jstr);\n    env->DeleteLocalRef(jstr);\n\n    jstring msg = env->NewStringUTF(\"xxx原因导致了未转换成功\");\n    convertError(env,  msg, msg);\n    env->DeleteLocalRef(msg);\n\n    LOGD(\"lame ver = %s\",get_lame_very_short_version());\n    LOGI(\"convertmp3   %S  ===  %S\",\"wav\",\"mp3\");\n    LOGD(\"CONVERT   %S\",\"test\");\n    return env->NewStringUTF(\"Hello From JNI!\");//\n}\n/*\n * Class:     com_convert_mymp3convert_Mp3ConvertUtil\n * Method:    getLameVer\n * Signature: ()Ljava/lang/String;\n */\nJNIEXPORT jstring JNICALL\nJava_com_convert_mymp3convert_Mp3ConvertUtil_getLameVer(JNIEnv *env, jclass obj) {\n    LOGD(\"CONVERT  123321 测试 S \");\n    LOGD(\"CONVERT  123321 测试 S --- %d\",123);\n    LOGD(\"CONVERT  123321 测试 S --- %s\",\"test\");\n    return (*env).NewStringUTF(get_lame_version());\n}\n//int flag = 0;\n/**\n *wav转换mp3\n * @param env\n * @param obj\n * @param wav\n * @param mp3\n */\n/*\n * Class:     com_convert_mymp3convert_Mp3ConvertUtil\n * Method:    convertmp3\n * Signature: (Ljava/lang/String;Ljava/lang/String;)V\n */\nJNIEXPORT void JNICALL\nJava_com_convert_mymp3convert_Mp3ConvertUtil_convertmp3(JNIEnv *env, jclass obj, jstring wav,jstring mp3) {\n\n    char* cwav = const_cast<char *>(env->GetStringUTFChars(wav, JNI_FALSE));//Jstring2CStr(env,wav) ;\n    char* cmp3= const_cast<char *>(env->GetStringUTFChars(mp3, JNI_FALSE));//Jstring2CStr(env,mp3);\n    LOGI(\"wav = %s\", cwav);\n    LOGI(\"mp3 = %s\", cmp3);\n\n    char buf[2048] = {};\n    sprintf(buf, \"source：%s，target：%s \", cwav,cmp3);\n    LOGD(buf,NULL);\n\n    if(access(cwav,F_OK) == -1){\n        free(cwav);\n        free(cmp3);\n        LOGD(\"转换源文件不存在\");\n        jstring msg = jstrCat(env,\"转换源文件不存在:\",mp3);\n        nativeLog(env, msg);\n        convertError(env,msg,mp3);\n        env->DeleteLocalRef(msg);\n        return;\n    }\n    long long fileSize = file_size(cwav);\n    if (fileSize == 0) {\n        free(cwav);\n        free(cmp3);\n        jstring msg = jstrCat(env,\"转换源文件大小为0:\",mp3);\n        nativeLog(env, msg);\n        convertError(env,msg,mp3);\n        env->DeleteLocalRef(msg);\n        return;\n    }\n    //1.打开 wav,MP3文件\n    FILE* fwav = fopen(cwav,\"rb\");\n    FILE* fmp3 = fopen(cmp3,\"wb\");\n\n    short int wav_buffer[8192*2]= {};\n    unsigned char mp3_buffer[8192] = {};\n\n    //1.初始化lame的编码器\n    lame_t lame =  lame_init();\n    //2. 设置lame mp3编码的采样率\n    lame_set_in_samplerate(lame , 44100);\n    lame_set_num_channels(lame,2);\n    // 3. 设置MP3的编码方式\n    lame_set_VBR(lame, vbr_default);\n    lame_init_params(lame);\n    LOGI(\"lame init finish\");\n\n    int read ; int write; //代表读了多少个次 和写了多少次\n    long long total=0; // 当前读的wav文件的byte数目\n\n    LOGD(\"FILE SIZE = %d\",fileSize);\n    int progress = 0;\n    do{\n//        if(flag==404){\n//            return;\n//        }\n        read = fread(wav_buffer,sizeof(short int)*2, 8192,fwav);\n        total +=  read* sizeof(short int)*2;\n        LOGI(\"converting ....%d\", total);\n        int tmpProgress = (total*100)/fileSize;\n        LOGD(\"converting size = %d\",tmpProgress);\n\n        if(tmpProgress != progress){\n            progress = tmpProgress;\n            publishJavaProgress(env,obj,progress,mp3);\n        }\n\n        // 调用java代码 完成进度条的更新\n        if(read!=0){\n            write = lame_encode_buffer_interleaved(lame,wav_buffer,read,mp3_buffer,8192);\n            //把转化后的mp3数据写到文件里\n            fwrite(mp3_buffer,sizeof(unsigned char),write,fmp3);\n        }\n        if(read==0){\n            write = lame_encode_flush(lame,mp3_buffer,8192);\n            fwrite(mp3_buffer,sizeof(unsigned char),write,fmp3);\n        }\n    }while(read!=0);\n\n    lame_close(lame);\n    fclose(fwav);\n    fclose(fmp3);\n    env->ReleaseStringUTFChars(wav,cwav);\n    env->ReleaseStringUTFChars(mp3,cmp3);\n\n    convertFinish(env,mp3);\n    LOGI(\"convert  finish\");\n\n}\n\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "app/src/main/jni/NativeMp3ConvertUtil.h",
    "content": "//\n// Created by shaomingfa on 2021/1/14.\n//\n#include <jni.h>\n#ifndef MYMP3CONVERT_NATIVEMP3CONVERTUTIL_H\n#define MYMP3CONVERT_NATIVEMP3CONVERTUTIL_H\n\n\nclass NativeMp3ConvertUtil {\n\n};\n\n\n#endif //MYMP3CONVERT_NATIVEMP3CONVERTUTIL_H\n"
  },
  {
    "path": "app/src/main/jni/NativeMyTest.cpp",
    "content": "//\n// Created by shaomingfa on 2021/1/14.\n//\n#include <jni.h>\n#include <string>\n#include \"com_convert_mymp3convert_MyTest.h\"\n#include \"libmp3lame/lame.h\"\n/**\n * 字符串拼接\n * @param env\n * @param cstr\n * @param jstr\n * @return\n */\njstring jstrCat(JNIEnv *env,char * cstr,jstring jstr){\n    char *c =(char *)(*env).GetStringUTFChars(jstr,JNI_FALSE);\n    char * bf = new char[strlen(cstr) + strlen(c) +1];\n    memcpy(bf, cstr, strlen(cstr) + 1);\n    strcat(bf, c);\n    jstring  js = env->NewStringUTF(bf);\n    delete [] bf;\n    (*env).ReleaseStringUTFChars(jstr,c);\n    return js;\n}\n/*\n * Class:     com_convert_mymp3convert_MyTest\n * Method:    test\n * Signature: ()Ljava/lang/String;\n */\nextern \"C\" JNIEXPORT jstring JNICALL Java_com_convert_mymp3convert_MyTest_test\n        (JNIEnv *env, jclass clazz){\n\n    //1、直接使用GetStringUTFChars方法将传递过来的jstring转为char*\n    char *c1 = \"即将转换：\";\n    jstring mp3 = env->NewStringUTF(\"mp3\");\n    char *c2 = (char *) (env->GetStringUTFChars(mp3, JNI_FALSE));\n    env->ReleaseStringUTFChars(mp3,c2);\n    //2、再使用本地函数strcat 拼接两个char*对象，然后NewStringUTF转为jstring返回去\n    jstring  res = jstrCat(env,c1,mp3);//strcat(c1, c2);\n    jstring jstr = res;//env->NewStringUTF(res);\n    //convertLog(env,jstr);\n    env->DeleteLocalRef(jstr);\n\n    return env->NewStringUTF(get_lame_very_short_version());\n}\n\n"
  },
  {
    "path": "app/src/main/jni/com_convert_mymp3convert_Mp3ConvertUtil.h",
    "content": "/* DO NOT EDIT THIS FILE - it is machine generated */\n#include <jni.h>\n/* Header for class com_convert_mymp3convert_Mp3ConvertUtil */\n\n#ifndef _Included_com_convert_mymp3convert_Mp3ConvertUtil\n#define _Included_com_convert_mymp3convert_Mp3ConvertUtil\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n/*\n * Class:     com_convert_mymp3convert_Mp3ConvertUtil\n * Method:    hello\n * Signature: (Ljava/lang/String;)Ljava/lang/String;\n */\nJNIEXPORT jstring JNICALL Java_com_convert_mymp3convert_Mp3ConvertUtil_hello\n  (JNIEnv *, jclass, jstring);\n\n/*\n * Class:     com_convert_mymp3convert_Mp3ConvertUtil\n * Method:    getLameVer\n * Signature: ()Ljava/lang/String;\n */\nJNIEXPORT jstring JNICALL Java_com_convert_mymp3convert_Mp3ConvertUtil_getLameVer\n  (JNIEnv *, jclass);\n\n/*\n * Class:     com_convert_mymp3convert_Mp3ConvertUtil\n * Method:    convertmp3\n * Signature: (Ljava/lang/String;Ljava/lang/String;)V\n */\nJNIEXPORT void JNICALL Java_com_convert_mymp3convert_Mp3ConvertUtil_convertmp3\n  (JNIEnv *, jclass, jstring, jstring);\n\n#ifdef __cplusplus\n}\n#endif\n#endif\n"
  },
  {
    "path": "app/src/main/jni/com_convert_mymp3convert_MyTest.h",
    "content": "/* DO NOT EDIT THIS FILE - it is machine generated */\n/* Header for class com_convert_mymp3convert_MyTest */\n\n#pragma once\n#include <jni.h>\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n/*\n * Class:     com_convert_mymp3convert_MyTest\n * Method:    test\n * Signature: ()Ljava/lang/String;\n */\nJNIEXPORT jstring JNICALL Java_com_convert_mymp3convert_MyTest_test\n  (JNIEnv *, jclass);\n\n#ifdef __cplusplus\n}\n#endif\n\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/VbrTag.c",
    "content": "/*\n *      Xing VBR tagging for LAME.\n *\n *      Copyright (c) 1999 A.L. Faber\n *      Copyright (c) 2001 Jonathan Dee\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n/* $Id: VbrTag.c,v 1.103.2.1 2011/11/18 09:18:28 robert Exp $ */\n\n#ifdef HAVE_CONFIG_H\n# include <config.h>\n#endif\n\n#include \"lame.h\"\n#include \"machine.h\"\n#include \"encoder.h\"\n#include \"util.h\"\n#include \"bitstream.h\"\n#include \"VbrTag.h\"\n#include \"lame_global_flags.h\"\n#include \"tables.h\"\n\n#ifdef __sun__\n/* woraround for SunOS 4.x, it has SEEK_* defined here */\n#include <unistd.h>\n#endif\n\n\n#ifdef _DEBUG\n/*  #define DEBUG_VBRTAG */\n#endif\n\n/*\n *    4 bytes for Header Tag\n *    4 bytes for Header Flags\n *  100 bytes for entry (NUMTOCENTRIES)\n *    4 bytes for FRAME SIZE\n *    4 bytes for STREAM_SIZE\n *    4 bytes for VBR SCALE. a VBR quality indicator: 0=best 100=worst\n *   20 bytes for LAME tag.  for example, \"LAME3.12 (beta 6)\"\n * ___________\n *  140 bytes\n*/\n#define VBRHEADERSIZE (NUMTOCENTRIES+4+4+4+4+4)\n\n#define LAMEHEADERSIZE (VBRHEADERSIZE + 9 + 1 + 1 + 8 + 1 + 1 + 3 + 1 + 1 + 2 + 4 + 2 + 2)\n\n/* the size of the Xing header (MPEG1 and MPEG2) in kbps */\n#define XING_BITRATE1 128\n#define XING_BITRATE2  64\n#define XING_BITRATE25 32\n\nextern const char* get_lame_tag_encoder_short_version(void);\n\nstatic const char VBRTag0[] = { \"Xing\" };\nstatic const char VBRTag1[] = { \"Info\" };\n\n\n\n\n/* Lookup table for fast CRC computation\n * See 'CRC_update_lookup'\n * Uses the polynomial x^16+x^15+x^2+1 */\n\nstatic const unsigned int crc16_lookup[256] = {\n    0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,\n    0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,\n    0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,\n    0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,\n    0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,\n    0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,\n    0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,\n    0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,\n    0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,\n    0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,\n    0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,\n    0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,\n    0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,\n    0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,\n    0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,\n    0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,\n    0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,\n    0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,\n    0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,\n    0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,\n    0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,\n    0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,\n    0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,\n    0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,\n    0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,\n    0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,\n    0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,\n    0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,\n    0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,\n    0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,\n    0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,\n    0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040\n};\n\n\n\n\n\n/***********************************************************************\n *  Robert Hegemann 2001-01-17\n ***********************************************************************/\n\nstatic void\naddVbr(VBR_seek_info_t * v, int bitrate)\n{\n    int     i;\n\n    v->nVbrNumFrames++;\n    v->sum += bitrate;\n    v->seen++;\n\n    if (v->seen < v->want) {\n        return;\n    }\n\n    if (v->pos < v->size) {\n        v->bag[v->pos] = v->sum;\n        v->pos++;\n        v->seen = 0;\n    }\n    if (v->pos == v->size) {\n        for (i = 1; i < v->size; i += 2) {\n            v->bag[i / 2] = v->bag[i];\n        }\n        v->want *= 2;\n        v->pos /= 2;\n    }\n}\n\nstatic void\nXing_seek_table(VBR_seek_info_t const* v, unsigned char *t)\n{\n    int     i, indx;\n    int     seek_point;\n\n    if (v->pos <= 0)\n        return;\n\n    for (i = 1; i < NUMTOCENTRIES; ++i) {\n        float   j = i / (float) NUMTOCENTRIES, act, sum;\n        indx = (int) (floor(j * v->pos));\n        if (indx > v->pos - 1)\n            indx = v->pos - 1;\n        act = v->bag[indx];\n        sum = v->sum;\n        seek_point = (int) (256. * act / sum);\n        if (seek_point > 255)\n            seek_point = 255;\n        t[i] = seek_point;\n    }\n}\n\n#ifdef DEBUG_VBR_SEEKING_TABLE\nstatic void\nprint_seeking(unsigned char *t)\n{\n    int     i;\n\n    printf(\"seeking table \");\n    for (i = 0; i < NUMTOCENTRIES; ++i) {\n        printf(\" %d \", t[i]);\n    }\n    printf(\"\\n\");\n}\n#endif\n\n\n/****************************************************************************\n * AddVbrFrame: Add VBR entry, used to fill the VBR the TOC entries\n * Paramters:\n *      nStreamPos: how many bytes did we write to the bitstream so far\n *                              (in Bytes NOT Bits)\n ****************************************************************************\n*/\nvoid\nAddVbrFrame(lame_internal_flags * gfc)\n{\n    int     kbps = bitrate_table[gfc->cfg.version][gfc->ov_enc.bitrate_index];\n    assert(gfc->VBR_seek_table.bag);\n    addVbr(&gfc->VBR_seek_table, kbps);\n}\n\n\n/*-------------------------------------------------------------*/\nstatic int\nExtractI4(const unsigned char *buf)\n{\n    int     x;\n    /* big endian extract */\n    x = buf[0];\n    x <<= 8;\n    x |= buf[1];\n    x <<= 8;\n    x |= buf[2];\n    x <<= 8;\n    x |= buf[3];\n    return x;\n}\n\nstatic void\nCreateI4(unsigned char *buf, uint32_t nValue)\n{\n    /* big endian create */\n    buf[0] = (nValue >> 24) & 0xff;\n    buf[1] = (nValue >> 16) & 0xff;\n    buf[2] = (nValue >> 8) & 0xff;\n    buf[3] = (nValue) & 0xff;\n}\n\n\n\nstatic void\nCreateI2(unsigned char *buf, int nValue)\n{\n    /* big endian create */\n    buf[0] = (nValue >> 8) & 0xff;\n    buf[1] = (nValue) & 0xff;\n}\n\n/* check for magic strings*/\nstatic int\nIsVbrTag(const unsigned char *buf)\n{\n    int     isTag0, isTag1;\n\n    isTag0 = ((buf[0] == VBRTag0[0]) && (buf[1] == VBRTag0[1]) && (buf[2] == VBRTag0[2])\n              && (buf[3] == VBRTag0[3]));\n    isTag1 = ((buf[0] == VBRTag1[0]) && (buf[1] == VBRTag1[1]) && (buf[2] == VBRTag1[2])\n              && (buf[3] == VBRTag1[3]));\n\n    return (isTag0 || isTag1);\n}\n\n#define SHIFT_IN_BITS_VALUE(x,n,v) ( x = (x << (n)) | ( (v) & ~(-1 << (n)) ) )\n\nstatic void\nsetLameTagFrameHeader(lame_internal_flags const *gfc, unsigned char *buffer)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    EncResult_t const *const eov = &gfc->ov_enc;\n    char    abyte, bbyte;\n\n    SHIFT_IN_BITS_VALUE(buffer[0], 8u, 0xffu);\n\n    SHIFT_IN_BITS_VALUE(buffer[1], 3u, 7);\n    SHIFT_IN_BITS_VALUE(buffer[1], 1u, (cfg->samplerate_out < 16000) ? 0 : 1);\n    SHIFT_IN_BITS_VALUE(buffer[1], 1u, cfg->version);\n    SHIFT_IN_BITS_VALUE(buffer[1], 2u, 4 - 3);\n    SHIFT_IN_BITS_VALUE(buffer[1], 1u, (!cfg->error_protection) ? 1 : 0);\n\n    SHIFT_IN_BITS_VALUE(buffer[2], 4u, eov->bitrate_index);\n    SHIFT_IN_BITS_VALUE(buffer[2], 2u, cfg->samplerate_index);\n    SHIFT_IN_BITS_VALUE(buffer[2], 1u, 0);\n    SHIFT_IN_BITS_VALUE(buffer[2], 1u, cfg->extension);\n\n    SHIFT_IN_BITS_VALUE(buffer[3], 2u, cfg->mode);\n    SHIFT_IN_BITS_VALUE(buffer[3], 2u, eov->mode_ext);\n    SHIFT_IN_BITS_VALUE(buffer[3], 1u, cfg->copyright);\n    SHIFT_IN_BITS_VALUE(buffer[3], 1u, cfg->original);\n    SHIFT_IN_BITS_VALUE(buffer[3], 2u, cfg->emphasis);\n\n    /* the default VBR header. 48 kbps layer III, no padding, no crc */\n    /* but sampling freq, mode andy copyright/copy protection taken */\n    /* from first valid frame */\n    buffer[0] = (uint8_t) 0xff;\n    abyte = (buffer[1] & (unsigned char) 0xf1);\n    {\n        int     bitrate;\n        if (1 == cfg->version) {\n            bitrate = XING_BITRATE1;\n        }\n        else {\n            if (cfg->samplerate_out < 16000)\n                bitrate = XING_BITRATE25;\n            else\n                bitrate = XING_BITRATE2;\n        }\n\n        if (cfg->vbr == vbr_off)\n            bitrate = cfg->avg_bitrate;\n\n        if (cfg->free_format)\n            bbyte = 0x00;\n        else\n            bbyte = 16 * BitrateIndex(bitrate, cfg->version, cfg->samplerate_out);\n    }\n\n    /* Use as much of the info from the real frames in the\n     * Xing header:  samplerate, channels, crc, etc...\n     */\n    if (cfg->version == 1) {\n        /* MPEG1 */\n        buffer[1] = abyte | (char) 0x0a; /* was 0x0b; */\n        abyte = buffer[2] & (char) 0x0d; /* AF keep also private bit */\n        buffer[2] = (char) bbyte | abyte; /* 64kbs MPEG1 frame */\n    }\n    else {\n        /* MPEG2 */\n        buffer[1] = abyte | (char) 0x02; /* was 0x03; */\n        abyte = buffer[2] & (char) 0x0d; /* AF keep also private bit */\n        buffer[2] = (char) bbyte | abyte; /* 64kbs MPEG2 frame */\n    }\n}\n\n#if 0\nstatic int CheckVbrTag(unsigned char *buf);\n\n/*-------------------------------------------------------------*/\n/* Same as GetVbrTag below, but only checks for the Xing tag.\n   requires buf to contain only 40 bytes */\n/*-------------------------------------------------------------*/\nint\nCheckVbrTag(unsigned char *buf)\n{\n    int     h_id, h_mode;\n\n    /* get selected MPEG header data */\n    h_id = (buf[1] >> 3) & 1;\n    h_mode = (buf[3] >> 6) & 3;\n\n    /*  determine offset of header */\n    if (h_id) {\n        /* mpeg1 */\n        if (h_mode != 3)\n            buf += (32 + 4);\n        else\n            buf += (17 + 4);\n    }\n    else {\n        /* mpeg2 */\n        if (h_mode != 3)\n            buf += (17 + 4);\n        else\n            buf += (9 + 4);\n    }\n\n    return IsVbrTag(buf);\n}\n#endif\n\nint\nGetVbrTag(VBRTAGDATA * pTagData, const unsigned char *buf)\n{\n    int     i, head_flags;\n    int     h_bitrate, h_id, h_mode, h_sr_index, h_layer;\n    int     enc_delay, enc_padding;\n\n    /* get Vbr header data */\n    pTagData->flags = 0;\n\n    /* get selected MPEG header data */\n    h_layer = (buf[1] >> 1) & 3;\n    if ( h_layer != 0x01 ) {\n        /* the following code assumes Layer-3, so give up here */\n        return 0;\n    }\n    h_id = (buf[1] >> 3) & 1;\n    h_sr_index = (buf[2] >> 2) & 3;\n    h_mode = (buf[3] >> 6) & 3;\n    h_bitrate = ((buf[2] >> 4) & 0xf);\n    h_bitrate = bitrate_table[h_id][h_bitrate];\n\n    /* check for FFE syncword */\n    if ((buf[1] >> 4) == 0xE)\n        pTagData->samprate = samplerate_table[2][h_sr_index];\n    else\n        pTagData->samprate = samplerate_table[h_id][h_sr_index];\n    /* if( h_id == 0 ) */\n    /*  pTagData->samprate >>= 1; */\n\n\n\n    /*  determine offset of header */\n    if (h_id) {\n        /* mpeg1 */\n        if (h_mode != 3)\n            buf += (32 + 4);\n        else\n            buf += (17 + 4);\n    }\n    else {\n        /* mpeg2 */\n        if (h_mode != 3)\n            buf += (17 + 4);\n        else\n            buf += (9 + 4);\n    }\n\n    if (!IsVbrTag(buf))\n        return 0;\n\n    buf += 4;\n\n    pTagData->h_id = h_id;\n\n    head_flags = pTagData->flags = ExtractI4(buf);\n    buf += 4;           /* get flags */\n\n    if (head_flags & FRAMES_FLAG) {\n        pTagData->frames = ExtractI4(buf);\n        buf += 4;\n    }\n\n    if (head_flags & BYTES_FLAG) {\n        pTagData->bytes = ExtractI4(buf);\n        buf += 4;\n    }\n\n    if (head_flags & TOC_FLAG) {\n        if (pTagData->toc != NULL) {\n            for (i = 0; i < NUMTOCENTRIES; i++)\n                pTagData->toc[i] = buf[i];\n        }\n        buf += NUMTOCENTRIES;\n    }\n\n    pTagData->vbr_scale = -1;\n\n    if (head_flags & VBR_SCALE_FLAG) {\n        pTagData->vbr_scale = ExtractI4(buf);\n        buf += 4;\n    }\n\n    pTagData->headersize = ((h_id + 1) * 72000 * h_bitrate) / pTagData->samprate;\n\n    buf += 21;\n    enc_delay = buf[0] << 4;\n    enc_delay += buf[1] >> 4;\n    enc_padding = (buf[1] & 0x0F) << 8;\n    enc_padding += buf[2];\n    /* check for reasonable values (this may be an old Xing header, */\n    /* not a INFO tag) */\n    if (enc_delay < 0 || enc_delay > 3000)\n        enc_delay = -1;\n    if (enc_padding < 0 || enc_padding > 3000)\n        enc_padding = -1;\n\n    pTagData->enc_delay = enc_delay;\n    pTagData->enc_padding = enc_padding;\n\n#ifdef DEBUG_VBRTAG\n    fprintf(stderr, \"\\n\\n********************* VBR TAG INFO *****************\\n\");\n    fprintf(stderr, \"tag         :%s\\n\", VBRTag);\n    fprintf(stderr, \"head_flags  :%d\\n\", head_flags);\n    fprintf(stderr, \"bytes       :%d\\n\", pTagData->bytes);\n    fprintf(stderr, \"frames      :%d\\n\", pTagData->frames);\n    fprintf(stderr, \"VBR Scale   :%d\\n\", pTagData->vbr_scale);\n    fprintf(stderr, \"enc_delay  = %i \\n\", enc_delay);\n    fprintf(stderr, \"enc_padding= %i \\n\", enc_padding);\n    fprintf(stderr, \"toc:\\n\");\n    if (pTagData->toc != NULL) {\n        for (i = 0; i < NUMTOCENTRIES; i++) {\n            if ((i % 10) == 0)\n                fprintf(stderr, \"\\n\");\n            fprintf(stderr, \" %3d\", (int) (pTagData->toc[i]));\n        }\n    }\n    fprintf(stderr, \"\\n***************** END OF VBR TAG INFO ***************\\n\");\n#endif\n    return 1;           /* success */\n}\n\n\n/****************************************************************************\n * InitVbrTag: Initializes the header, and write empty frame to stream\n * Paramters:\n *                              fpStream: pointer to output file stream\n *                              nMode   : Channel Mode: 0=STEREO 1=JS 2=DS 3=MONO\n ****************************************************************************\n*/\nint\nInitVbrTag(lame_global_flags * gfp)\n{\n    lame_internal_flags *gfc = gfp->internal_flags;\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    int     kbps_header;\n\n#define MAXFRAMESIZE 2880 /* or 0xB40, the max freeformat 640 32kHz framesize */\n\n    /*\n     * Xing VBR pretends to be a 48kbs layer III frame.  (at 44.1kHz).\n     * (at 48kHz they use 56kbs since 48kbs frame not big enough for\n     * table of contents)\n     * let's always embed Xing header inside a 64kbs layer III frame.\n     * this gives us enough room for a LAME version string too.\n     * size determined by sampling frequency (MPEG1)\n     * 32kHz:    216 bytes@48kbs    288bytes@ 64kbs\n     * 44.1kHz:  156 bytes          208bytes@64kbs     (+1 if padding = 1)\n     * 48kHz:    144 bytes          192\n     *\n     * MPEG 2 values are the same since the framesize and samplerate\n     * are each reduced by a factor of 2.\n     */\n\n\n    if (1 == cfg->version) {\n        kbps_header = XING_BITRATE1;\n    }\n    else {\n        if (cfg->samplerate_out < 16000)\n            kbps_header = XING_BITRATE25;\n        else\n            kbps_header = XING_BITRATE2;\n    }\n\n    if (cfg->vbr == vbr_off)\n        kbps_header = cfg->avg_bitrate;\n\n    /** make sure LAME Header fits into Frame\n     */\n    {\n        int     total_frame_size = ((cfg->version + 1) * 72000 * kbps_header) / cfg->samplerate_out;\n        int     header_size = (cfg->sideinfo_len + LAMEHEADERSIZE);\n        gfc->VBR_seek_table.TotalFrameSize = total_frame_size;\n        if (total_frame_size < header_size || total_frame_size > MAXFRAMESIZE) {\n            /* disable tag, it wont fit */\n            gfc->cfg.write_lame_tag = 0;\n            return 0;\n        }\n    }\n\n    gfc->VBR_seek_table.nVbrNumFrames = 0;\n    gfc->VBR_seek_table.nBytesWritten = 0;\n    gfc->VBR_seek_table.sum = 0;\n\n    gfc->VBR_seek_table.seen = 0;\n    gfc->VBR_seek_table.want = 1;\n    gfc->VBR_seek_table.pos = 0;\n\n    if (gfc->VBR_seek_table.bag == NULL) {\n        gfc->VBR_seek_table.bag = malloc(400 * sizeof(int));\n        if (gfc->VBR_seek_table.bag != NULL) {\n            gfc->VBR_seek_table.size = 400;\n        }\n        else {\n            gfc->VBR_seek_table.size = 0;\n            ERRORF(gfc, \"Error: can't allocate VbrFrames buffer\\n\");\n            gfc->cfg.write_lame_tag = 0;\n            return -1;\n        }\n    }\n\n    /* write dummy VBR tag of all 0's into bitstream */\n    {\n        uint8_t buffer[MAXFRAMESIZE];\n        size_t  i, n;\n\n        memset(buffer, 0, sizeof(buffer));\n        setLameTagFrameHeader(gfc, buffer);\n        n = gfc->VBR_seek_table.TotalFrameSize;\n        for (i = 0; i < n; ++i) {\n            add_dummy_byte(gfc, buffer[i], 1);\n        }\n    }\n    /* Success */\n    return 0;\n}\n\n\n\n/* fast CRC-16 computation - uses table crc16_lookup 8*/\nstatic uint16_t\nCRC_update_lookup(uint16_t value, uint16_t crc)\n{\n    uint16_t tmp;\n    tmp = crc ^ value;\n    crc = (crc >> 8) ^ crc16_lookup[tmp & 0xff];\n    return crc;\n}\n\nvoid\nUpdateMusicCRC(uint16_t * crc, unsigned char const *buffer, int size)\n{\n    int     i;\n    for (i = 0; i < size; ++i)\n        *crc = CRC_update_lookup(buffer[i], *crc);\n}\n\n\n\n\n\n/****************************************************************************\n * Jonathan Dee 2001/08/31\n *\n * PutLameVBR: Write LAME info: mini version + info on various switches used\n * Paramters:\n *                              pbtStreamBuffer : pointer to output buffer\n *                              id3v2size               : size of id3v2 tag in bytes\n *                              crc                             : computation of crc-16 of Lame Tag so far (starting at frame sync)\n *\n ****************************************************************************\n*/\nstatic int\nPutLameVBR(lame_global_flags const *gfp, size_t nMusicLength, uint8_t * pbtStreamBuffer, uint16_t crc)\n{\n    lame_internal_flags const *gfc = gfp->internal_flags;\n    SessionConfig_t const *const cfg = &gfc->cfg;\n\n    int     nBytesWritten = 0;\n    int     i;\n\n    int     enc_delay = gfc->ov_enc.encoder_delay; /* encoder delay */\n    int     enc_padding = gfc->ov_enc.encoder_padding; /* encoder padding  */\n\n    /*recall: cfg->vbr_q is for example set by the switch -V  */\n    /*   gfp->quality by -q, -h, -f, etc */\n\n    int     nQuality = (100 - 10 * gfp->VBR_q - gfp->quality);\n\n\n    /*\n    NOTE:\n            Even though the specification for the LAME VBR tag\n            did explicitly mention other encoders than LAME,\n            many SW/HW decoder seem to be able to make use of\n            this tag only, if the encoder version starts with LAME.\n            To be compatible with such decoders, ANY encoder will\n            be forced to write a fake LAME version string!\n            As a result, the encoder version info becomes worthless.\n    */\n    const char *szVersion = get_lame_tag_encoder_short_version();\n    uint8_t nVBR;\n    uint8_t nRevision = 0x00;\n    uint8_t nRevMethod;\n    uint8_t vbr_type_translator[] = { 1, 5, 3, 2, 4, 0, 3 }; /*numbering different in vbr_mode vs. Lame tag */\n\n    uint8_t nLowpass =\n        (((cfg->lowpassfreq / 100.0) + .5) > 255 ? 255 : (cfg->lowpassfreq / 100.0) + .5);\n\n    uint32_t nPeakSignalAmplitude = 0;\n\n    uint16_t nRadioReplayGain = 0;\n    uint16_t nAudiophileReplayGain = 0;\n\n    uint8_t nNoiseShaping = cfg->noise_shaping;\n    uint8_t nStereoMode = 0;\n    int     bNonOptimal = 0;\n    uint8_t nSourceFreq = 0;\n    uint8_t nMisc = 0;\n    uint16_t nMusicCRC = 0;\n\n    /*psy model type: Gpsycho or NsPsytune */\n    unsigned char bExpNPsyTune = 1; /* only NsPsytune */\n    unsigned char bSafeJoint = (cfg->use_safe_joint_stereo) != 0;\n\n    unsigned char bNoGapMore = 0;\n    unsigned char bNoGapPrevious = 0;\n\n    int     nNoGapCount = gfp->nogap_total;\n    int     nNoGapCurr = gfp->nogap_current;\n\n\n    uint8_t nAthType = cfg->ATHtype; /*4 bits. */\n\n    uint8_t nFlags = 0;\n\n    /* if ABR, {store bitrate <=255} else { store \"-b\"} */\n    int     nABRBitrate;\n    switch (cfg->vbr) {\n    case vbr_abr:{\n            nABRBitrate = cfg->vbr_avg_bitrate_kbps;\n            break;\n        }\n    case vbr_off:{\n            nABRBitrate = cfg->avg_bitrate;\n            break;\n        }\n    default:{          /*vbr modes */\n            nABRBitrate = bitrate_table[cfg->version][cfg->vbr_min_bitrate_index];;\n        }\n    }\n\n\n    /*revision and vbr method */\n    if (cfg->vbr < sizeof(vbr_type_translator))\n        nVBR = vbr_type_translator[cfg->vbr];\n    else\n        nVBR = 0x00;    /*unknown. */\n\n    nRevMethod = 0x10 * nRevision + nVBR;\n\n\n    /* ReplayGain */\n    if (cfg->findReplayGain) {\n        int     RadioGain = gfc->ov_rpg.RadioGain;\n        if (RadioGain > 0x1FE)\n            RadioGain = 0x1FE;\n        if (RadioGain < -0x1FE)\n            RadioGain = -0x1FE;\n\n        nRadioReplayGain = 0x2000; /* set name code */\n        nRadioReplayGain |= 0xC00; /* set originator code to `determined automatically' */\n\n        if (RadioGain >= 0)\n            nRadioReplayGain |= RadioGain; /* set gain adjustment */\n        else {\n            nRadioReplayGain |= 0x200; /* set the sign bit */\n            nRadioReplayGain |= -RadioGain; /* set gain adjustment */\n        }\n    }\n\n    /* peak sample */\n    if (cfg->findPeakSample)\n        nPeakSignalAmplitude =\n            abs((int) ((((FLOAT) gfc->ov_rpg.PeakSample) / 32767.0) * pow(2, 23) + .5));\n\n    /*nogap */\n    if (nNoGapCount != -1) {\n        if (nNoGapCurr > 0)\n            bNoGapPrevious = 1;\n\n        if (nNoGapCurr < nNoGapCount - 1)\n            bNoGapMore = 1;\n    }\n\n    /*flags */\n\n    nFlags = nAthType + (bExpNPsyTune << 4)\n        + (bSafeJoint << 5)\n        + (bNoGapMore << 6)\n        + (bNoGapPrevious << 7);\n\n\n    if (nQuality < 0)\n        nQuality = 0;\n\n    /*stereo mode field... a bit ugly. */\n\n    switch (cfg->mode) {\n    case MONO:\n        nStereoMode = 0;\n        break;\n    case STEREO:\n        nStereoMode = 1;\n        break;\n    case DUAL_CHANNEL:\n        nStereoMode = 2;\n        break;\n    case JOINT_STEREO:\n        if (cfg->force_ms)\n            nStereoMode = 4;\n        else\n            nStereoMode = 3;\n        break;\n    case NOT_SET:\n        /* FALLTHROUGH */\n    default:\n        nStereoMode = 7;\n        break;\n    }\n\n    /*Intensity stereo : nStereoMode = 6. IS is not implemented */\n\n    if (cfg->samplerate_in <= 32000)\n        nSourceFreq = 0x00;\n    else if (cfg->samplerate_in == 48000)\n        nSourceFreq = 0x02;\n    else if (cfg->samplerate_in > 48000)\n        nSourceFreq = 0x03;\n    else\n        nSourceFreq = 0x01; /*default is 44100Hz. */\n\n\n    /*Check if the user overrided the default LAME behaviour with some nasty options */\n\n    if (cfg->short_blocks == short_block_forced || cfg->short_blocks == short_block_dispensed || ((cfg->lowpassfreq == -1) && (cfg->highpassfreq == -1)) || /* \"-k\" */\n        (cfg->disable_reservoir && cfg->avg_bitrate < 320) ||\n        cfg->noATH || cfg->ATHonly || (nAthType == 0) || cfg->samplerate_in <= 32000)\n        bNonOptimal = 1;\n\n    nMisc = nNoiseShaping + (nStereoMode << 2)\n        + (bNonOptimal << 5)\n        + (nSourceFreq << 6);\n\n\n    nMusicCRC = gfc->nMusicCRC;\n\n\n    /*Write all this information into the stream */\n    CreateI4(&pbtStreamBuffer[nBytesWritten], nQuality);\n    nBytesWritten += 4;\n\n    strncpy((char *) &pbtStreamBuffer[nBytesWritten], szVersion, 9);\n    nBytesWritten += 9;\n\n    pbtStreamBuffer[nBytesWritten] = nRevMethod;\n    nBytesWritten++;\n\n    pbtStreamBuffer[nBytesWritten] = nLowpass;\n    nBytesWritten++;\n\n    CreateI4(&pbtStreamBuffer[nBytesWritten], nPeakSignalAmplitude);\n    nBytesWritten += 4;\n\n    CreateI2(&pbtStreamBuffer[nBytesWritten], nRadioReplayGain);\n    nBytesWritten += 2;\n\n    CreateI2(&pbtStreamBuffer[nBytesWritten], nAudiophileReplayGain);\n    nBytesWritten += 2;\n\n    pbtStreamBuffer[nBytesWritten] = nFlags;\n    nBytesWritten++;\n\n    if (nABRBitrate >= 255)\n        pbtStreamBuffer[nBytesWritten] = 0xFF;\n    else\n        pbtStreamBuffer[nBytesWritten] = nABRBitrate;\n    nBytesWritten++;\n\n    pbtStreamBuffer[nBytesWritten] = enc_delay >> 4; /* works for win32, does it for unix? */\n    pbtStreamBuffer[nBytesWritten + 1] = (enc_delay << 4) + (enc_padding >> 8);\n    pbtStreamBuffer[nBytesWritten + 2] = enc_padding;\n\n    nBytesWritten += 3;\n\n    pbtStreamBuffer[nBytesWritten] = nMisc;\n    nBytesWritten++;\n\n\n    pbtStreamBuffer[nBytesWritten++] = 0; /*unused in rev0 */\n\n    CreateI2(&pbtStreamBuffer[nBytesWritten], cfg->preset);\n    nBytesWritten += 2;\n\n    CreateI4(&pbtStreamBuffer[nBytesWritten], (int) nMusicLength);\n    nBytesWritten += 4;\n\n    CreateI2(&pbtStreamBuffer[nBytesWritten], nMusicCRC);\n    nBytesWritten += 2;\n\n    /*Calculate tag CRC.... must be done here, since it includes\n     *previous information*/\n\n    for (i = 0; i < nBytesWritten; i++)\n        crc = CRC_update_lookup(pbtStreamBuffer[i], crc);\n\n    CreateI2(&pbtStreamBuffer[nBytesWritten], crc);\n    nBytesWritten += 2;\n\n    return nBytesWritten;\n}\n\nstatic long\nskipId3v2(FILE * fpStream)\n{\n    size_t  nbytes;\n    long    id3v2TagSize;\n    unsigned char id3v2Header[10];\n\n    /* seek to the beginning of the stream */\n    if (fseek(fpStream, 0, SEEK_SET) != 0) {\n        return -2;      /* not seekable, abort */\n    }\n    /* read 10 bytes in case there's an ID3 version 2 header here */\n    nbytes = fread(id3v2Header, 1, sizeof(id3v2Header), fpStream);\n    if (nbytes != sizeof(id3v2Header)) {\n        return -3;      /* not readable, maybe opened Write-Only */\n    }\n    /* does the stream begin with the ID3 version 2 file identifier? */\n    if (!strncmp((char *) id3v2Header, \"ID3\", 3)) {\n        /* the tag size (minus the 10-byte header) is encoded into four\n         * bytes where the most significant bit is clear in each byte */\n        id3v2TagSize = (((id3v2Header[6] & 0x7f) << 21)\n                        | ((id3v2Header[7] & 0x7f) << 14)\n                        | ((id3v2Header[8] & 0x7f) << 7)\n                        | (id3v2Header[9] & 0x7f))\n            + sizeof id3v2Header;\n    }\n    else {\n        /* no ID3 version 2 tag in this stream */\n        id3v2TagSize = 0;\n    }\n    return id3v2TagSize;\n}\n\n\n\nsize_t\nlame_get_lametag_frame(lame_global_flags const *gfp, unsigned char *buffer, size_t size)\n{\n    lame_internal_flags *gfc;\n    SessionConfig_t const *cfg;\n    unsigned long stream_size;\n    unsigned int  nStreamIndex;\n    uint8_t btToc[NUMTOCENTRIES];\n\n    if (gfp == 0) {\n        return 0;\n    }\n    gfc = gfp->internal_flags;\n    if (gfc == 0) {\n        return 0;\n    }\n    if (gfc->class_id != LAME_ID) {\n        return 0;\n    }\n    cfg = &gfc->cfg;\n    if (cfg->write_lame_tag == 0) {\n        return 0;\n    }\n    if (gfc->VBR_seek_table.pos <= 0) {\n        return 0;\n    }\n    if (size < gfc->VBR_seek_table.TotalFrameSize) {\n        return gfc->VBR_seek_table.TotalFrameSize;\n    }\n    if (buffer == 0) {\n        return 0;\n    }\n\n    memset(buffer, 0, gfc->VBR_seek_table.TotalFrameSize);\n\n    /* 4 bytes frame header */\n\n    setLameTagFrameHeader(gfc, buffer);\n\n    /* Clear all TOC entries */\n    memset(btToc, 0, sizeof(btToc));\n\n    if (cfg->free_format) {\n        int     i;\n        for (i = 1; i < NUMTOCENTRIES; ++i)\n            btToc[i] = 255 * i / 100;\n    }\n    else {\n        Xing_seek_table(&gfc->VBR_seek_table, btToc);\n    }\n#ifdef DEBUG_VBR_SEEKING_TABLE\n    print_seeking(btToc);\n#endif\n\n    /* Start writing the tag after the zero frame */\n    nStreamIndex = cfg->sideinfo_len;\n    /* note! Xing header specifies that Xing data goes in the\n     * ancillary data with NO ERROR PROTECTION.  If error protecton\n     * in enabled, the Xing data still starts at the same offset,\n     * and now it is in sideinfo data block, and thus will not\n     * decode correctly by non-Xing tag aware players */\n    if (cfg->error_protection)\n        nStreamIndex -= 2;\n\n    /* Put Vbr tag */\n    if (cfg->vbr == vbr_off) {\n        buffer[nStreamIndex++] = VBRTag1[0];\n        buffer[nStreamIndex++] = VBRTag1[1];\n        buffer[nStreamIndex++] = VBRTag1[2];\n        buffer[nStreamIndex++] = VBRTag1[3];\n\n    }\n    else {\n        buffer[nStreamIndex++] = VBRTag0[0];\n        buffer[nStreamIndex++] = VBRTag0[1];\n        buffer[nStreamIndex++] = VBRTag0[2];\n        buffer[nStreamIndex++] = VBRTag0[3];\n    }\n\n    /* Put header flags */\n    CreateI4(&buffer[nStreamIndex], FRAMES_FLAG + BYTES_FLAG + TOC_FLAG + VBR_SCALE_FLAG);\n    nStreamIndex += 4;\n\n    /* Put Total Number of frames */\n    CreateI4(&buffer[nStreamIndex], gfc->VBR_seek_table.nVbrNumFrames);\n    nStreamIndex += 4;\n\n    /* Put total audio stream size, including Xing/LAME Header */\n    stream_size = gfc->VBR_seek_table.nBytesWritten + gfc->VBR_seek_table.TotalFrameSize;\n    CreateI4(&buffer[nStreamIndex], stream_size);\n    nStreamIndex += 4;\n\n    /* Put TOC */\n    memcpy(&buffer[nStreamIndex], btToc, sizeof(btToc));\n    nStreamIndex += sizeof(btToc);\n\n\n    if (cfg->error_protection) {\n        /* (jo) error_protection: add crc16 information to header */\n        CRC_writeheader(gfc, (char *) buffer);\n    }\n    {\n        /*work out CRC so far: initially crc = 0 */\n        uint16_t crc = 0x00;\n        unsigned int i;\n        for (i = 0; i < nStreamIndex; i++)\n            crc = CRC_update_lookup(buffer[i], crc);\n        /*Put LAME VBR info */\n        nStreamIndex += PutLameVBR(gfp, stream_size, buffer + nStreamIndex, crc);\n    }\n\n#ifdef DEBUG_VBRTAG\n    {\n        VBRTAGDATA TestHeader;\n        GetVbrTag(&TestHeader, buffer);\n    }\n#endif\n\n    return gfc->VBR_seek_table.TotalFrameSize;\n}\n\n/***********************************************************************\n *\n * PutVbrTag: Write final VBR tag to the file\n * Paramters:\n *                              lpszFileName: filename of MP3 bit stream\n *                              nVbrScale       : encoder quality indicator (0..100)\n ****************************************************************************\n */\n\nint\nPutVbrTag(lame_global_flags const *gfp, FILE * fpStream)\n{\n    lame_internal_flags *gfc = gfp->internal_flags;\n\n    long    lFileSize;\n    long    id3v2TagSize;\n    size_t  nbytes;\n    uint8_t buffer[MAXFRAMESIZE];\n\n    if (gfc->VBR_seek_table.pos <= 0)\n        return -1;\n\n    /* Seek to end of file */\n    fseek(fpStream, 0, SEEK_END);\n\n    /* Get file size */\n    lFileSize = ftell(fpStream);\n\n    /* Abort if file has zero length. Yes, it can happen :) */\n    if (lFileSize == 0)\n        return -1;\n\n    /*\n     * The VBR tag may NOT be located at the beginning of the stream.\n     * If an ID3 version 2 tag was added, then it must be skipped to write\n     * the VBR tag data.\n     */\n\n    id3v2TagSize = skipId3v2(fpStream);\n\n    if (id3v2TagSize < 0) {\n        return id3v2TagSize;\n    }\n\n    /*Seek to the beginning of the stream */\n    fseek(fpStream, id3v2TagSize, SEEK_SET);\n\n    nbytes = lame_get_lametag_frame(gfp, buffer, sizeof(buffer));\n    if (nbytes > sizeof(buffer)) {\n        return -1;\n    }\n\n    if (nbytes < 1) {\n        return 0;\n    }\n\n    /* Put it all to disk again */\n    if (fwrite(buffer, nbytes, 1, fpStream) != 1) {\n        return -1;\n    }\n\n    return 0;           /* success */\n}\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/VbrTag.h",
    "content": "/*\n *      Xing VBR tagging for LAME.\n *\n *      Copyright (c) 1999 A.L. Faber\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n#ifndef LAME_VRBTAG_H\n#define LAME_VRBTAG_H\n\n\n/* -----------------------------------------------------------\n * A Vbr header may be present in the ancillary\n * data field of the first frame of an mp3 bitstream\n * The Vbr header (optionally) contains\n *      frames      total number of audio frames in the bitstream\n *      bytes       total number of bytes in the bitstream\n *      toc         table of contents\n\n * toc (table of contents) gives seek points\n * for random access\n * the ith entry determines the seek point for\n * i-percent duration\n * seek point in bytes = (toc[i]/256.0) * total_bitstream_bytes\n * e.g. half duration seek point = (toc[50]/256.0) * total_bitstream_bytes\n */\n\n\n#define FRAMES_FLAG     0x0001\n#define BYTES_FLAG      0x0002\n#define TOC_FLAG        0x0004\n#define VBR_SCALE_FLAG  0x0008\n\n#define NUMTOCENTRIES 100\n\n#ifndef lame_internal_flags_defined\n#define lame_internal_flags_defined\nstruct lame_internal_flags;\ntypedef struct lame_internal_flags lame_internal_flags;\n#endif\n\n\n/*structure to receive extracted header */\n/* toc may be NULL*/\ntypedef struct {\n    int     h_id;            /* from MPEG header, 0=MPEG2, 1=MPEG1 */\n    int     samprate;        /* determined from MPEG header */\n    int     flags;           /* from Vbr header data */\n    int     frames;          /* total bit stream frames from Vbr header data */\n    int     bytes;           /* total bit stream bytes from Vbr header data */\n    int     vbr_scale;       /* encoded vbr scale from Vbr header data */\n    unsigned char toc[NUMTOCENTRIES]; /* may be NULL if toc not desired */\n    int     headersize;      /* size of VBR header, in bytes */\n    int     enc_delay;       /* encoder delay */\n    int     enc_padding;     /* encoder paddign added at end of stream */\n} VBRTAGDATA;\n\nint     GetVbrTag(VBRTAGDATA * pTagData, const unsigned char *buf);\n\nint     InitVbrTag(lame_global_flags * gfp);\nint     PutVbrTag(lame_global_flags const *gfp, FILE * fid);\nvoid    AddVbrFrame(lame_internal_flags * gfc);\nvoid    UpdateMusicCRC(uint16_t * crc, const unsigned char *buffer, int size);\n\n#endif\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/bitstream.c",
    "content": "/*\n *      MP3 bitstream Output interface for LAME\n *\n *      Copyright (c) 1999-2000 Mark Taylor\n *      Copyright (c) 1999-2002 Takehiro Tominaga\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n *\n * $Id: bitstream.c,v 1.97 2011/05/07 16:05:17 rbrito Exp $\n */\n\n\n#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n\n#include <stdlib.h>\n#include <stdio.h>\n\n#include \"lame.h\"\n#include \"machine.h\"\n#include \"encoder.h\"\n#include \"util.h\"\n#include \"tables.h\"\n#include \"quantize_pvt.h\"\n#include \"lame_global_flags.h\"\n#include \"gain_analysis.h\"\n#include \"VbrTag.h\"\n#include \"bitstream.h\"\n#include \"tables.h\"\n\n\n\n/* unsigned int is at least this large:  */\n/* we work with ints, so when doing bit manipulation, we limit\n * ourselves to MAX_LENGTH-2 just to be on the safe side */\n#define MAX_LENGTH      32\n\n\n\n#ifdef DEBUG\nstatic int hogege;\n#endif\n\n\n\nstatic int\ncalcFrameLength(SessionConfig_t const *const cfg, int kbps, int pad)\n{\n  return 8 * ((cfg->version + 1) * 72000 * kbps / cfg->samplerate_out + pad);\n}\n\n\n/***********************************************************************\n * compute bitsperframe and mean_bits for a layer III frame\n **********************************************************************/\nint\ngetframebits(const lame_internal_flags * gfc)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    EncResult_t const *const eov = &gfc->ov_enc;\n    int     bit_rate;\n\n    /* get bitrate in kbps [?] */\n    if (eov->bitrate_index)\n        bit_rate = bitrate_table[cfg->version][eov->bitrate_index];\n    else\n        bit_rate = cfg->avg_bitrate;\n    /*assert(bit_rate <= 550); */\n    assert(8 <= bit_rate && bit_rate <= 640);\n\n    /* main encoding routine toggles padding on and off */\n    /* one Layer3 Slot consists of 8 bits */\n    return calcFrameLength(cfg, bit_rate, eov->padding);\n}\n\nint\nget_max_frame_buffer_size_by_constraint(SessionConfig_t const * cfg, int constraint)\n{\n    int     maxmp3buf = 0;\n    if (cfg->avg_bitrate > 320) {\n        /* in freeformat the buffer is constant */\n        if (constraint == MDB_STRICT_ISO) {\n            maxmp3buf = calcFrameLength(cfg, cfg->avg_bitrate, 0);\n        }\n        else {\n            /* maximum allowed bits per granule are 7680 */\n            maxmp3buf = 7680 * (cfg->version + 1);\n        }\n    }\n    else {\n        int     max_kbps;\n        if (cfg->samplerate_out < 16000) {\n            max_kbps = bitrate_table[cfg->version][8]; /* default: allow 64 kbps (MPEG-2.5) */\n        }\n        else {\n            max_kbps = bitrate_table[cfg->version][14];\n        }\n        switch (constraint) \n        {\n        default:\n        case MDB_DEFAULT:\n            /* Bouvigne suggests this more lax interpretation of the ISO doc instead of using 8*960. */\n            /* All mp3 decoders should have enough buffer to handle this value: size of a 320kbps 32kHz frame */\n            maxmp3buf = 8 * 1440;\n            break;\n        case MDB_STRICT_ISO:\n            maxmp3buf = calcFrameLength(cfg, max_kbps, 0);\n            break;\n        case MDB_MAXIMUM:\n            maxmp3buf = 7680 * (cfg->version + 1);\n            break;\n        }\n    }\n    return maxmp3buf;\n}\n\n\nstatic void\nputheader_bits(lame_internal_flags * gfc)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    EncStateVar_t *const esv = &gfc->sv_enc;\n    Bit_stream_struc *bs = &gfc->bs;\n#ifdef DEBUG\n    hogege += cfg->sideinfo_len * 8;\n#endif\n    memcpy(&bs->buf[bs->buf_byte_idx], esv->header[esv->w_ptr].buf, cfg->sideinfo_len);\n    bs->buf_byte_idx += cfg->sideinfo_len;\n    bs->totbit += cfg->sideinfo_len * 8;\n    esv->w_ptr = (esv->w_ptr + 1) & (MAX_HEADER_BUF - 1);\n}\n\n\n\n\n/*write j bits into the bit stream */\ninline static void\nputbits2(lame_internal_flags * gfc, int val, int j)\n{\n    EncStateVar_t const *const esv = &gfc->sv_enc;\n    Bit_stream_struc *bs;\n    bs = &gfc->bs;\n\n    assert(j < MAX_LENGTH - 2);\n\n    while (j > 0) {\n        int     k;\n        if (bs->buf_bit_idx == 0) {\n            bs->buf_bit_idx = 8;\n            bs->buf_byte_idx++;\n            assert(bs->buf_byte_idx < BUFFER_SIZE);\n            assert(esv->header[esv->w_ptr].write_timing >= bs->totbit);\n            if (esv->header[esv->w_ptr].write_timing == bs->totbit) {\n                putheader_bits(gfc);\n            }\n            bs->buf[bs->buf_byte_idx] = 0;\n        }\n\n        k = Min(j, bs->buf_bit_idx);\n        j -= k;\n\n        bs->buf_bit_idx -= k;\n\n        assert(j < MAX_LENGTH); /* 32 too large on 32 bit machines */\n        assert(bs->buf_bit_idx < MAX_LENGTH);\n\n        bs->buf[bs->buf_byte_idx] |= ((val >> j) << bs->buf_bit_idx);\n        bs->totbit += k;\n    }\n}\n\n/*write j bits into the bit stream, ignoring frame headers */\ninline static void\nputbits_noheaders(lame_internal_flags * gfc, int val, int j)\n{\n    Bit_stream_struc *bs;\n    bs = &gfc->bs;\n\n    assert(j < MAX_LENGTH - 2);\n\n    while (j > 0) {\n        int     k;\n        if (bs->buf_bit_idx == 0) {\n            bs->buf_bit_idx = 8;\n            bs->buf_byte_idx++;\n            assert(bs->buf_byte_idx < BUFFER_SIZE);\n            bs->buf[bs->buf_byte_idx] = 0;\n        }\n\n        k = Min(j, bs->buf_bit_idx);\n        j -= k;\n\n        bs->buf_bit_idx -= k;\n\n        assert(j < MAX_LENGTH); /* 32 too large on 32 bit machines */\n        assert(bs->buf_bit_idx < MAX_LENGTH);\n\n        bs->buf[bs->buf_byte_idx] |= ((val >> j) << bs->buf_bit_idx);\n        bs->totbit += k;\n    }\n}\n\n\n/*\n  Some combinations of bitrate, Fs, and stereo make it impossible to stuff\n  out a frame using just main_data, due to the limited number of bits to\n  indicate main_data_length. In these situations, we put stuffing bits into\n  the ancillary data...\n*/\n\ninline static void\ndrain_into_ancillary(lame_internal_flags * gfc, int remainingBits)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    EncStateVar_t *const esv = &gfc->sv_enc;\n    int     i;\n    assert(remainingBits >= 0);\n\n    if (remainingBits >= 8) {\n        putbits2(gfc, 0x4c, 8);\n        remainingBits -= 8;\n    }\n    if (remainingBits >= 8) {\n        putbits2(gfc, 0x41, 8);\n        remainingBits -= 8;\n    }\n    if (remainingBits >= 8) {\n        putbits2(gfc, 0x4d, 8);\n        remainingBits -= 8;\n    }\n    if (remainingBits >= 8) {\n        putbits2(gfc, 0x45, 8);\n        remainingBits -= 8;\n    }\n\n    if (remainingBits >= 32) {\n        const char *const version = get_lame_short_version();\n        if (remainingBits >= 32)\n            for (i = 0; i < (int) strlen(version) && remainingBits >= 8; ++i) {\n                remainingBits -= 8;\n                putbits2(gfc, version[i], 8);\n            }\n    }\n\n    for (; remainingBits >= 1; remainingBits -= 1) {\n        putbits2(gfc, esv->ancillary_flag, 1);\n        esv->ancillary_flag ^= !cfg->disable_reservoir;\n    }\n\n    assert(remainingBits == 0);\n\n}\n\n/*write N bits into the header */\ninline static void\nwriteheader(lame_internal_flags * gfc, int val, int j)\n{\n    EncStateVar_t *const esv = &gfc->sv_enc;\n    int     ptr = esv->header[esv->h_ptr].ptr;\n\n    while (j > 0) {\n        int const k = Min(j, 8 - (ptr & 7));\n        j -= k;\n        assert(j < MAX_LENGTH); /* >> 32  too large for 32 bit machines */\n        esv->header[esv->h_ptr].buf[ptr >> 3]\n            |= ((val >> j)) << (8 - (ptr & 7) - k);\n        ptr += k;\n    }\n    esv->header[esv->h_ptr].ptr = ptr;\n}\n\n\nstatic int\nCRC_update(int value, int crc)\n{\n    int     i;\n    value <<= 8;\n    for (i = 0; i < 8; i++) {\n        value <<= 1;\n        crc <<= 1;\n\n        if (((crc ^ value) & 0x10000))\n            crc ^= CRC16_POLYNOMIAL;\n    }\n    return crc;\n}\n\n\nvoid\nCRC_writeheader(lame_internal_flags const *gfc, char *header)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    int     crc = 0xffff;    /* (jo) init crc16 for error_protection */\n    int     i;\n\n    crc = CRC_update(((unsigned char *) header)[2], crc);\n    crc = CRC_update(((unsigned char *) header)[3], crc);\n    for (i = 6; i < cfg->sideinfo_len; i++) {\n        crc = CRC_update(((unsigned char *) header)[i], crc);\n    }\n\n    header[4] = crc >> 8;\n    header[5] = crc & 255;\n}\n\ninline static void\nencodeSideInfo2(lame_internal_flags * gfc, int bitsPerFrame)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    EncResult_t const *const eov = &gfc->ov_enc;\n    EncStateVar_t *const esv = &gfc->sv_enc;\n    III_side_info_t *l3_side;\n    int     gr, ch;\n\n    l3_side = &gfc->l3_side;\n    esv->header[esv->h_ptr].ptr = 0;\n    memset(esv->header[esv->h_ptr].buf, 0, cfg->sideinfo_len);\n    if (cfg->samplerate_out < 16000)\n        writeheader(gfc, 0xffe, 12);\n    else\n        writeheader(gfc, 0xfff, 12);\n    writeheader(gfc, (cfg->version), 1);\n    writeheader(gfc, 4 - 3, 2);\n    writeheader(gfc, (!cfg->error_protection), 1);\n    writeheader(gfc, (eov->bitrate_index), 4);\n    writeheader(gfc, (cfg->samplerate_index), 2);\n    writeheader(gfc, (eov->padding), 1);\n    writeheader(gfc, (cfg->extension), 1);\n    writeheader(gfc, (cfg->mode), 2);\n    writeheader(gfc, (eov->mode_ext), 2);\n    writeheader(gfc, (cfg->copyright), 1);\n    writeheader(gfc, (cfg->original), 1);\n    writeheader(gfc, (cfg->emphasis), 2);\n    if (cfg->error_protection) {\n        writeheader(gfc, 0, 16); /* dummy */\n    }\n\n    if (cfg->version == 1) {\n        /* MPEG1 */\n        assert(l3_side->main_data_begin >= 0);\n        writeheader(gfc, (l3_side->main_data_begin), 9);\n\n        if (cfg->channels_out == 2)\n            writeheader(gfc, l3_side->private_bits, 3);\n        else\n            writeheader(gfc, l3_side->private_bits, 5);\n\n        for (ch = 0; ch < cfg->channels_out; ch++) {\n            int     band;\n            for (band = 0; band < 4; band++) {\n                writeheader(gfc, l3_side->scfsi[ch][band], 1);\n            }\n        }\n\n        for (gr = 0; gr < 2; gr++) {\n            for (ch = 0; ch < cfg->channels_out; ch++) {\n                gr_info *const gi = &l3_side->tt[gr][ch];\n                writeheader(gfc, gi->part2_3_length + gi->part2_length, 12);\n                writeheader(gfc, gi->big_values / 2, 9);\n                writeheader(gfc, gi->global_gain, 8);\n                writeheader(gfc, gi->scalefac_compress, 4);\n\n                if (gi->block_type != NORM_TYPE) {\n                    writeheader(gfc, 1, 1); /* window_switching_flag */\n                    writeheader(gfc, gi->block_type, 2);\n                    writeheader(gfc, gi->mixed_block_flag, 1);\n\n                    if (gi->table_select[0] == 14)\n                        gi->table_select[0] = 16;\n                    writeheader(gfc, gi->table_select[0], 5);\n                    if (gi->table_select[1] == 14)\n                        gi->table_select[1] = 16;\n                    writeheader(gfc, gi->table_select[1], 5);\n\n                    writeheader(gfc, gi->subblock_gain[0], 3);\n                    writeheader(gfc, gi->subblock_gain[1], 3);\n                    writeheader(gfc, gi->subblock_gain[2], 3);\n                }\n                else {\n                    writeheader(gfc, 0, 1); /* window_switching_flag */\n                    if (gi->table_select[0] == 14)\n                        gi->table_select[0] = 16;\n                    writeheader(gfc, gi->table_select[0], 5);\n                    if (gi->table_select[1] == 14)\n                        gi->table_select[1] = 16;\n                    writeheader(gfc, gi->table_select[1], 5);\n                    if (gi->table_select[2] == 14)\n                        gi->table_select[2] = 16;\n                    writeheader(gfc, gi->table_select[2], 5);\n\n                    assert(0 <= gi->region0_count && gi->region0_count < 16);\n                    assert(0 <= gi->region1_count && gi->region1_count < 8);\n                    writeheader(gfc, gi->region0_count, 4);\n                    writeheader(gfc, gi->region1_count, 3);\n                }\n                writeheader(gfc, gi->preflag, 1);\n                writeheader(gfc, gi->scalefac_scale, 1);\n                writeheader(gfc, gi->count1table_select, 1);\n            }\n        }\n    }\n    else {\n        /* MPEG2 */\n        assert(l3_side->main_data_begin >= 0);\n        writeheader(gfc, (l3_side->main_data_begin), 8);\n        writeheader(gfc, l3_side->private_bits, cfg->channels_out);\n\n        gr = 0;\n        for (ch = 0; ch < cfg->channels_out; ch++) {\n            gr_info *const gi = &l3_side->tt[gr][ch];\n            writeheader(gfc, gi->part2_3_length + gi->part2_length, 12);\n            writeheader(gfc, gi->big_values / 2, 9);\n            writeheader(gfc, gi->global_gain, 8);\n            writeheader(gfc, gi->scalefac_compress, 9);\n\n            if (gi->block_type != NORM_TYPE) {\n                writeheader(gfc, 1, 1); /* window_switching_flag */\n                writeheader(gfc, gi->block_type, 2);\n                writeheader(gfc, gi->mixed_block_flag, 1);\n\n                if (gi->table_select[0] == 14)\n                    gi->table_select[0] = 16;\n                writeheader(gfc, gi->table_select[0], 5);\n                if (gi->table_select[1] == 14)\n                    gi->table_select[1] = 16;\n                writeheader(gfc, gi->table_select[1], 5);\n\n                writeheader(gfc, gi->subblock_gain[0], 3);\n                writeheader(gfc, gi->subblock_gain[1], 3);\n                writeheader(gfc, gi->subblock_gain[2], 3);\n            }\n            else {\n                writeheader(gfc, 0, 1); /* window_switching_flag */\n                if (gi->table_select[0] == 14)\n                    gi->table_select[0] = 16;\n                writeheader(gfc, gi->table_select[0], 5);\n                if (gi->table_select[1] == 14)\n                    gi->table_select[1] = 16;\n                writeheader(gfc, gi->table_select[1], 5);\n                if (gi->table_select[2] == 14)\n                    gi->table_select[2] = 16;\n                writeheader(gfc, gi->table_select[2], 5);\n\n                assert(0 <= gi->region0_count && gi->region0_count < 16);\n                assert(0 <= gi->region1_count && gi->region1_count < 8);\n                writeheader(gfc, gi->region0_count, 4);\n                writeheader(gfc, gi->region1_count, 3);\n            }\n\n            writeheader(gfc, gi->scalefac_scale, 1);\n            writeheader(gfc, gi->count1table_select, 1);\n        }\n    }\n\n    if (cfg->error_protection) {\n        /* (jo) error_protection: add crc16 information to header */\n        CRC_writeheader(gfc, esv->header[esv->h_ptr].buf);\n    }\n\n    {\n        int const old = esv->h_ptr;\n        assert(esv->header[old].ptr == cfg->sideinfo_len * 8);\n\n        esv->h_ptr = (old + 1) & (MAX_HEADER_BUF - 1);\n        esv->header[esv->h_ptr].write_timing = esv->header[old].write_timing + bitsPerFrame;\n\n        if (esv->h_ptr == esv->w_ptr) {\n            /* yikes! we are out of header buffer space */\n            ERRORF(gfc, \"Error: MAX_HEADER_BUF too small in bitstream.c \\n\");\n        }\n\n    }\n}\n\n\ninline static int\nhuffman_coder_count1(lame_internal_flags * gfc, gr_info const *gi)\n{\n    /* Write count1 area */\n    struct huffcodetab const *const h = &ht[gi->count1table_select + 32];\n    int     i, bits = 0;\n#ifdef DEBUG\n    int     gegebo = gfc->bs.totbit;\n#endif\n\n    int const *ix = &gi->l3_enc[gi->big_values];\n    FLOAT const *xr = &gi->xr[gi->big_values];\n    assert(gi->count1table_select < 2);\n\n    for (i = (gi->count1 - gi->big_values) / 4; i > 0; --i) {\n        int     huffbits = 0;\n        int     p = 0, v;\n\n        v = ix[0];\n        if (v) {\n            p += 8;\n            if (xr[0] < 0.0f)\n                huffbits++;\n            assert(v <= 1);\n        }\n\n        v = ix[1];\n        if (v) {\n            p += 4;\n            huffbits *= 2;\n            if (xr[1] < 0.0f)\n                huffbits++;\n            assert(v <= 1);\n        }\n\n        v = ix[2];\n        if (v) {\n            p += 2;\n            huffbits *= 2;\n            if (xr[2] < 0.0f)\n                huffbits++;\n            assert(v <= 1);\n        }\n\n        v = ix[3];\n        if (v) {\n            p++;\n            huffbits *= 2;\n            if (xr[3] < 0.0f)\n                huffbits++;\n            assert(v <= 1);\n        }\n\n        ix += 4;\n        xr += 4;\n        putbits2(gfc, huffbits + h->table[p], h->hlen[p]);\n        bits += h->hlen[p];\n    }\n#ifdef DEBUG\n    DEBUGF(gfc, \"count1: real: %ld counted:%d (bigv %d count1len %d)\\n\",\n           gfc->bs.totbit - gegebo, gi->count1bits, gi->big_values, gi->count1);\n#endif\n    return bits;\n}\n\n\n\n/*\n  Implements the pseudocode of page 98 of the IS\n  */\ninline static int\nHuffmancode(lame_internal_flags * const gfc, const unsigned int tableindex,\n            int start, int end, gr_info const *gi)\n{\n    struct huffcodetab const *const h = &ht[tableindex];\n    unsigned int const linbits = h->xlen;\n    int     i, bits = 0;\n\n    assert(tableindex < 32u);\n    if (!tableindex)\n        return bits;\n\n    for (i = start; i < end; i += 2) {\n        int16_t  cbits = 0;\n        uint16_t xbits = 0;\n        unsigned int xlen = h->xlen;\n        unsigned int ext = 0;\n        unsigned int x1 = gi->l3_enc[i];\n        unsigned int x2 = gi->l3_enc[i + 1];\n\n        assert(gi->l3_enc[i] >= 0);\n        assert(gi->l3_enc[i+1] >= 0);\n\n        if (x1 != 0u) {\n            if (gi->xr[i] < 0.0f)\n                ext++;\n            cbits--;\n        }\n\n        if (tableindex > 15u) {\n            /* use ESC-words */\n            if (x1 >= 15u) {\n                uint16_t const linbits_x1 = x1 - 15u;\n                assert(linbits_x1 <= h->linmax);\n                ext |= linbits_x1 << 1u;\n                xbits = linbits;\n                x1 = 15u;\n            }\n\n            if (x2 >= 15u) {\n                uint16_t const linbits_x2 = x2 - 15u;\n                assert(linbits_x2 <= h->linmax);\n                ext <<= linbits;\n                ext |= linbits_x2;\n                xbits += linbits;\n                x2 = 15u;\n            }\n            xlen = 16;\n        }\n\n        if (x2 != 0u) {\n            ext <<= 1;\n            if (gi->xr[i + 1] < 0.0f)\n                ext++;\n            cbits--;\n        }\n\n        assert((x1 | x2) < 16u);\n\n        x1 = x1 * xlen + x2;\n        xbits -= cbits;\n        cbits += h->hlen[x1];\n\n        assert(cbits <= MAX_LENGTH);\n        assert(xbits <= MAX_LENGTH);\n\n        putbits2(gfc, h->table[x1], cbits);\n        putbits2(gfc, (int)ext, xbits);\n        bits += cbits + xbits;\n    }\n    return bits;\n}\n\n/*\n  Note the discussion of huffmancodebits() on pages 28\n  and 29 of the IS, as well as the definitions of the side\n  information on pages 26 and 27.\n  */\nstatic int\nShortHuffmancodebits(lame_internal_flags * gfc, gr_info const *gi)\n{\n    int     bits;\n    int     region1Start;\n\n    region1Start = 3 * gfc->scalefac_band.s[3];\n    if (region1Start > gi->big_values)\n        region1Start = gi->big_values;\n\n    /* short blocks do not have a region2 */\n    bits = Huffmancode(gfc, gi->table_select[0], 0, region1Start, gi);\n    bits += Huffmancode(gfc, gi->table_select[1], region1Start, gi->big_values, gi);\n    return bits;\n}\n\nstatic int\nLongHuffmancodebits(lame_internal_flags * gfc, gr_info const *gi)\n{\n    unsigned int i;\n    int     bigvalues, bits;\n    int     region1Start, region2Start;\n\n    bigvalues = gi->big_values;\n    assert(0 <= bigvalues && bigvalues <= 576);\n\n    assert(gi->region0_count >= -1);\n    assert(gi->region1_count >= -1);\n    i = gi->region0_count + 1;\n    assert((size_t) i < dimension_of(gfc->scalefac_band.l));\n    region1Start = gfc->scalefac_band.l[i];\n    i += gi->region1_count + 1;\n    assert((size_t) i < dimension_of(gfc->scalefac_band.l));\n    region2Start = gfc->scalefac_band.l[i];\n\n    if (region1Start > bigvalues)\n        region1Start = bigvalues;\n\n    if (region2Start > bigvalues)\n        region2Start = bigvalues;\n\n    bits = Huffmancode(gfc, gi->table_select[0], 0, region1Start, gi);\n    bits += Huffmancode(gfc, gi->table_select[1], region1Start, region2Start, gi);\n    bits += Huffmancode(gfc, gi->table_select[2], region2Start, bigvalues, gi);\n    return bits;\n}\n\ninline static int\nwriteMainData(lame_internal_flags * const gfc)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    III_side_info_t const *const l3_side = &gfc->l3_side;\n    int     gr, ch, sfb, data_bits, tot_bits = 0;\n\n    if (cfg->version == 1) {\n        /* MPEG 1 */\n        for (gr = 0; gr < 2; gr++) {\n            for (ch = 0; ch < cfg->channels_out; ch++) {\n                gr_info const *const gi = &l3_side->tt[gr][ch];\n                int const slen1 = slen1_tab[gi->scalefac_compress];\n                int const slen2 = slen2_tab[gi->scalefac_compress];\n                data_bits = 0;\n#ifdef DEBUG\n                hogege = gfc->bs.totbit;\n#endif\n                for (sfb = 0; sfb < gi->sfbdivide; sfb++) {\n                    if (gi->scalefac[sfb] == -1)\n                        continue; /* scfsi is used */\n                    putbits2(gfc, gi->scalefac[sfb], slen1);\n                    data_bits += slen1;\n                }\n                for (; sfb < gi->sfbmax; sfb++) {\n                    if (gi->scalefac[sfb] == -1)\n                        continue; /* scfsi is used */\n                    putbits2(gfc, gi->scalefac[sfb], slen2);\n                    data_bits += slen2;\n                }\n                assert(data_bits == gi->part2_length);\n\n                if (gi->block_type == SHORT_TYPE) {\n                    data_bits += ShortHuffmancodebits(gfc, gi);\n                }\n                else {\n                    data_bits += LongHuffmancodebits(gfc, gi);\n                }\n                data_bits += huffman_coder_count1(gfc, gi);\n#ifdef DEBUG\n                DEBUGF(gfc, \"<%ld> \", gfc->bs.totbit - hogege);\n#endif\n                /* does bitcount in quantize.c agree with actual bit count? */\n                assert(data_bits == gi->part2_3_length + gi->part2_length);\n                tot_bits += data_bits;\n            }           /* for ch */\n        }               /* for gr */\n    }\n    else {\n        /* MPEG 2 */\n        gr = 0;\n        for (ch = 0; ch < cfg->channels_out; ch++) {\n            gr_info const *const gi = &l3_side->tt[gr][ch];\n            int     i, sfb_partition, scale_bits = 0;\n            assert(gi->sfb_partition_table);\n            data_bits = 0;\n#ifdef DEBUG\n            hogege = gfc->bs.totbit;\n#endif\n            sfb = 0;\n            sfb_partition = 0;\n\n            if (gi->block_type == SHORT_TYPE) {\n                for (; sfb_partition < 4; sfb_partition++) {\n                    int const sfbs = gi->sfb_partition_table[sfb_partition] / 3;\n                    int const slen = gi->slen[sfb_partition];\n                    for (i = 0; i < sfbs; i++, sfb++) {\n                        putbits2(gfc, Max(gi->scalefac[sfb * 3 + 0], 0), slen);\n                        putbits2(gfc, Max(gi->scalefac[sfb * 3 + 1], 0), slen);\n                        putbits2(gfc, Max(gi->scalefac[sfb * 3 + 2], 0), slen);\n                        scale_bits += 3 * slen;\n                    }\n                }\n                data_bits += ShortHuffmancodebits(gfc, gi);\n            }\n            else {\n                for (; sfb_partition < 4; sfb_partition++) {\n                    int const sfbs = gi->sfb_partition_table[sfb_partition];\n                    int const slen = gi->slen[sfb_partition];\n                    for (i = 0; i < sfbs; i++, sfb++) {\n                        putbits2(gfc, Max(gi->scalefac[sfb], 0), slen);\n                        scale_bits += slen;\n                    }\n                }\n                data_bits += LongHuffmancodebits(gfc, gi);\n            }\n            data_bits += huffman_coder_count1(gfc, gi);\n#ifdef DEBUG\n            DEBUGF(gfc, \"<%ld> \", gfc->bs.totbit - hogege);\n#endif\n            /* does bitcount in quantize.c agree with actual bit count? */\n            assert(data_bits == gi->part2_3_length);\n            assert(scale_bits == gi->part2_length);\n            tot_bits += scale_bits + data_bits;\n        }               /* for ch */\n    }                   /* for gf */\n    return tot_bits;\n}                       /* main_data */\n\n\n\n/* compute the number of bits required to flush all mp3 frames\n   currently in the buffer.  This should be the same as the\n   reservoir size.  Only call this routine between frames - i.e.\n   only after all headers and data have been added to the buffer\n   by format_bitstream().\n\n   Also compute total_bits_output =\n       size of mp3 buffer (including frame headers which may not\n       have yet been send to the mp3 buffer) +\n       number of bits needed to flush all mp3 frames.\n\n   total_bytes_output is the size of the mp3 output buffer if\n   lame_encode_flush_nogap() was called right now.\n\n */\nint\ncompute_flushbits(const lame_internal_flags * gfc, int *total_bytes_output)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    EncStateVar_t const *const esv = &gfc->sv_enc;\n    int     flushbits, remaining_headers;\n    int     bitsPerFrame;\n    int     last_ptr, first_ptr;\n    first_ptr = esv->w_ptr; /* first header to add to bitstream */\n    last_ptr = esv->h_ptr - 1; /* last header to add to bitstream */\n    if (last_ptr == -1)\n        last_ptr = MAX_HEADER_BUF - 1;\n\n    /* add this many bits to bitstream so we can flush all headers */\n    flushbits = esv->header[last_ptr].write_timing - gfc->bs.totbit;\n    *total_bytes_output = flushbits;\n\n    if (flushbits >= 0) {\n        /* if flushbits >= 0, some headers have not yet been written */\n        /* reduce flushbits by the size of the headers */\n        remaining_headers = 1 + last_ptr - first_ptr;\n        if (last_ptr < first_ptr)\n            remaining_headers = 1 + last_ptr - first_ptr + MAX_HEADER_BUF;\n        flushbits -= remaining_headers * 8 * cfg->sideinfo_len;\n    }\n\n\n    /* finally, add some bits so that the last frame is complete\n     * these bits are not necessary to decode the last frame, but\n     * some decoders will ignore last frame if these bits are missing\n     */\n    bitsPerFrame = getframebits(gfc);\n    flushbits += bitsPerFrame;\n    *total_bytes_output += bitsPerFrame;\n    /* round up:   */\n    if (*total_bytes_output % 8)\n        *total_bytes_output = 1 + (*total_bytes_output / 8);\n    else\n        *total_bytes_output = (*total_bytes_output / 8);\n    *total_bytes_output += gfc->bs.buf_byte_idx + 1;\n\n\n    if (flushbits < 0) {\n#if 0\n        /* if flushbits < 0, this would mean that the buffer looks like:\n         * (data...)  last_header  (data...)  (extra data that should not be here...)\n         */\n        DEBUGF(gfc, \"last header write_timing = %i \\n\", esv->header[last_ptr].write_timing);\n        DEBUGF(gfc, \"first header write_timing = %i \\n\", esv->header[first_ptr].write_timing);\n        DEBUGF(gfc, \"bs.totbit:                 %i \\n\", gfc->bs.totbit);\n        DEBUGF(gfc, \"first_ptr, last_ptr        %i %i \\n\", first_ptr, last_ptr);\n        DEBUGF(gfc, \"remaining_headers =        %i \\n\", remaining_headers);\n        DEBUGF(gfc, \"bitsperframe:              %i \\n\", bitsPerFrame);\n        DEBUGF(gfc, \"sidelen:                   %i \\n\", cfg->sideinfo_len);\n#endif\n        ERRORF(gfc, \"strange error flushing buffer ... \\n\");\n    }\n    return flushbits;\n}\n\n\nvoid\nflush_bitstream(lame_internal_flags * gfc)\n{\n    EncStateVar_t *const esv = &gfc->sv_enc;\n    III_side_info_t *l3_side;\n    int     nbytes;\n    int     flushbits;\n    int     last_ptr = esv->h_ptr - 1; /* last header to add to bitstream */\n    if (last_ptr == -1)\n        last_ptr = MAX_HEADER_BUF - 1;\n    l3_side = &gfc->l3_side;\n\n\n    if ((flushbits = compute_flushbits(gfc, &nbytes)) < 0)\n        return;\n    drain_into_ancillary(gfc, flushbits);\n\n    /* check that the 100% of the last frame has been written to bitstream */\n    assert(esv->header[last_ptr].write_timing + getframebits(gfc)\n           == gfc->bs.totbit);\n\n    /* we have padded out all frames with ancillary data, which is the\n       same as filling the bitreservoir with ancillary data, so : */\n    esv->ResvSize = 0;\n    l3_side->main_data_begin = 0;\n}\n\n\n\n\nvoid\nadd_dummy_byte(lame_internal_flags * gfc, unsigned char val, unsigned int n)\n{\n    EncStateVar_t *const esv = &gfc->sv_enc;\n    int     i;\n\n    while (n-- > 0u) {\n        putbits_noheaders(gfc, val, 8);\n\n        for (i = 0; i < MAX_HEADER_BUF; ++i)\n            esv->header[i].write_timing += 8;\n    }\n}\n\n\n/*\n  format_bitstream()\n\n  This is called after a frame of audio has been quantized and coded.\n  It will write the encoded audio to the bitstream. Note that\n  from a layer3 encoder's perspective the bit stream is primarily\n  a series of main_data() blocks, with header and side information\n  inserted at the proper locations to maintain framing. (See Figure A.7\n  in the IS).\n  */\nint\nformat_bitstream(lame_internal_flags * gfc)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    EncStateVar_t *const esv = &gfc->sv_enc;\n    int     bits, nbytes;\n    III_side_info_t *l3_side;\n    int     bitsPerFrame;\n    l3_side = &gfc->l3_side;\n\n    bitsPerFrame = getframebits(gfc);\n    drain_into_ancillary(gfc, l3_side->resvDrain_pre);\n\n    encodeSideInfo2(gfc, bitsPerFrame);\n    bits = 8 * cfg->sideinfo_len;\n    bits += writeMainData(gfc);\n    drain_into_ancillary(gfc, l3_side->resvDrain_post);\n    bits += l3_side->resvDrain_post;\n\n    l3_side->main_data_begin += (bitsPerFrame - bits) / 8;\n\n    /* compare number of bits needed to clear all buffered mp3 frames\n     * with what we think the resvsize is: */\n    if (compute_flushbits(gfc, &nbytes) != esv->ResvSize) {\n        ERRORF(gfc, \"Internal buffer inconsistency. flushbits <> ResvSize\");\n    }\n\n\n    /* compare main_data_begin for the next frame with what we\n     * think the resvsize is: */\n    if ((l3_side->main_data_begin * 8) != esv->ResvSize) {\n        ERRORF(gfc, \"bit reservoir error: \\n\"\n               \"l3_side->main_data_begin: %i \\n\"\n               \"Resvoir size:             %i \\n\"\n               \"resv drain (post)         %i \\n\"\n               \"resv drain (pre)          %i \\n\"\n               \"header and sideinfo:      %i \\n\"\n               \"data bits:                %i \\n\"\n               \"total bits:               %i (remainder: %i) \\n\"\n               \"bitsperframe:             %i \\n\",\n               8 * l3_side->main_data_begin,\n               esv->ResvSize,\n               l3_side->resvDrain_post,\n               l3_side->resvDrain_pre,\n               8 * cfg->sideinfo_len,\n               bits - l3_side->resvDrain_post - 8 * cfg->sideinfo_len,\n               bits, bits % 8, bitsPerFrame);\n\n        ERRORF(gfc, \"This is a fatal error.  It has several possible causes:\");\n        ERRORF(gfc, \"90%%  LAME compiled with buggy version of gcc using advanced optimizations\");\n        ERRORF(gfc, \" 9%%  Your system is overclocked\");\n        ERRORF(gfc, \" 1%%  bug in LAME encoding library\");\n\n        esv->ResvSize = l3_side->main_data_begin * 8;\n    };\n    assert(gfc->bs.totbit % 8 == 0);\n\n    if (gfc->bs.totbit > 1000000000) {\n        /* to avoid totbit overflow, (at 8h encoding at 128kbs) lets reset bit counter */\n        int     i;\n        for (i = 0; i < MAX_HEADER_BUF; ++i)\n            esv->header[i].write_timing -= gfc->bs.totbit;\n        gfc->bs.totbit = 0;\n    }\n\n\n    return 0;\n}\n\n\nstatic int\ndo_gain_analysis(lame_internal_flags * gfc, unsigned char* buffer, int minimum)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    RpgStateVar_t const *const rsv = &gfc->sv_rpg;\n    RpgResult_t *const rov = &gfc->ov_rpg;\n#ifdef DECODE_ON_THE_FLY\n    if (cfg->decode_on_the_fly) { /* decode the frame */\n        sample_t pcm_buf[2][1152];\n        int     mp3_in = minimum;\n        int     samples_out = -1;\n\n        /* re-synthesis to pcm.  Repeat until we get a samples_out=0 */\n        while (samples_out != 0) {\n\n            samples_out = hip_decode1_unclipped(gfc->hip, buffer, mp3_in, pcm_buf[0], pcm_buf[1]);\n            /* samples_out = 0:  need more data to decode\n             * samples_out = -1:  error.  Lets assume 0 pcm output\n             * samples_out = number of samples output */\n\n            /* set the lenght of the mp3 input buffer to zero, so that in the\n             * next iteration of the loop we will be querying mpglib about\n             * buffered data */\n            mp3_in = 0;\n\n            if (samples_out == -1) {\n                /* error decoding. Not fatal, but might screw up\n                 * the ReplayGain tag. What should we do? Ignore for now */\n                samples_out = 0;\n            }\n            if (samples_out > 0) {\n                /* process the PCM data */\n\n                /* this should not be possible, and indicates we have\n                 * overflown the pcm_buf buffer */\n                assert(samples_out <= 1152);\n\n                if (cfg->findPeakSample) {\n                    int     i;\n                    /* FIXME: is this correct? maybe Max(fabs(pcm),PeakSample) */\n                    for (i = 0; i < samples_out; i++) {\n                        if (pcm_buf[0][i] > rov->PeakSample)\n                            rov->PeakSample = pcm_buf[0][i];\n                        else if (-pcm_buf[0][i] > rov->PeakSample)\n                            rov->PeakSample = -pcm_buf[0][i];\n                    }\n                    if (cfg->channels_out > 1)\n                        for (i = 0; i < samples_out; i++) {\n                            if (pcm_buf[1][i] > rov->PeakSample)\n                                rov->PeakSample = pcm_buf[1][i];\n                            else if (-pcm_buf[1][i] > rov->PeakSample)\n                                rov->PeakSample = -pcm_buf[1][i];\n                        }\n                }\n\n                if (cfg->findReplayGain)\n                    if (AnalyzeSamples\n                        (rsv->rgdata, pcm_buf[0], pcm_buf[1], samples_out,\n                         cfg->channels_out) == GAIN_ANALYSIS_ERROR)\n                        return -6;\n\n            }       /* if (samples_out>0) */\n        }           /* while (samples_out!=0) */\n    }               /* if (gfc->decode_on_the_fly) */\n#endif\n    return minimum;\n}\n\nstatic int\ndo_copy_buffer(lame_internal_flags * gfc, unsigned char *buffer, int size)\n{\n    Bit_stream_struc *const bs = &gfc->bs;\n    int const minimum = bs->buf_byte_idx + 1;\n    if (minimum <= 0)\n        return 0;\n    if (size != 0 && minimum > size)\n        return -1;      /* buffer is too small */\n    memcpy(buffer, bs->buf, minimum);\n    bs->buf_byte_idx = -1;\n    bs->buf_bit_idx = 0;\n    return minimum;\n}\n\n/* copy data out of the internal MP3 bit buffer into a user supplied\n   unsigned char buffer.\n\n   mp3data=0      indicates data in buffer is an id3tags and VBR tags\n   mp3data=1      data is real mp3 frame data.\n\n\n*/\nint\ncopy_buffer(lame_internal_flags * gfc, unsigned char *buffer, int size, int mp3data)\n{\n    int const minimum = do_copy_buffer(gfc, buffer, size);\n    if (minimum > 0 && mp3data) {\n        UpdateMusicCRC(&gfc->nMusicCRC, buffer, minimum);\n\n        /** sum number of bytes belonging to the mp3 stream\n         *  this info will be written into the Xing/LAME header for seeking\n         */\n        gfc->VBR_seek_table.nBytesWritten += minimum;\n\n        return do_gain_analysis(gfc, buffer, minimum);\n    }                   /* if (mp3data) */\n    return minimum;\n}\n\n\nvoid\ninit_bit_stream_w(lame_internal_flags * gfc)\n{\n    EncStateVar_t *const esv = &gfc->sv_enc;\n\n    esv->h_ptr = esv->w_ptr = 0;\n    esv->header[esv->h_ptr].write_timing = 0;\n\n    gfc->bs.buf = (unsigned char *) malloc(BUFFER_SIZE);\n    gfc->bs.buf_size = BUFFER_SIZE;\n    gfc->bs.buf_byte_idx = -1;\n    gfc->bs.buf_bit_idx = 0;\n    gfc->bs.totbit = 0;\n}\n\n/* end of bitstream.c */\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/bitstream.h",
    "content": "/*\n *\tMP3 bitstream Output interface for LAME\n *\n *\tCopyright (c) 1999 Takehiro TOMINAGA\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\t See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n#ifndef LAME_BITSTREAM_H\n#define LAME_BITSTREAM_H\n\nint     getframebits(const lame_internal_flags * gfc);\n\nint     format_bitstream(lame_internal_flags * gfc);\n\nvoid    flush_bitstream(lame_internal_flags * gfc);\nvoid    add_dummy_byte(lame_internal_flags * gfc, unsigned char val, unsigned int n);\n\nint     copy_buffer(lame_internal_flags * gfc, unsigned char *buffer, int buffer_size,\n                    int update_crc);\nvoid    init_bit_stream_w(lame_internal_flags * gfc);\nvoid    CRC_writeheader(lame_internal_flags const *gfc, char *buffer);\nint     compute_flushbits(const lame_internal_flags * gfp, int *nbytes);\n\nint     get_max_frame_buffer_size_by_constraint(SessionConfig_t const * cfg, int constraint);\n\n#endif\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/encoder.c",
    "content": "/*\n *      LAME MP3 encoding engine\n *\n *      Copyright (c) 1999 Mark Taylor\n *      Copyright (c) 2000-2002 Takehiro Tominaga\n *      Copyright (c) 2000-2011 Robert Hegemann\n *      Copyright (c) 2001 Gabriel Bouvigne\n *      Copyright (c) 2001 John Dahlstrom\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n/* $Id: encoder.c,v 1.111 2011/05/07 16:05:17 rbrito Exp $ */\n\n#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n\n\n#include \"lame.h\"\n#include \"machine.h\"\n#include \"encoder.h\"\n#include \"util.h\"\n#include \"lame_global_flags.h\"\n#include \"newmdct.h\"\n#include \"psymodel.h\"\n#include \"lame-analysis.h\"\n#include \"bitstream.h\"\n#include \"VbrTag.h\"\n#include \"quantize_pvt.h\"\n\n\n\n/*\n * auto-adjust of ATH, useful for low volume\n * Gabriel Bouvigne 3 feb 2001\n *\n * modifies some values in\n *   gfp->internal_flags->ATH\n *   (gfc->ATH)\n */\nstatic void\nadjust_ATH(lame_internal_flags const *const gfc)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    FLOAT   gr2_max, max_pow;\n\n    if (gfc->ATH->use_adjust == 0) {\n        gfc->ATH->adjust_factor = 1.0; /* no adjustment */\n        return;\n    }\n\n    /* jd - 2001 mar 12, 27, jun 30 */\n    /* loudness based on equal loudness curve; */\n    /* use granule with maximum combined loudness */\n    max_pow = gfc->ov_psy.loudness_sq[0][0];\n    gr2_max = gfc->ov_psy.loudness_sq[1][0];\n    if (cfg->channels_out == 2) {\n        max_pow += gfc->ov_psy.loudness_sq[0][1];\n        gr2_max += gfc->ov_psy.loudness_sq[1][1];\n    }\n    else {\n        max_pow += max_pow;\n        gr2_max += gr2_max;\n    }\n    if (cfg->mode_gr == 2) {\n        max_pow = Max(max_pow, gr2_max);\n    }\n    max_pow *= 0.5;     /* max_pow approaches 1.0 for full band noise */\n\n    /* jd - 2001 mar 31, jun 30 */\n    /* user tuning of ATH adjustment region */\n    max_pow *= gfc->ATH->aa_sensitivity_p;\n\n    /*  adjust ATH depending on range of maximum value\n     */\n\n    /* jd - 2001 feb27, mar12,20, jun30, jul22 */\n    /* continuous curves based on approximation */\n    /* to GB's original values. */\n    /* For an increase in approximate loudness, */\n    /* set ATH adjust to adjust_limit immediately */\n    /* after a delay of one frame. */\n    /* For a loudness decrease, reduce ATH adjust */\n    /* towards adjust_limit gradually. */\n    /* max_pow is a loudness squared or a power. */\n    if (max_pow > 0.03125) { /* ((1 - 0.000625)/ 31.98) from curve below */\n        if (gfc->ATH->adjust_factor >= 1.0) {\n            gfc->ATH->adjust_factor = 1.0;\n        }\n        else {\n            /* preceding frame has lower ATH adjust; */\n            /* ascend only to the preceding adjust_limit */\n            /* in case there is leading low volume */\n            if (gfc->ATH->adjust_factor < gfc->ATH->adjust_limit) {\n                gfc->ATH->adjust_factor = gfc->ATH->adjust_limit;\n            }\n        }\n        gfc->ATH->adjust_limit = 1.0;\n    }\n    else {              /* adjustment curve */\n        /* about 32 dB maximum adjust (0.000625) */\n        FLOAT const adj_lim_new = 31.98 * max_pow + 0.000625;\n        if (gfc->ATH->adjust_factor >= adj_lim_new) { /* descend gradually */\n            gfc->ATH->adjust_factor *= adj_lim_new * 0.075 + 0.925;\n            if (gfc->ATH->adjust_factor < adj_lim_new) { /* stop descent */\n                gfc->ATH->adjust_factor = adj_lim_new;\n            }\n        }\n        else {          /* ascend */\n            if (gfc->ATH->adjust_limit >= adj_lim_new) {\n                gfc->ATH->adjust_factor = adj_lim_new;\n            }\n            else {      /* preceding frame has lower ATH adjust; */\n                /* ascend only to the preceding adjust_limit */\n                if (gfc->ATH->adjust_factor < gfc->ATH->adjust_limit) {\n                    gfc->ATH->adjust_factor = gfc->ATH->adjust_limit;\n                }\n            }\n        }\n        gfc->ATH->adjust_limit = adj_lim_new;\n    }\n}\n\n/***********************************************************************\n *\n *  some simple statistics\n *\n *  bitrate index 0: free bitrate -> not allowed in VBR mode\n *  : bitrates, kbps depending on MPEG version\n *  bitrate index 15: forbidden\n *\n *  mode_ext:\n *  0:  LR\n *  1:  LR-i\n *  2:  MS\n *  3:  MS-i\n *\n ***********************************************************************/\n\nstatic void\nupdateStats(lame_internal_flags * const gfc)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    EncResult_t *eov = &gfc->ov_enc;\n    int     gr, ch;\n    assert(0 <= eov->bitrate_index && eov->bitrate_index < 16);\n    assert(0 <= eov->mode_ext && eov->mode_ext < 4);\n\n    /* count bitrate indices */\n    eov->bitrate_channelmode_hist[eov->bitrate_index][4]++;\n    eov->bitrate_channelmode_hist[15][4]++;\n\n    /* count 'em for every mode extension in case of 2 channel encoding */\n    if (cfg->channels_out == 2) {\n        eov->bitrate_channelmode_hist[eov->bitrate_index][eov->mode_ext]++;\n        eov->bitrate_channelmode_hist[15][eov->mode_ext]++;\n    }\n    for (gr = 0; gr < cfg->mode_gr; ++gr) {\n        for (ch = 0; ch < cfg->channels_out; ++ch) {\n            int     bt = gfc->l3_side.tt[gr][ch].block_type;\n            if (gfc->l3_side.tt[gr][ch].mixed_block_flag)\n                bt = 4;\n            eov->bitrate_blocktype_hist[eov->bitrate_index][bt]++;\n            eov->bitrate_blocktype_hist[eov->bitrate_index][5]++;\n            eov->bitrate_blocktype_hist[15][bt]++;\n            eov->bitrate_blocktype_hist[15][5]++;\n        }\n    }\n}\n\n\n\n\nstatic void\nlame_encode_frame_init(lame_internal_flags * gfc, const sample_t *const inbuf[2])\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n\n    int     ch, gr;\n\n    if (gfc->lame_encode_frame_init == 0) {\n        sample_t primebuff0[286 + 1152 + 576];\n        sample_t primebuff1[286 + 1152 + 576];\n        int const framesize = 576 * cfg->mode_gr;\n        /* prime the MDCT/polyphase filterbank with a short block */\n        int     i, j;\n        gfc->lame_encode_frame_init = 1;\n        memset(primebuff0, 0, sizeof(primebuff0));\n        memset(primebuff1, 0, sizeof(primebuff1));\n        for (i = 0, j = 0; i < 286 + 576 * (1 + cfg->mode_gr); ++i) {\n            if (i < framesize) {\n                primebuff0[i] = 0;\n                if (cfg->channels_out == 2)\n                    primebuff1[i] = 0;\n            }\n            else {\n                primebuff0[i] = inbuf[0][j];\n                if (cfg->channels_out == 2)\n                    primebuff1[i] = inbuf[1][j];\n                ++j;\n            }\n        }\n        /* polyphase filtering / mdct */\n        for (gr = 0; gr < cfg->mode_gr; gr++) {\n            for (ch = 0; ch < cfg->channels_out; ch++) {\n                gfc->l3_side.tt[gr][ch].block_type = SHORT_TYPE;\n            }\n        }\n        mdct_sub48(gfc, primebuff0, primebuff1);\n\n        /* check FFT will not use a negative starting offset */\n#if 576 < FFTOFFSET\n# error FFTOFFSET greater than 576: FFT uses a negative offset\n#endif\n        /* check if we have enough data for FFT */\n        assert(gfc->sv_enc.mf_size >= (BLKSIZE + framesize - FFTOFFSET));\n        /* check if we have enough data for polyphase filterbank */\n        assert(gfc->sv_enc.mf_size >= (512 + framesize - 32));\n    }\n\n}\n\n\n\n\n\n\n\n/************************************************************************\n*\n* encodeframe()           Layer 3\n*\n* encode a single frame\n*\n************************************************************************\nlame_encode_frame()\n\n\n                       gr 0            gr 1\ninbuf:           |--------------|--------------|--------------|\n\n\nPolyphase (18 windows, each shifted 32)\ngr 0:\nwindow1          <----512---->\nwindow18                 <----512---->\n\ngr 1:\nwindow1                         <----512---->\nwindow18                                <----512---->\n\n\n\nMDCT output:  |--------------|--------------|--------------|\n\nFFT's                    <---------1024---------->\n                                         <---------1024-------->\n\n\n\n    inbuf = buffer of PCM data size=MP3 framesize\n    encoder acts on inbuf[ch][0], but output is delayed by MDCTDELAY\n    so the MDCT coefficints are from inbuf[ch][-MDCTDELAY]\n\n    psy-model FFT has a 1 granule delay, so we feed it data for the \n    next granule.\n    FFT is centered over granule:  224+576+224\n    So FFT starts at:   576-224-MDCTDELAY\n\n    MPEG2:  FFT ends at:  BLKSIZE+576-224-MDCTDELAY      (1328)\n    MPEG1:  FFT ends at:  BLKSIZE+2*576-224-MDCTDELAY    (1904)\n\n    MPEG2:  polyphase first window:  [0..511]\n                      18th window:   [544..1055]          (1056)\n    MPEG1:            36th window:   [1120..1631]         (1632)\n            data needed:  512+framesize-32\n\n    A close look newmdct.c shows that the polyphase filterbank\n    only uses data from [0..510] for each window.  Perhaps because the window\n    used by the filterbank is zero for the last point, so Takehiro's\n    code doesn't bother to compute with it.\n\n    FFT starts at 576-224-MDCTDELAY (304)  = 576-FFTOFFSET\n\n*/\n\ntypedef FLOAT chgrdata[2][2];\n\n\nint\nlame_encode_mp3_frame(       /* Output */\n                         lame_internal_flags * gfc, /* Context */\n                         sample_t const *inbuf_l, /* Input */\n                         sample_t const *inbuf_r, /* Input */\n                         unsigned char *mp3buf, /* Output */\n                         int mp3buf_size)\n{                       /* Output */\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    int     mp3count;\n    III_psy_ratio masking_LR[2][2]; /*LR masking & energy */\n    III_psy_ratio masking_MS[2][2]; /*MS masking & energy */\n    const III_psy_ratio (*masking)[2]; /*pointer to selected maskings */\n    const sample_t *inbuf[2];\n\n    FLOAT   tot_ener[2][4];\n    FLOAT   ms_ener_ratio[2] = { .5, .5 };\n    FLOAT   pe[2][2] = { {0., 0.}, {0., 0.} }, pe_MS[2][2] = { {\n    0., 0.}, {\n    0., 0.}};\n    FLOAT (*pe_use)[2];\n\n    int     ch, gr;\n\n    inbuf[0] = inbuf_l;\n    inbuf[1] = inbuf_r;\n\n    if (gfc->lame_encode_frame_init == 0) {\n        /*first run? */\n        lame_encode_frame_init(gfc, inbuf);\n\n    }\n\n\n    /********************** padding *****************************/\n    /* padding method as described in \n     * \"MPEG-Layer3 / Bitstream Syntax and Decoding\"\n     * by Martin Sieler, Ralph Sperschneider\n     *\n     * note: there is no padding for the very first frame\n     *\n     * Robert Hegemann 2000-06-22\n     */\n    gfc->ov_enc.padding = FALSE;\n    if ((gfc->sv_enc.slot_lag -= gfc->sv_enc.frac_SpF) < 0) {\n        gfc->sv_enc.slot_lag += cfg->samplerate_out;\n        gfc->ov_enc.padding = TRUE;\n    }\n\n\n\n    /****************************************\n    *   Stage 1: psychoacoustic model       *\n    ****************************************/\n\n    {\n        /* psychoacoustic model\n         * psy model has a 1 granule (576) delay that we must compensate for\n         * (mt 6/99).\n         */\n        int     ret;\n        const sample_t *bufp[2] = {0, 0}; /* address of beginning of left & right granule */\n        int     blocktype[2];\n\n        for (gr = 0; gr < cfg->mode_gr; gr++) {\n\n            for (ch = 0; ch < cfg->channels_out; ch++) {\n                bufp[ch] = &inbuf[ch][576 + gr * 576 - FFTOFFSET];\n            }\n            ret = L3psycho_anal_vbr(gfc, bufp, gr,\n                                    masking_LR, masking_MS,\n                                    pe[gr], pe_MS[gr], tot_ener[gr], blocktype);\n            if (ret != 0)\n                return -4;\n\n            if (cfg->mode == JOINT_STEREO) {\n                ms_ener_ratio[gr] = tot_ener[gr][2] + tot_ener[gr][3];\n                if (ms_ener_ratio[gr] > 0)\n                    ms_ener_ratio[gr] = tot_ener[gr][3] / ms_ener_ratio[gr];\n            }\n\n            /* block type flags */\n            for (ch = 0; ch < cfg->channels_out; ch++) {\n                gr_info *const cod_info = &gfc->l3_side.tt[gr][ch];\n                cod_info->block_type = blocktype[ch];\n                cod_info->mixed_block_flag = 0;\n            }\n        }\n    }\n\n\n    /* auto-adjust of ATH, useful for low volume */\n    adjust_ATH(gfc);\n\n\n    /****************************************\n    *   Stage 2: MDCT                       *\n    ****************************************/\n\n    /* polyphase filtering / mdct */\n    mdct_sub48(gfc, inbuf[0], inbuf[1]);\n\n\n    /****************************************\n    *   Stage 3: MS/LR decision             *\n    ****************************************/\n\n    /* Here will be selected MS or LR coding of the 2 stereo channels */\n    gfc->ov_enc.mode_ext = MPG_MD_LR_LR;\n\n    if (cfg->force_ms) {\n        gfc->ov_enc.mode_ext = MPG_MD_MS_LR;\n    }\n    else if (cfg->mode == JOINT_STEREO) {\n        /* ms_ratio = is scaled, for historical reasons, to look like\n           a ratio of side_channel / total.\n           0 = signal is 100% mono\n           .5 = L & R uncorrelated\n         */\n\n        /* [0] and [1] are the results for the two granules in MPEG-1,\n         * in MPEG-2 it's only a faked averaging of the same value\n         * _prev is the value of the last granule of the previous frame\n         * _next is the value of the first granule of the next frame\n         */\n\n        FLOAT   sum_pe_MS = 0;\n        FLOAT   sum_pe_LR = 0;\n        for (gr = 0; gr < cfg->mode_gr; gr++) {\n            for (ch = 0; ch < cfg->channels_out; ch++) {\n                sum_pe_MS += pe_MS[gr][ch];\n                sum_pe_LR += pe[gr][ch];\n            }\n        }\n\n        /* based on PE: M/S coding would not use much more bits than L/R */\n        if (sum_pe_MS <= 1.00 * sum_pe_LR) {\n\n            gr_info const *const gi0 = &gfc->l3_side.tt[0][0];\n            gr_info const *const gi1 = &gfc->l3_side.tt[cfg->mode_gr - 1][0];\n\n            if (gi0[0].block_type == gi0[1].block_type && gi1[0].block_type == gi1[1].block_type) {\n\n                gfc->ov_enc.mode_ext = MPG_MD_MS_LR;\n            }\n        }\n    }\n\n    /* bit and noise allocation */\n    if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR) {\n        masking = (const III_psy_ratio (*)[2])masking_MS; /* use MS masking */\n        pe_use = pe_MS;\n    }\n    else {\n        masking = (const III_psy_ratio (*)[2])masking_LR; /* use LR masking */\n        pe_use = pe;\n    }\n\n\n    /* copy data for MP3 frame analyzer */\n    if (cfg->analysis && gfc->pinfo != NULL) {\n        for (gr = 0; gr < cfg->mode_gr; gr++) {\n            for (ch = 0; ch < cfg->channels_out; ch++) {\n                gfc->pinfo->ms_ratio[gr] = 0;\n                gfc->pinfo->ms_ener_ratio[gr] = ms_ener_ratio[gr];\n                gfc->pinfo->blocktype[gr][ch] = gfc->l3_side.tt[gr][ch].block_type;\n                gfc->pinfo->pe[gr][ch] = pe_use[gr][ch];\n                memcpy(gfc->pinfo->xr[gr][ch], &gfc->l3_side.tt[gr][ch].xr[0], sizeof(FLOAT) * 576);\n                /* in psymodel, LR and MS data was stored in pinfo.  \n                   switch to MS data: */\n                if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR) {\n                    gfc->pinfo->ers[gr][ch] = gfc->pinfo->ers[gr][ch + 2];\n                    memcpy(gfc->pinfo->energy[gr][ch], gfc->pinfo->energy[gr][ch + 2],\n                           sizeof(gfc->pinfo->energy[gr][ch]));\n                }\n            }\n        }\n    }\n\n\n    /****************************************\n    *   Stage 4: quantization loop          *\n    ****************************************/\n\n    if (cfg->vbr == vbr_off || cfg->vbr == vbr_abr) {\n        static FLOAT const fircoef[9] = {\n            -0.0207887 * 5, -0.0378413 * 5, -0.0432472 * 5, -0.031183 * 5,\n            7.79609e-18 * 5, 0.0467745 * 5, 0.10091 * 5, 0.151365 * 5,\n            0.187098 * 5\n        };\n\n        int     i;\n        FLOAT   f;\n\n        for (i = 0; i < 18; i++)\n            gfc->sv_enc.pefirbuf[i] = gfc->sv_enc.pefirbuf[i + 1];\n\n        f = 0.0;\n        for (gr = 0; gr < cfg->mode_gr; gr++)\n            for (ch = 0; ch < cfg->channels_out; ch++)\n                f += pe_use[gr][ch];\n        gfc->sv_enc.pefirbuf[18] = f;\n\n        f = gfc->sv_enc.pefirbuf[9];\n        for (i = 0; i < 9; i++)\n            f += (gfc->sv_enc.pefirbuf[i] + gfc->sv_enc.pefirbuf[18 - i]) * fircoef[i];\n\n        f = (670 * 5 * cfg->mode_gr * cfg->channels_out) / f;\n        for (gr = 0; gr < cfg->mode_gr; gr++) {\n            for (ch = 0; ch < cfg->channels_out; ch++) {\n                pe_use[gr][ch] *= f;\n            }\n        }\n    }\n    gfc->iteration_loop(gfc, (const FLOAT (*)[2])pe_use, ms_ener_ratio, masking);\n\n\n    /****************************************\n    *   Stage 5: bitstream formatting       *\n    ****************************************/\n\n\n    /*  write the frame to the bitstream  */\n    (void) format_bitstream(gfc);\n\n    /* copy mp3 bit buffer into array */\n    mp3count = copy_buffer(gfc, mp3buf, mp3buf_size, 1);\n\n\n    if (cfg->write_lame_tag) {\n        AddVbrFrame(gfc);\n    }\n\n    if (cfg->analysis && gfc->pinfo != NULL) {\n        int     framesize = 576 * cfg->mode_gr;\n        for (ch = 0; ch < cfg->channels_out; ch++) {\n            int     j;\n            for (j = 0; j < FFTOFFSET; j++)\n                gfc->pinfo->pcmdata[ch][j] = gfc->pinfo->pcmdata[ch][j + framesize];\n            for (j = FFTOFFSET; j < 1600; j++) {\n                gfc->pinfo->pcmdata[ch][j] = inbuf[ch][j - FFTOFFSET];\n            }\n        }\n        gfc->sv_qnt.masking_lower = 1.0;\n\n        set_frame_pinfo(gfc, masking);\n    }\n\n    ++gfc->ov_enc.frame_number;\n\n    updateStats(gfc);\n\n    return mp3count;\n}\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/encoder.h",
    "content": "/*\n *      encoder.h include file\n *\n *      Copyright (c) 2000 Mark Taylor\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n\n#ifndef LAME_ENCODER_H\n#define LAME_ENCODER_H\n\n/***********************************************************************\n*\n*  encoder and decoder delays\n*\n***********************************************************************/\n\n/* \n * layer III enc->dec delay:  1056 (1057?)   (observed)\n * layer  II enc->dec delay:   480  (481?)   (observed)\n *\n * polyphase 256-16             (dec or enc)        = 240\n * mdct      256+32  (9*32)     (dec or enc)        = 288\n * total:    512+16\n *\n * My guess is that delay of polyphase filterbank is actualy 240.5\n * (there are technical reasons for this, see postings in mp3encoder).\n * So total Encode+Decode delay = ENCDELAY + 528 + 1\n */\n\n/* \n * ENCDELAY  The encoder delay.  \n *\n * Minimum allowed is MDCTDELAY (see below)\n *  \n * The first 96 samples will be attenuated, so using a value less than 96\n * will result in corrupt data for the first 96-ENCDELAY samples.\n *\n * suggested: 576\n * set to 1160 to sync with FhG.\n */\n\n#define ENCDELAY      576\n\n\n\n/*\n * make sure there is at least one complete frame after the\n * last frame containing real data\n *\n * Using a value of 288 would be sufficient for a \n * a very sophisticated decoder that can decode granule-by-granule instead\n * of frame by frame.  But lets not assume this, and assume the decoder  \n * will not decode frame N unless it also has data for frame N+1\n *\n */\n/*#define POSTDELAY   288*/\n#define POSTDELAY   1152\n\n\n\n/* \n * delay of the MDCT used in mdct.c\n * original ISO routines had a delay of 528!  \n * Takehiro's routines: \n */\n\n#define MDCTDELAY     48\n#define FFTOFFSET     (224+MDCTDELAY)\n\n/*\n * Most decoders, including the one we use, have a delay of 528 samples.  \n */\n\n#define DECDELAY      528\n\n\n/* number of subbands */\n#define SBLIMIT       32\n\n/* parition bands bands */\n#define CBANDS        64\n\n/* number of critical bands/scale factor bands where masking is computed*/\n#define SBPSY_l       21\n#define SBPSY_s       12\n\n/* total number of scalefactor bands encoded */\n#define SBMAX_l       22\n#define SBMAX_s       13\n#define PSFB21         6\n#define PSFB12         6\n\n\n\n/* FFT sizes */\n#define BLKSIZE       1024\n#define HBLKSIZE      (BLKSIZE/2 + 1)\n#define BLKSIZE_s     256\n#define HBLKSIZE_s    (BLKSIZE_s/2 + 1)\n\n\n/* #define switch_pe        1800 */\n#define NORM_TYPE     0\n#define START_TYPE    1\n#define SHORT_TYPE    2\n#define STOP_TYPE     3\n\n/* \n * Mode Extention:\n * When we are in stereo mode, there are 4 possible methods to store these\n * two channels. The stereo modes -m? are using a subset of them.\n *\n *  -ms: MPG_MD_LR_LR\n *  -mj: MPG_MD_LR_LR and MPG_MD_MS_LR\n *  -mf: MPG_MD_MS_LR\n *  -mi: all\n */\n#if 0\n#define MPG_MD_LR_LR  0\n#define MPG_MD_LR_I   1\n#define MPG_MD_MS_LR  2\n#define MPG_MD_MS_I   3\n#endif\nenum MPEGChannelMode\n{   MPG_MD_LR_LR = 0\n,   MPG_MD_LR_I  = 1\n,   MPG_MD_MS_LR = 2\n,   MPG_MD_MS_I  = 3\n};\n\n#ifndef lame_internal_flags_defined\n#define lame_internal_flags_defined\nstruct lame_internal_flags;\ntypedef struct lame_internal_flags lame_internal_flags;\n#endif\n\nint     lame_encode_mp3_frame(lame_internal_flags * gfc,\n                              sample_t const *inbuf_l,\n                              sample_t const *inbuf_r, unsigned char *mp3buf, int mp3buf_size);\n\n#endif /* LAME_ENCODER_H */\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/fft.c",
    "content": "/*\n** FFT and FHT routines\n**  Copyright 1988, 1993; Ron Mayer\n**      Copyright (c) 1999-2000 Takehiro Tominaga\n**\n**  fht(fz,n);\n**      Does a hartley transform of \"n\" points in the array \"fz\".\n**\n** NOTE: This routine uses at least 2 patented algorithms, and may be\n**       under the restrictions of a bunch of different organizations.\n**       Although I wrote it completely myself; it is kind of a derivative\n**       of a routine I once authored and released under the GPL, so it\n**       may fall under the free software foundation's restrictions;\n**       it was worked on as a Stanford Univ project, so they claim\n**       some rights to it; it was further optimized at work here, so\n**       I think this company claims parts of it.  The patents are\n**       held by R. Bracewell (the FHT algorithm) and O. Buneman (the\n**       trig generator), both at Stanford Univ.\n**       If it were up to me, I'd say go do whatever you want with it;\n**       but it would be polite to give credit to the following people\n**       if you use this anywhere:\n**           Euler     - probable inventor of the fourier transform.\n**           Gauss     - probable inventor of the FFT.\n**           Hartley   - probable inventor of the hartley transform.\n**           Buneman   - for a really cool trig generator\n**           Mayer(me) - for authoring this particular version and\n**                       including all the optimizations in one package.\n**       Thanks,\n**       Ron Mayer; mayer@acuson.com\n** and added some optimization by\n**           Mather    - idea of using lookup table\n**           Takehiro  - some dirty hack for speed up\n*/\n\n/* $Id: fft.c,v 1.38 2009/04/20 21:48:00 robert Exp $ */\n\n#ifdef HAVE_CONFIG_H\n# include <config.h>\n#endif\n\n#include \"lame.h\"\n#include \"machine.h\"\n#include \"encoder.h\"\n#include \"util.h\"\n#include \"fft.h\"\n\n//#include \"vector/lame_intrin.h\"\n\n\n\n#define TRI_SIZE (5-1)  /* 1024 =  4**5 */\n\n/* fft.c    */\nstatic FLOAT window[BLKSIZE], window_s[BLKSIZE_s / 2];\n\nstatic const FLOAT costab[TRI_SIZE * 2] = {\n    9.238795325112867e-01, 3.826834323650898e-01,\n    9.951847266721969e-01, 9.801714032956060e-02,\n    9.996988186962042e-01, 2.454122852291229e-02,\n    9.999811752826011e-01, 6.135884649154475e-03\n};\n\nstatic void\nfht(FLOAT * fz, int n)\n{\n    const FLOAT *tri = costab;\n    int     k4;\n    FLOAT  *fi, *gi;\n    FLOAT const *fn;\n\n    n <<= 1;            /* to get BLKSIZE, because of 3DNow! ASM routine */\n    fn = fz + n;\n    k4 = 4;\n    do {\n        FLOAT   s1, c1;\n        int     i, k1, k2, k3, kx;\n        kx = k4 >> 1;\n        k1 = k4;\n        k2 = k4 << 1;\n        k3 = k2 + k1;\n        k4 = k2 << 1;\n        fi = fz;\n        gi = fi + kx;\n        do {\n            FLOAT   f0, f1, f2, f3;\n            f1 = fi[0] - fi[k1];\n            f0 = fi[0] + fi[k1];\n            f3 = fi[k2] - fi[k3];\n            f2 = fi[k2] + fi[k3];\n            fi[k2] = f0 - f2;\n            fi[0] = f0 + f2;\n            fi[k3] = f1 - f3;\n            fi[k1] = f1 + f3;\n            f1 = gi[0] - gi[k1];\n            f0 = gi[0] + gi[k1];\n            f3 = SQRT2 * gi[k3];\n            f2 = SQRT2 * gi[k2];\n            gi[k2] = f0 - f2;\n            gi[0] = f0 + f2;\n            gi[k3] = f1 - f3;\n            gi[k1] = f1 + f3;\n            gi += k4;\n            fi += k4;\n        } while (fi < fn);\n        c1 = tri[0];\n        s1 = tri[1];\n        for (i = 1; i < kx; i++) {\n            FLOAT   c2, s2;\n            c2 = 1 - (2 * s1) * s1;\n            s2 = (2 * s1) * c1;\n            fi = fz + i;\n            gi = fz + k1 - i;\n            do {\n                FLOAT   a, b, g0, f0, f1, g1, f2, g2, f3, g3;\n                b = s2 * fi[k1] - c2 * gi[k1];\n                a = c2 * fi[k1] + s2 * gi[k1];\n                f1 = fi[0] - a;\n                f0 = fi[0] + a;\n                g1 = gi[0] - b;\n                g0 = gi[0] + b;\n                b = s2 * fi[k3] - c2 * gi[k3];\n                a = c2 * fi[k3] + s2 * gi[k3];\n                f3 = fi[k2] - a;\n                f2 = fi[k2] + a;\n                g3 = gi[k2] - b;\n                g2 = gi[k2] + b;\n                b = s1 * f2 - c1 * g3;\n                a = c1 * f2 + s1 * g3;\n                fi[k2] = f0 - a;\n                fi[0] = f0 + a;\n                gi[k3] = g1 - b;\n                gi[k1] = g1 + b;\n                b = c1 * g2 - s1 * f3;\n                a = s1 * g2 + c1 * f3;\n                gi[k2] = g0 - a;\n                gi[0] = g0 + a;\n                fi[k3] = f1 - b;\n                fi[k1] = f1 + b;\n                gi += k4;\n                fi += k4;\n            } while (fi < fn);\n            c2 = c1;\n            c1 = c2 * tri[0] - s1 * tri[1];\n            s1 = c2 * tri[1] + s1 * tri[0];\n        }\n        tri += 2;\n    } while (k4 < n);\n}\n\n\nstatic const unsigned char rv_tbl[] = {\n    0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,\n    0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,\n    0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,\n    0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,\n    0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,\n    0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,\n    0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,\n    0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,\n    0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,\n    0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,\n    0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,\n    0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,\n    0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,\n    0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,\n    0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,\n    0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe\n};\n\n#define ch01(index)  (buffer[chn][index])\n\n#define ml00(f) (window[i        ] * f(i))\n#define ml10(f) (window[i + 0x200] * f(i + 0x200))\n#define ml20(f) (window[i + 0x100] * f(i + 0x100))\n#define ml30(f) (window[i + 0x300] * f(i + 0x300))\n\n#define ml01(f) (window[i + 0x001] * f(i + 0x001))\n#define ml11(f) (window[i + 0x201] * f(i + 0x201))\n#define ml21(f) (window[i + 0x101] * f(i + 0x101))\n#define ml31(f) (window[i + 0x301] * f(i + 0x301))\n\n#define ms00(f) (window_s[i       ] * f(i + k))\n#define ms10(f) (window_s[0x7f - i] * f(i + k + 0x80))\n#define ms20(f) (window_s[i + 0x40] * f(i + k + 0x40))\n#define ms30(f) (window_s[0x3f - i] * f(i + k + 0xc0))\n\n#define ms01(f) (window_s[i + 0x01] * f(i + k + 0x01))\n#define ms11(f) (window_s[0x7e - i] * f(i + k + 0x81))\n#define ms21(f) (window_s[i + 0x41] * f(i + k + 0x41))\n#define ms31(f) (window_s[0x3e - i] * f(i + k + 0xc1))\n\n\nvoid\nfft_short(lame_internal_flags const *const gfc,\n          FLOAT x_real[3][BLKSIZE_s], int chn, const sample_t *const buffer[2])\n{\n    int     i;\n    int     j;\n    int     b;\n\n    for (b = 0; b < 3; b++) {\n        FLOAT  *x = &x_real[b][BLKSIZE_s / 2];\n        short const k = (576 / 3) * (b + 1);\n        j = BLKSIZE_s / 8 - 1;\n        do {\n            FLOAT   f0, f1, f2, f3, w;\n\n            i = rv_tbl[j << 2];\n\n            f0 = ms00(ch01);\n            w = ms10(ch01);\n            f1 = f0 - w;\n            f0 = f0 + w;\n            f2 = ms20(ch01);\n            w = ms30(ch01);\n            f3 = f2 - w;\n            f2 = f2 + w;\n\n            x -= 4;\n            x[0] = f0 + f2;\n            x[2] = f0 - f2;\n            x[1] = f1 + f3;\n            x[3] = f1 - f3;\n\n            f0 = ms01(ch01);\n            w = ms11(ch01);\n            f1 = f0 - w;\n            f0 = f0 + w;\n            f2 = ms21(ch01);\n            w = ms31(ch01);\n            f3 = f2 - w;\n            f2 = f2 + w;\n\n            x[BLKSIZE_s / 2 + 0] = f0 + f2;\n            x[BLKSIZE_s / 2 + 2] = f0 - f2;\n            x[BLKSIZE_s / 2 + 1] = f1 + f3;\n            x[BLKSIZE_s / 2 + 3] = f1 - f3;\n        } while (--j >= 0);\n\n        gfc->fft_fht(x, BLKSIZE_s / 2);\n        /* BLKSIZE_s/2 because of 3DNow! ASM routine */\n    }\n}\n\nvoid\nfft_long(lame_internal_flags const *const gfc,\n         FLOAT x[BLKSIZE], int chn, const sample_t *const buffer[2])\n{\n    int     i;\n    int     jj = BLKSIZE / 8 - 1;\n    x += BLKSIZE / 2;\n\n    do {\n        FLOAT   f0, f1, f2, f3, w;\n\n        i = rv_tbl[jj];\n        f0 = ml00(ch01);\n        w = ml10(ch01);\n        f1 = f0 - w;\n        f0 = f0 + w;\n        f2 = ml20(ch01);\n        w = ml30(ch01);\n        f3 = f2 - w;\n        f2 = f2 + w;\n\n        x -= 4;\n        x[0] = f0 + f2;\n        x[2] = f0 - f2;\n        x[1] = f1 + f3;\n        x[3] = f1 - f3;\n\n        f0 = ml01(ch01);\n        w = ml11(ch01);\n        f1 = f0 - w;\n        f0 = f0 + w;\n        f2 = ml21(ch01);\n        w = ml31(ch01);\n        f3 = f2 - w;\n        f2 = f2 + w;\n\n        x[BLKSIZE / 2 + 0] = f0 + f2;\n        x[BLKSIZE / 2 + 2] = f0 - f2;\n        x[BLKSIZE / 2 + 1] = f1 + f3;\n        x[BLKSIZE / 2 + 3] = f1 - f3;\n    } while (--jj >= 0);\n\n    gfc->fft_fht(x, BLKSIZE / 2);\n    /* BLKSIZE/2 because of 3DNow! ASM routine */\n}\n\n#ifdef HAVE_NASM\nextern void fht_3DN(FLOAT * fz, int n);\nextern void fht_SSE(FLOAT * fz, int n);\n#endif\n\nvoid\ninit_fft(lame_internal_flags * const gfc)\n{\n    int     i;\n\n    /* The type of window used here will make no real difference, but */\n    /* in the interest of merging nspsytune stuff - switch to blackman window */\n    for (i = 0; i < BLKSIZE; i++)\n        /* blackman window */\n        window[i] = 0.42 - 0.5 * cos(2 * PI * (i + .5) / BLKSIZE) +\n            0.08 * cos(4 * PI * (i + .5) / BLKSIZE);\n\n    for (i = 0; i < BLKSIZE_s / 2; i++)\n        window_s[i] = 0.5 * (1.0 - cos(2.0 * PI * (i + 0.5) / BLKSIZE_s));\n\n    gfc->fft_fht = fht;\n#ifdef HAVE_NASM\n    if (gfc->CPU_features.AMD_3DNow) {\n        gfc->fft_fht = fht_3DN;\n    }\n    else if (gfc->CPU_features.SSE) {\n        gfc->fft_fht = fht_SSE;\n    }\n    else {\n        gfc->fft_fht = fht;\n    }\n#else\n#ifdef HAVE_XMMINTRIN_H\n#ifdef MIN_ARCH_SSE\n    gfc->fft_fht = fht_SSE2;\n#endif\n#endif\n#endif\n}\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/fft.h",
    "content": "/*\n *\tFast Fourier Transform include file\n *\n *\tCopyright (c) 2000 Mark Taylor\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\t See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n#ifndef LAME_FFT_H\n#define LAME_FFT_H\n\nvoid    fft_long(lame_internal_flags const *const gfc, FLOAT x_real[BLKSIZE],\n                 int chn, const sample_t *const data[2]);\n\nvoid    fft_short(lame_internal_flags const *const gfc, FLOAT x_real[3][BLKSIZE_s],\n                  int chn, const sample_t *const data[2]);\n\nvoid    init_fft(lame_internal_flags * const gfc);\n\n#endif\n\n/* End of fft.h */\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/gain_analysis.c",
    "content": "/*\n *  ReplayGainAnalysis - analyzes input samples and give the recommended dB change\n *  Copyright (C) 2001 David Robinson and Glen Sawyer\n *  Improvements and optimizations added by Frank Klemm, and by Marcel Muller \n *\n *  This library is free software; you can redistribute it and/or\n *  modify it under the terms of the GNU Lesser General Public\n *  License as published by the Free Software Foundation; either\n *  version 2.1 of the License, or (at your option) any later version.\n *\n *  This library is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n *  Lesser General Public License for more details.\n *\n *  You should have received a copy of the GNU Lesser General Public\n *  License along with this library; if not, write to the Free Software\n *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n *\n *  concept and filter values by David Robinson (David@Robinson.org)\n *    -- blame him if you think the idea is flawed\n *  original coding by Glen Sawyer (mp3gain@hotmail.com)\n *    -- blame him if you think this runs too slowly, or the coding is otherwise flawed\n *\n *  lots of code improvements by Frank Klemm ( http://www.uni-jena.de/~pfk/mpp/ )\n *    -- credit him for all the _good_ programming ;)\n *\n *\n *  For an explanation of the concepts and the basic algorithms involved, go to:\n *    http://www.replaygain.org/\n */\n\n/*\n *  Here's the deal. Call\n *\n *    InitGainAnalysis ( long samplefreq );\n *\n *  to initialize everything. Call\n *\n *    AnalyzeSamples ( const Float_t*  left_samples,\n *                     const Float_t*  right_samples,\n *                     size_t          num_samples,\n *                     int             num_channels );\n *\n *  as many times as you want, with as many or as few samples as you want.\n *  If mono, pass the sample buffer in through left_samples, leave\n *  right_samples NULL, and make sure num_channels = 1.\n *\n *    GetTitleGain()\n *\n *  will return the recommended dB level change for all samples analyzed\n *  SINCE THE LAST TIME you called GetTitleGain() OR InitGainAnalysis().\n *\n *    GetAlbumGain()\n *\n *  will return the recommended dB level change for all samples analyzed\n *  since InitGainAnalysis() was called and finalized with GetTitleGain().\n *\n *  Pseudo-code to process an album:\n *\n *    Float_t       l_samples [4096];\n *    Float_t       r_samples [4096];\n *    size_t        num_samples;\n *    unsigned int  num_songs;\n *    unsigned int  i;\n *\n *    InitGainAnalysis ( 44100 );\n *    for ( i = 1; i <= num_songs; i++ ) {\n *        while ( ( num_samples = getSongSamples ( song[i], left_samples, right_samples ) ) > 0 )\n *            AnalyzeSamples ( left_samples, right_samples, num_samples, 2 );\n *        fprintf (\"Recommended dB change for song %2d: %+6.2f dB\\n\", i, GetTitleGain() );\n *    }\n *    fprintf (\"Recommended dB change for whole album: %+6.2f dB\\n\", GetAlbumGain() );\n */\n\n/*\n *  So here's the main source of potential code confusion:\n *\n *  The filters applied to the incoming samples are IIR filters,\n *  meaning they rely on up to <filter order> number of previous samples\n *  AND up to <filter order> number of previous filtered samples.\n *\n *  I set up the AnalyzeSamples routine to minimize memory usage and interface\n *  complexity. The speed isn't compromised too much (I don't think), but the\n *  internal complexity is higher than it should be for such a relatively\n *  simple routine.\n *\n *  Optimization/clarity suggestions are welcome.\n */\n\n#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include \"lame.h\"\n#include \"machine.h\"\n#include \"gain_analysis.h\"\n\n/* for each filter: */\n/* [0] 48 kHz, [1] 44.1 kHz, [2] 32 kHz, [3] 24 kHz, [4] 22050 Hz, [5] 16 kHz, [6] 12 kHz, [7] is 11025 Hz, [8] 8 kHz */\n\n#ifdef WIN32\n#pragma warning ( disable : 4305 )\n#endif\n\n/*lint -save -e736 loss of precision */\nstatic const Float_t ABYule[9][2 * YULE_ORDER + 1] = {\n    {0.03857599435200, -3.84664617118067, -0.02160367184185, 7.81501653005538, -0.00123395316851,\n     -11.34170355132042, -0.00009291677959, 13.05504219327545, -0.01655260341619,\n     -12.28759895145294, 0.02161526843274, 9.48293806319790, -0.02074045215285, -5.87257861775999,\n     0.00594298065125, 2.75465861874613, 0.00306428023191, -0.86984376593551, 0.00012025322027,\n     0.13919314567432, 0.00288463683916},\n    {0.05418656406430, -3.47845948550071, -0.02911007808948, 6.36317777566148, -0.00848709379851,\n     -8.54751527471874, -0.00851165645469, 9.47693607801280, -0.00834990904936, -8.81498681370155,\n     0.02245293253339, 6.85401540936998, -0.02596338512915, -4.39470996079559, 0.01624864962975,\n     2.19611684890774, -0.00240879051584, -0.75104302451432, 0.00674613682247, 0.13149317958808,\n     -0.00187763777362},\n    {0.15457299681924, -2.37898834973084, -0.09331049056315, 2.84868151156327, -0.06247880153653,\n     -2.64577170229825, 0.02163541888798, 2.23697657451713, -0.05588393329856, -1.67148153367602,\n     0.04781476674921, 1.00595954808547, 0.00222312597743, -0.45953458054983, 0.03174092540049,\n     0.16378164858596, -0.01390589421898, -0.05032077717131, 0.00651420667831, 0.02347897407020,\n     -0.00881362733839},\n    {0.30296907319327, -1.61273165137247, -0.22613988682123, 1.07977492259970, -0.08587323730772,\n     -0.25656257754070, 0.03282930172664, -0.16276719120440, -0.00915702933434, -0.22638893773906,\n     -0.02364141202522, 0.39120800788284, -0.00584456039913, -0.22138138954925, 0.06276101321749,\n     0.04500235387352, -0.00000828086748, 0.02005851806501, 0.00205861885564, 0.00302439095741,\n     -0.02950134983287},\n    {0.33642304856132, -1.49858979367799, -0.25572241425570, 0.87350271418188, -0.11828570177555,\n     0.12205022308084, 0.11921148675203, -0.80774944671438, -0.07834489609479, 0.47854794562326,\n     -0.00469977914380, -0.12453458140019, -0.00589500224440, -0.04067510197014, 0.05724228140351,\n     0.08333755284107, 0.00832043980773, -0.04237348025746, -0.01635381384540, 0.02977207319925,\n     -0.01760176568150},\n    {0.44915256608450, -0.62820619233671, -0.14351757464547, 0.29661783706366, -0.22784394429749,\n     -0.37256372942400, -0.01419140100551, 0.00213767857124, 0.04078262797139, -0.42029820170918,\n     -0.12398163381748, 0.22199650564824, 0.04097565135648, 0.00613424350682, 0.10478503600251,\n     0.06747620744683, -0.01863887810927, 0.05784820375801, -0.03193428438915, 0.03222754072173,\n     0.00541907748707},\n    {0.56619470757641, -1.04800335126349, -0.75464456939302, 0.29156311971249, 0.16242137742230,\n     -0.26806001042947, 0.16744243493672, 0.00819999645858, -0.18901604199609, 0.45054734505008,\n     0.30931782841830, -0.33032403314006, -0.27562961986224, 0.06739368333110, 0.00647310677246,\n     -0.04784254229033, 0.08647503780351, 0.01639907836189, -0.03788984554840, 0.01807364323573,\n     -0.00588215443421},\n    {0.58100494960553, -0.51035327095184, -0.53174909058578, -0.31863563325245, -0.14289799034253,\n     -0.20256413484477, 0.17520704835522, 0.14728154134330, 0.02377945217615, 0.38952639978999,\n     0.15558449135573, -0.23313271880868, -0.25344790059353, -0.05246019024463, 0.01628462406333,\n     -0.02505961724053, 0.06920467763959, 0.02442357316099, -0.03721611395801, 0.01818801111503,\n     -0.00749618797172},\n    {0.53648789255105, -0.25049871956020, -0.42163034350696, -0.43193942311114, -0.00275953611929,\n     -0.03424681017675, 0.04267842219415, -0.04678328784242, -0.10214864179676, 0.26408300200955,\n     0.14590772289388, 0.15113130533216, -0.02459864859345, -0.17556493366449, -0.11202315195388,\n     -0.18823009262115, -0.04060034127000, 0.05477720428674, 0.04788665548180, 0.04704409688120,\n     -0.02217936801134}\n};\n\nstatic const Float_t ABButter[9][2 * BUTTER_ORDER + 1] = {\n    {0.98621192462708, -1.97223372919527, -1.97242384925416, 0.97261396931306, 0.98621192462708},\n    {0.98500175787242, -1.96977855582618, -1.97000351574484, 0.97022847566350, 0.98500175787242},\n    {0.97938932735214, -1.95835380975398, -1.95877865470428, 0.95920349965459, 0.97938932735214},\n    {0.97531843204928, -1.95002759149878, -1.95063686409857, 0.95124613669835, 0.97531843204928},\n    {0.97316523498161, -1.94561023566527, -1.94633046996323, 0.94705070426118, 0.97316523498161},\n    {0.96454515552826, -1.92783286977036, -1.92909031105652, 0.93034775234268, 0.96454515552826},\n    {0.96009142950541, -1.91858953033784, -1.92018285901082, 0.92177618768381, 0.96009142950541},\n    {0.95856916599601, -1.91542108074780, -1.91713833199203, 0.91885558323625, 0.95856916599601},\n    {0.94597685600279, -1.88903307939452, -1.89195371200558, 0.89487434461664, 0.94597685600279}\n};\n\n/*lint -restore */\n\n#ifdef WIN32\n#pragma warning ( default : 4305 )\n#endif\n\n/* When calling this procedure, make sure that ip[-order] and op[-order] point to real data! */\n\nstatic void\nfilterYule(const Float_t * input, Float_t * output, size_t nSamples, const Float_t * const kernel)\n{\n    /*register double  y; */\n\n    while (nSamples--) {\n        *output = 1e-10 /* 1e-10 is a hack to avoid slowdown because of denormals */\n            + input[0] * kernel[0]\n            - output[-1] * kernel[1]\n            + input[-1] * kernel[2]\n            - output[-2] * kernel[3]\n            + input[-2] * kernel[4]\n            - output[-3] * kernel[5]\n            + input[-3] * kernel[6]\n            - output[-4] * kernel[7]\n            + input[-4] * kernel[8]\n            - output[-5] * kernel[9]\n            + input[-5] * kernel[10]\n            - output[-6] * kernel[11]\n            + input[-6] * kernel[12]\n            - output[-7] * kernel[13]\n            + input[-7] * kernel[14]\n            - output[-8] * kernel[15]\n            + input[-8] * kernel[16]\n            - output[-9] * kernel[17]\n            + input[-9] * kernel[18]\n            - output[-10] * kernel[19]\n            + input[-10] * kernel[20];\n        ++output;\n        ++input;\n        /* *output++ = (Float_t)y; */\n    }\n}\n\nstatic void\nfilterButter(const Float_t * input, Float_t * output, size_t nSamples, const Float_t * const kernel)\n{                       /*register double  y; */\n\n    while (nSamples--) {\n        *output = input[0] * kernel[0]\n            - output[-1] * kernel[1]\n            + input[-1] * kernel[2]\n            - output[-2] * kernel[3]\n            + input[-2] * kernel[4];\n        ++output;\n        ++input;\n        /* *output++ = (Float_t)y; */\n    }\n}\n\n\n\nstatic int ResetSampleFrequency(replaygain_t * rgData, long samplefreq);\n\n/* returns a INIT_GAIN_ANALYSIS_OK if successful, INIT_GAIN_ANALYSIS_ERROR if not */\n\nint\nResetSampleFrequency(replaygain_t * rgData, long samplefreq)\n{\n    int     i;\n\n    /* zero out initial values */\n    for (i = 0; i < MAX_ORDER; i++)\n        rgData->linprebuf[i] = rgData->lstepbuf[i]\n            = rgData->loutbuf[i]\n            = rgData->rinprebuf[i]\n            = rgData->rstepbuf[i]\n            = rgData->routbuf[i] = 0.;\n\n    switch ((int) (samplefreq)) {\n    case 48000:\n        rgData->freqindex = 0;\n        break;\n    case 44100:\n        rgData->freqindex = 1;\n        break;\n    case 32000:\n        rgData->freqindex = 2;\n        break;\n    case 24000:\n        rgData->freqindex = 3;\n        break;\n    case 22050:\n        rgData->freqindex = 4;\n        break;\n    case 16000:\n        rgData->freqindex = 5;\n        break;\n    case 12000:\n        rgData->freqindex = 6;\n        break;\n    case 11025:\n        rgData->freqindex = 7;\n        break;\n    case 8000:\n        rgData->freqindex = 8;\n        break;\n    default:\n        return INIT_GAIN_ANALYSIS_ERROR;\n    }\n\n    rgData->sampleWindow =\n        (samplefreq * RMS_WINDOW_TIME_NUMERATOR + RMS_WINDOW_TIME_DENOMINATOR -\n         1) / RMS_WINDOW_TIME_DENOMINATOR;\n\n    rgData->lsum = 0.;\n    rgData->rsum = 0.;\n    rgData->totsamp = 0;\n\n    memset(rgData->A, 0, sizeof(rgData->A));\n\n    return INIT_GAIN_ANALYSIS_OK;\n}\n\nint\nInitGainAnalysis(replaygain_t * rgData, long samplefreq)\n{\n    if (ResetSampleFrequency(rgData, samplefreq) != INIT_GAIN_ANALYSIS_OK) {\n        return INIT_GAIN_ANALYSIS_ERROR;\n    }\n\n    rgData->linpre = rgData->linprebuf + MAX_ORDER;\n    rgData->rinpre = rgData->rinprebuf + MAX_ORDER;\n    rgData->lstep = rgData->lstepbuf + MAX_ORDER;\n    rgData->rstep = rgData->rstepbuf + MAX_ORDER;\n    rgData->lout = rgData->loutbuf + MAX_ORDER;\n    rgData->rout = rgData->routbuf + MAX_ORDER;\n\n    memset(rgData->B, 0, sizeof(rgData->B));\n\n    return INIT_GAIN_ANALYSIS_OK;\n}\n\n/* returns GAIN_ANALYSIS_OK if successful, GAIN_ANALYSIS_ERROR if not */\n\nstatic inline double\nfsqr(const double d)\n{\n    return d * d;\n}\n\nint\nAnalyzeSamples(replaygain_t * rgData, const Float_t * left_samples, const Float_t * right_samples,\n               size_t num_samples, int num_channels)\n{\n    const Float_t *curleft;\n    const Float_t *curright;\n    long    batchsamples;\n    long    cursamples;\n    long    cursamplepos;\n    int     i;\n\n    if (num_samples == 0)\n        return GAIN_ANALYSIS_OK;\n\n    cursamplepos = 0;\n    batchsamples = (long) num_samples;\n\n    switch (num_channels) {\n    case 1:\n        right_samples = left_samples;\n        break;\n    case 2:\n        break;\n    default:\n        return GAIN_ANALYSIS_ERROR;\n    }\n\n    if (num_samples < MAX_ORDER) {\n        memcpy(rgData->linprebuf + MAX_ORDER, left_samples, num_samples * sizeof(Float_t));\n        memcpy(rgData->rinprebuf + MAX_ORDER, right_samples, num_samples * sizeof(Float_t));\n    }\n    else {\n        memcpy(rgData->linprebuf + MAX_ORDER, left_samples, MAX_ORDER * sizeof(Float_t));\n        memcpy(rgData->rinprebuf + MAX_ORDER, right_samples, MAX_ORDER * sizeof(Float_t));\n    }\n\n    while (batchsamples > 0) {\n        cursamples = batchsamples > rgData->sampleWindow - rgData->totsamp ?\n            rgData->sampleWindow - rgData->totsamp : batchsamples;\n        if (cursamplepos < MAX_ORDER) {\n            curleft = rgData->linpre + cursamplepos;\n            curright = rgData->rinpre + cursamplepos;\n            if (cursamples > MAX_ORDER - cursamplepos)\n                cursamples = MAX_ORDER - cursamplepos;\n        }\n        else {\n            curleft = left_samples + cursamplepos;\n            curright = right_samples + cursamplepos;\n        }\n\n        YULE_FILTER(curleft, rgData->lstep + rgData->totsamp, cursamples,\n                    ABYule[rgData->freqindex]);\n        YULE_FILTER(curright, rgData->rstep + rgData->totsamp, cursamples,\n                    ABYule[rgData->freqindex]);\n\n        BUTTER_FILTER(rgData->lstep + rgData->totsamp, rgData->lout + rgData->totsamp, cursamples,\n                      ABButter[rgData->freqindex]);\n        BUTTER_FILTER(rgData->rstep + rgData->totsamp, rgData->rout + rgData->totsamp, cursamples,\n                      ABButter[rgData->freqindex]);\n\n        curleft = rgData->lout + rgData->totsamp; /* Get the squared values */\n        curright = rgData->rout + rgData->totsamp;\n\n        i = cursamples % 8;\n        while (i--) {\n            rgData->lsum += fsqr(*curleft++);\n            rgData->rsum += fsqr(*curright++);\n        }\n        i = cursamples / 8;\n        while (i--) {\n            rgData->lsum += fsqr(curleft[0])\n                + fsqr(curleft[1])\n                + fsqr(curleft[2])\n                + fsqr(curleft[3])\n                + fsqr(curleft[4])\n                + fsqr(curleft[5])\n                + fsqr(curleft[6])\n                + fsqr(curleft[7]);\n            curleft += 8;\n            rgData->rsum += fsqr(curright[0])\n                + fsqr(curright[1])\n                + fsqr(curright[2])\n                + fsqr(curright[3])\n                + fsqr(curright[4])\n                + fsqr(curright[5])\n                + fsqr(curright[6])\n                + fsqr(curright[7]);\n            curright += 8;\n        }\n\n        batchsamples -= cursamples;\n        cursamplepos += cursamples;\n        rgData->totsamp += cursamples;\n        if (rgData->totsamp == rgData->sampleWindow) { /* Get the Root Mean Square (RMS) for this set of samples */\n            double const val =\n                STEPS_per_dB * 10. * log10((rgData->lsum + rgData->rsum) / rgData->totsamp * 0.5 +\n                                           1.e-37);\n            size_t  ival = (val <= 0) ? 0 : (size_t) val;\n            if (ival >= sizeof(rgData->A) / sizeof(*(rgData->A)))\n                ival = sizeof(rgData->A) / sizeof(*(rgData->A)) - 1;\n            rgData->A[ival]++;\n            rgData->lsum = rgData->rsum = 0.;\n            memmove(rgData->loutbuf, rgData->loutbuf + rgData->totsamp,\n                    MAX_ORDER * sizeof(Float_t));\n            memmove(rgData->routbuf, rgData->routbuf + rgData->totsamp,\n                    MAX_ORDER * sizeof(Float_t));\n            memmove(rgData->lstepbuf, rgData->lstepbuf + rgData->totsamp,\n                    MAX_ORDER * sizeof(Float_t));\n            memmove(rgData->rstepbuf, rgData->rstepbuf + rgData->totsamp,\n                    MAX_ORDER * sizeof(Float_t));\n            rgData->totsamp = 0;\n        }\n        if (rgData->totsamp > rgData->sampleWindow) /* somehow I really screwed up: Error in programming! Contact author about totsamp > sampleWindow */\n            return GAIN_ANALYSIS_ERROR;\n    }\n    if (num_samples < MAX_ORDER) {\n        memmove(rgData->linprebuf, rgData->linprebuf + num_samples,\n                (MAX_ORDER - num_samples) * sizeof(Float_t));\n        memmove(rgData->rinprebuf, rgData->rinprebuf + num_samples,\n                (MAX_ORDER - num_samples) * sizeof(Float_t));\n        memcpy(rgData->linprebuf + MAX_ORDER - num_samples, left_samples,\n               num_samples * sizeof(Float_t));\n        memcpy(rgData->rinprebuf + MAX_ORDER - num_samples, right_samples,\n               num_samples * sizeof(Float_t));\n    }\n    else {\n        memcpy(rgData->linprebuf, left_samples + num_samples - MAX_ORDER,\n               MAX_ORDER * sizeof(Float_t));\n        memcpy(rgData->rinprebuf, right_samples + num_samples - MAX_ORDER,\n               MAX_ORDER * sizeof(Float_t));\n    }\n\n    return GAIN_ANALYSIS_OK;\n}\n\n\nstatic  Float_t\nanalyzeResult(uint32_t const *Array, size_t len)\n{\n    uint32_t elems;\n    uint32_t upper;\n    uint32_t sum;\n    size_t  i;\n\n    elems = 0;\n    for (i = 0; i < len; i++)\n        elems += Array[i];\n    if (elems == 0)\n        return GAIN_NOT_ENOUGH_SAMPLES;\n\n    upper = (uint32_t) ceil(elems * (1. - RMS_PERCENTILE));\n    sum = 0;\n    for (i = len; i-- > 0;) {\n        sum += Array[i];\n        if (sum >= upper) {\n            break;\n        }\n    }\n\n    return (Float_t) ((Float_t) PINK_REF - (Float_t) i / (Float_t) STEPS_per_dB);\n}\n\n\nFloat_t\nGetTitleGain(replaygain_t * rgData)\n{\n    Float_t retval;\n    unsigned int i;\n\n    retval = analyzeResult(rgData->A, sizeof(rgData->A) / sizeof(*(rgData->A)));\n\n    for (i = 0; i < sizeof(rgData->A) / sizeof(*(rgData->A)); i++) {\n        rgData->B[i] += rgData->A[i];\n        rgData->A[i] = 0;\n    }\n\n    for (i = 0; i < MAX_ORDER; i++)\n        rgData->linprebuf[i] = rgData->lstepbuf[i]\n            = rgData->loutbuf[i]\n            = rgData->rinprebuf[i]\n            = rgData->rstepbuf[i]\n            = rgData->routbuf[i] = 0.f;\n\n    rgData->totsamp = 0;\n    rgData->lsum = rgData->rsum = 0.;\n    return retval;\n}\n\n#if 0\nstatic Float_t GetAlbumGain(replaygain_t const* rgData);\n\nFloat_t\nGetAlbumGain(replaygain_t const* rgData)\n{\n    return analyzeResult(rgData->B, sizeof(rgData->B) / sizeof(*(rgData->B)));\n}\n#endif\n\n/* end of gain_analysis.c */\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/gain_analysis.h",
    "content": "/*\n *  ReplayGainAnalysis - analyzes input samples and give the recommended dB change\n *  Copyright (C) 2001 David Robinson and Glen Sawyer\n *\n *  This library is free software; you can redistribute it and/or\n *  modify it under the terms of the GNU Lesser General Public\n *  License as published by the Free Software Foundation; either\n *  version 2.1 of the License, or (at your option) any later version.\n *\n *  This library is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n *  Lesser General Public License for more details.\n *\n *  You should have received a copy of the GNU Lesser General Public\n *  License along with this library; if not, write to the Free Software\n *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n *\n *  concept and filter values by David Robinson (David@Robinson.org)\n *    -- blame him if you think the idea is flawed\n *  coding by Glen Sawyer (mp3gain@hotmail.com) 735 W 255 N, Orem, UT 84057-4505 USA\n *    -- blame him if you think this runs too slowly, or the coding is otherwise flawed\n *\n *  For an explanation of the concepts and the basic algorithms involved, go to:\n *    http://www.replaygain.org/\n */\n\n#ifndef GAIN_ANALYSIS_H\n#define GAIN_ANALYSIS_H\n\n#ifdef HAVE_INTTYPES_H\n# include <inttypes.h>\n#else\n# ifdef HAVE_STDINT_H\n#  include <stdint.h>\n# endif\n#endif\n\n#ifdef __cplusplus\nextern  \"C\" {\n#endif\n\n\n    typedef sample_t Float_t; /* Type used for filtering */\n\n\n#define PINK_REF                64.82       /* 298640883795 */ /* calibration value for 89dB */\n\n\n#define YULE_ORDER         10\n#define BUTTER_ORDER        2\n#define YULE_FILTER     filterYule\n#define BUTTER_FILTER   filterButter\n#define RMS_PERCENTILE      0.95 /* percentile which is louder than the proposed level */\n#define MAX_SAMP_FREQ   48000L /* maximum allowed sample frequency [Hz] */\n#define RMS_WINDOW_TIME_NUMERATOR    1L\n#define RMS_WINDOW_TIME_DENOMINATOR 20L /* numerator / denominator = time slice size [s] */\n#define STEPS_per_dB      100 /* Table entries per dB */\n#define MAX_dB            120 /* Table entries for 0...MAX_dB (normal max. values are 70...80 dB) */\n\n    enum { GAIN_NOT_ENOUGH_SAMPLES = -24601, GAIN_ANALYSIS_ERROR = 0, GAIN_ANALYSIS_OK =\n            1, INIT_GAIN_ANALYSIS_ERROR = 0, INIT_GAIN_ANALYSIS_OK = 1\n    };\n\n    enum { MAX_ORDER = (BUTTER_ORDER > YULE_ORDER ? BUTTER_ORDER : YULE_ORDER)\n            , MAX_SAMPLES_PER_WINDOW = ((MAX_SAMP_FREQ * RMS_WINDOW_TIME_NUMERATOR) / RMS_WINDOW_TIME_DENOMINATOR + 1) /* max. Samples per Time slice */\n    };\n\n    struct replaygain_data {\n        Float_t linprebuf[MAX_ORDER * 2];\n        Float_t *linpre;     /* left input samples, with pre-buffer */\n        Float_t lstepbuf[MAX_SAMPLES_PER_WINDOW + MAX_ORDER];\n        Float_t *lstep;      /* left \"first step\" (i.e. post first filter) samples */\n        Float_t loutbuf[MAX_SAMPLES_PER_WINDOW + MAX_ORDER];\n        Float_t *lout;       /* left \"out\" (i.e. post second filter) samples */\n        Float_t rinprebuf[MAX_ORDER * 2];\n        Float_t *rinpre;     /* right input samples ... */\n        Float_t rstepbuf[MAX_SAMPLES_PER_WINDOW + MAX_ORDER];\n        Float_t *rstep;\n        Float_t routbuf[MAX_SAMPLES_PER_WINDOW + MAX_ORDER];\n        Float_t *rout;\n        long    sampleWindow; /* number of samples required to reach number of milliseconds required for RMS window */\n        long    totsamp;\n        double  lsum;\n        double  rsum;\n        int     freqindex;\n        int     first;\n        uint32_t A[STEPS_per_dB * MAX_dB];\n        uint32_t B[STEPS_per_dB * MAX_dB];\n\n    };\n#ifndef replaygain_data_defined\n#define replaygain_data_defined\n    typedef struct replaygain_data replaygain_t;\n#endif\n\n\n\n\n    int     InitGainAnalysis(replaygain_t * rgData, long samplefreq);\n    int     AnalyzeSamples(replaygain_t * rgData, const Float_t * left_samples,\n                           const Float_t * right_samples, size_t num_samples, int num_channels);\n    Float_t GetTitleGain(replaygain_t * rgData);\n\n\n#ifdef __cplusplus\n}\n#endif\n#endif                       /* GAIN_ANALYSIS_H */\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/id3tag.c",
    "content": "/*\n * id3tag.c -- Write ID3 version 1 and 2 tags.\n *\n * Copyright (C) 2000 Don Melton\n * Copyright (C) 2011-2012 Robert Hegemann\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.\n */\n\n/*\n * HISTORY: This source file is part of LAME (see http://www.mp3dev.org)\n * and was originally adapted by Conrad Sanderson <c.sanderson@me.gu.edu.au>\n * from mp3info by Ricardo Cerqueira <rmc@rccn.net> to write only ID3 version 1\n * tags.  Don Melton <don@blivet.com> COMPLETELY rewrote it to support version\n * 2 tags and be more conformant to other standards while remaining flexible.\n *\n * NOTE: See http://id3.org/ for more information about ID3 tag formats.\n */\n\n/* $Id: id3tag.c,v 1.75.2.2 2012/01/08 23:49:58 robert Exp $ */\n\n#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n\n#ifdef STDC_HEADERS\n# include <stddef.h>\n# include <stdlib.h>\n# include <string.h>\n# include <ctype.h>\n#else\n# ifndef HAVE_STRCHR\n#  define strchr index\n#  define strrchr rindex\n# endif\nchar   *strchr(), *strrchr();\n# ifndef HAVE_MEMCPY\n#  define memcpy(d, s, n) bcopy ((s), (d), (n))\n# endif\n#endif\n\n\n#include \"lame.h\"\n#include \"machine.h\"\n#include \"encoder.h\"\n#include \"id3tag.h\"\n#include \"lame_global_flags.h\"\n#include \"util.h\"\n#include \"bitstream.h\"\n\n#define lame_calloc(TYPE, COUNT) ((TYPE*)calloc(COUNT, sizeof(TYPE)))\n\nstatic const char *const genre_names[] = {\n    /*\n     * NOTE: The spelling of these genre names is identical to those found in\n     * Winamp and mp3info.\n     */\n    \"Blues\", \"Classic Rock\", \"Country\", \"Dance\", \"Disco\", \"Funk\", \"Grunge\",\n    \"Hip-Hop\", \"Jazz\", \"Metal\", \"New Age\", \"Oldies\", \"Other\", \"Pop\", \"R&B\",\n    \"Rap\", \"Reggae\", \"Rock\", \"Techno\", \"Industrial\", \"Alternative\", \"Ska\",\n    \"Death Metal\", \"Pranks\", \"Soundtrack\", \"Euro-Techno\", \"Ambient\", \"Trip-Hop\",\n    \"Vocal\", \"Jazz+Funk\", \"Fusion\", \"Trance\", \"Classical\", \"Instrumental\",\n    \"Acid\", \"House\", \"Game\", \"Sound Clip\", \"Gospel\", \"Noise\", \"Alternative Rock\",\n    \"Bass\", \"Soul\", \"Punk\", \"Space\", \"Meditative\", \"Instrumental Pop\",\n    \"Instrumental Rock\", \"Ethnic\", \"Gothic\", \"Darkwave\", \"Techno-Industrial\",\n    \"Electronic\", \"Pop-Folk\", \"Eurodance\", \"Dream\", \"Southern Rock\", \"Comedy\",\n    \"Cult\", \"Gangsta\", \"Top 40\", \"Christian Rap\", \"Pop/Funk\", \"Jungle\",\n    \"Native US\", \"Cabaret\", \"New Wave\", \"Psychedelic\", \"Rave\",\n    \"Showtunes\", \"Trailer\", \"Lo-Fi\", \"Tribal\", \"Acid Punk\", \"Acid Jazz\",\n    \"Polka\", \"Retro\", \"Musical\", \"Rock & Roll\", \"Hard Rock\", \"Folk\",\n    \"Folk-Rock\", \"National Folk\", \"Swing\", \"Fast Fusion\", \"Bebob\", \"Latin\",\n    \"Revival\", \"Celtic\", \"Bluegrass\", \"Avantgarde\", \"Gothic Rock\",\n    \"Progressive Rock\", \"Psychedelic Rock\", \"Symphonic Rock\", \"Slow Rock\",\n    \"Big Band\", \"Chorus\", \"Easy Listening\", \"Acoustic\", \"Humour\", \"Speech\",\n    \"Chanson\", \"Opera\", \"Chamber Music\", \"Sonata\", \"Symphony\", \"Booty Bass\",\n    \"Primus\", \"Porn Groove\", \"Satire\", \"Slow Jam\", \"Club\", \"Tango\", \"Samba\",\n    \"Folklore\", \"Ballad\", \"Power Ballad\", \"Rhythmic Soul\", \"Freestyle\", \"Duet\",\n    \"Punk Rock\", \"Drum Solo\", \"A Cappella\", \"Euro-House\", \"Dance Hall\",\n    \"Goa\", \"Drum & Bass\", \"Club-House\", \"Hardcore\", \"Terror\", \"Indie\",\n    \"BritPop\", \"Negerpunk\", \"Polsk Punk\", \"Beat\", \"Christian Gangsta\",\n    \"Heavy Metal\", \"Black Metal\", \"Crossover\", \"Contemporary Christian\",\n    \"Christian Rock\", \"Merengue\", \"Salsa\", \"Thrash Metal\", \"Anime\", \"JPop\",\n    \"SynthPop\"\n};\n\n#define GENRE_NAME_COUNT \\\n    ((int)(sizeof genre_names / sizeof (const char *const)))\n\nstatic const int genre_alpha_map[] = {\n    123, 34, 74, 73, 99, 20, 40, 26, 145, 90, 116, 41, 135, 85, 96, 138, 89, 0,\n    107, 132, 65, 88, 104, 102, 97, 136, 61, 141, 32, 1, 112, 128, 57, 140, 2,\n    139, 58, 3, 125, 50, 22, 4, 55, 127, 122, 120, 98, 52, 48, 54, 124, 25, 84,\n    80, 115, 81, 119, 5, 30, 36, 59, 126, 38, 49, 91, 6, 129, 79, 137, 7, 35,\n    100, 131, 19, 33, 46, 47, 8, 29, 146, 63, 86, 71, 45, 142, 9, 77, 82, 64,\n    133, 10, 66, 39, 11, 103, 12, 75, 134, 13, 53, 62, 109, 117, 23, 108, 92,\n    67, 93, 43, 121, 15, 68, 14, 16, 76, 87, 118, 17, 78, 143, 114, 110, 69, 21,\n    111, 95, 105, 42, 37, 24, 56, 44, 101, 83, 94, 106, 147, 113, 18, 51, 130,\n    144, 60, 70, 31, 72, 27, 28\n};\n\n#define GENRE_ALPHA_COUNT ((int)(sizeof genre_alpha_map / sizeof (int)))\n\n#define GENRE_INDEX_OTHER 12\n\n\n#define FRAME_ID(a, b, c, d) \\\n    ( ((unsigned long)(a) << 24) \\\n    | ((unsigned long)(b) << 16) \\\n    | ((unsigned long)(c) <<  8) \\\n    | ((unsigned long)(d) <<  0) )\n\ntypedef enum UsualStringIDs { ID_TITLE = FRAME_ID('T', 'I', 'T', '2')\n        , ID_ARTIST = FRAME_ID('T', 'P', 'E', '1')\n        , ID_ALBUM = FRAME_ID('T', 'A', 'L', 'B')\n        , ID_GENRE = FRAME_ID('T', 'C', 'O', 'N')\n        , ID_ENCODER = FRAME_ID('T', 'S', 'S', 'E')\n        , ID_PLAYLENGTH = FRAME_ID('T', 'L', 'E', 'N')\n        , ID_COMMENT = FRAME_ID('C', 'O', 'M', 'M') /* full text string */\n} UsualStringIDs;\n\ntypedef enum NumericStringIDs { ID_DATE = FRAME_ID('T', 'D', 'A', 'T') /* \"ddMM\" */\n        , ID_TIME = FRAME_ID('T', 'I', 'M', 'E') /* \"hhmm\" */\n        , ID_TPOS = FRAME_ID('T', 'P', 'O', 'S') /* '0'-'9' and '/' allowed */\n        , ID_TRACK = FRAME_ID('T', 'R', 'C', 'K') /* '0'-'9' and '/' allowed */\n        , ID_YEAR = FRAME_ID('T', 'Y', 'E', 'R') /* \"yyyy\" */\n} NumericStringIDs;\n\ntypedef enum MiscIDs { ID_TXXX = FRAME_ID('T', 'X', 'X', 'X')\n        , ID_WXXX = FRAME_ID('W', 'X', 'X', 'X')\n        , ID_SYLT = FRAME_ID('S', 'Y', 'L', 'T')\n        , ID_APIC = FRAME_ID('A', 'P', 'I', 'C')\n        , ID_GEOB = FRAME_ID('G', 'E', 'O', 'B')\n        , ID_PCNT = FRAME_ID('P', 'C', 'N', 'T')\n        , ID_AENC = FRAME_ID('A', 'E', 'N', 'C')\n        , ID_LINK = FRAME_ID('L', 'I', 'N', 'K')\n        , ID_ENCR = FRAME_ID('E', 'N', 'C', 'R')\n        , ID_GRID = FRAME_ID('G', 'R', 'I', 'D')\n        , ID_PRIV = FRAME_ID('P', 'R', 'I', 'V')\n        , ID_VSLT = FRAME_ID('V', 'S', 'L', 'T') /* full text string */\n        , ID_USER = FRAME_ID('U', 'S', 'E', 'R') /* full text string */\n        , ID_PCST = FRAME_ID('P', 'C', 'S', 'T') /* iTunes Podcast indicator, only presence important */\n        , ID_WFED = FRAME_ID('W', 'F', 'E', 'D') /* iTunes Podcast URL as TEXT FRAME !!! violates standard */\n} MiscIDs;\n\n\nstatic int\nframe_id_matches(int id, int mask)\n{\n    int     result = 0, i, window = 0xff;\n    for (i = 0; i < 4; ++i, window <<= 8) {\n        int const mw = (mask & window);\n        int const iw = (id & window);\n        if (mw != 0 && mw != iw) {\n            result |= iw;\n        }\n    }\n    return result;\n}\n\nstatic int\nisFrameIdMatching(int id, int mask)\n{\n    return frame_id_matches(id, mask) == 0 ? 1 : 0;\n}\n\nstatic int\ntest_tag_spec_flags(lame_internal_flags const *gfc, unsigned int tst)\n{\n    return (gfc->tag_spec.flags & tst) != 0u ? 1 : 0;\n}\n\n#if 0\nstatic void\ndebug_tag_spec_flags(lame_internal_flags * gfc, const char* info)\n{\n    MSGF(gfc, \"%s\\n\", info);\n    MSGF(gfc, \"CHANGED_FLAG  : %d\\n\", test_tag_spec_flags(gfc, CHANGED_FLAG )); \n    MSGF(gfc, \"ADD_V2_FLAG   : %d\\n\", test_tag_spec_flags(gfc, ADD_V2_FLAG  )); \n    MSGF(gfc, \"V1_ONLY_FLAG  : %d\\n\", test_tag_spec_flags(gfc, V1_ONLY_FLAG )); \n    MSGF(gfc, \"V2_ONLY_FLAG  : %d\\n\", test_tag_spec_flags(gfc, V2_ONLY_FLAG )); \n    MSGF(gfc, \"SPACE_V1_FLAG : %d\\n\", test_tag_spec_flags(gfc, SPACE_V1_FLAG)); \n    MSGF(gfc, \"PAD_V2_FLAG   : %d\\n\", test_tag_spec_flags(gfc, PAD_V2_FLAG  )); \n}\n#endif\n\n\n\nstatic int\nid3v2_add_ucs2(lame_t gfp, uint32_t frame_id, char const *lang, unsigned short const *desc, unsigned short const *text);\nstatic int\nid3v2_add_latin1(lame_t gfp, uint32_t frame_id, char const *lang, char const *desc, char const *text);\n\nstatic void\ncopyV1ToV2(lame_t gfp, int frame_id, char const *s)\n{\n    lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0;\n    if (gfc != 0) {\n        unsigned int flags = gfc->tag_spec.flags;\n        id3v2_add_latin1(gfp, frame_id, \"XXX\", 0, s);\n        gfc->tag_spec.flags = flags;\n#if 0\n        debug_tag_spec_flags(gfc, \"copyV1ToV2\");\n#endif\n    }\n}\n\n\nstatic void\nid3v2AddLameVersion(lame_t gfp)\n{\n    char    buffer[1024];\n    const char *b = get_lame_os_bitness();\n    const char *v = get_lame_version();\n    const char *u = get_lame_url();\n    const size_t lenb = strlen(b);\n\n    if (lenb > 0) {\n        sprintf(buffer, \"LAME %s version %s (%s)\", b, v, u);\n    }\n    else {\n        sprintf(buffer, \"LAME version %s (%s)\", v, u);\n    }\n    copyV1ToV2(gfp, ID_ENCODER, buffer);\n}\n\nstatic void\nid3v2AddAudioDuration(lame_t gfp, double ms)\n{\n    lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0;\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    char    buffer[1024];\n    double const max_ulong = MAX_U_32_NUM;\n    unsigned long playlength_ms;\n\n    ms *= 1000;\n    ms /= cfg->samplerate_in;\n    if (ms > max_ulong) {\n        playlength_ms = max_ulong;\n    }\n    else if (ms < 0) {\n        playlength_ms = 0;\n    }\n    else {\n        playlength_ms = ms;\n    }\n    sprintf(buffer, \"%lu\", playlength_ms);\n    copyV1ToV2(gfp, ID_PLAYLENGTH, buffer);\n}\n\nvoid\nid3tag_genre_list(void (*handler) (int, const char *, void *), void *cookie)\n{\n    if (handler) {\n        int     i;\n        for (i = 0; i < GENRE_NAME_COUNT; ++i) {\n            if (i < GENRE_ALPHA_COUNT) {\n                int     j = genre_alpha_map[i];\n                handler(j, genre_names[j], cookie);\n            }\n        }\n    }\n}\n\n#define GENRE_NUM_UNKNOWN 255\n\n\n\nvoid\nid3tag_init(lame_t gfp)\n{\n    lame_internal_flags *gfc = gfp->internal_flags;\n    free_id3tag(gfc);\n    memset(&gfc->tag_spec, 0, sizeof gfc->tag_spec);\n    gfc->tag_spec.genre_id3v1 = GENRE_NUM_UNKNOWN;\n    gfc->tag_spec.padding_size = 128;\n    id3v2AddLameVersion(gfp);\n}\n\n\n\nvoid\nid3tag_add_v2(lame_t gfp)\n{\n    lame_internal_flags *gfc = gfp->internal_flags;\n    gfc->tag_spec.flags &= ~V1_ONLY_FLAG;\n    gfc->tag_spec.flags |= ADD_V2_FLAG;\n}\n\nvoid\nid3tag_v1_only(lame_t gfp)\n{\n    lame_internal_flags *gfc = gfp->internal_flags;\n    gfc->tag_spec.flags &= ~(ADD_V2_FLAG | V2_ONLY_FLAG);\n    gfc->tag_spec.flags |= V1_ONLY_FLAG;\n}\n\nvoid\nid3tag_v2_only(lame_t gfp)\n{\n    lame_internal_flags *gfc = gfp->internal_flags;\n    gfc->tag_spec.flags &= ~V1_ONLY_FLAG;\n    gfc->tag_spec.flags |= V2_ONLY_FLAG;\n}\n\nvoid\nid3tag_space_v1(lame_t gfp)\n{\n    lame_internal_flags *gfc = gfp->internal_flags;\n    gfc->tag_spec.flags &= ~V2_ONLY_FLAG;\n    gfc->tag_spec.flags |= SPACE_V1_FLAG;\n}\n\nvoid\nid3tag_pad_v2(lame_t gfp)\n{\n    id3tag_set_pad(gfp, 128);\n}\n\nvoid\nid3tag_set_pad(lame_t gfp, size_t n)\n{\n    lame_internal_flags *gfc = gfp->internal_flags;\n    gfc->tag_spec.flags &= ~V1_ONLY_FLAG;\n    gfc->tag_spec.flags |= PAD_V2_FLAG;\n    gfc->tag_spec.flags |= ADD_V2_FLAG;\n    gfc->tag_spec.padding_size = (unsigned int)n;\n}\n\nstatic int\nhasUcs2ByteOrderMarker(unsigned short bom)\n{\n    if (bom == 0xFFFEu || bom == 0xFEFFu) {\n        return 1;\n    }\n    return 0;\n}\n\n\nstatic unsigned short\nswap_bytes(unsigned short w)\n{\n    return (0xff00u & (w << 8)) | (0x00ffu & (w >> 8));\n}\n\n\nstatic unsigned short\ntoLittleEndian(unsigned short bom, unsigned short c)\n{\n    if (bom == 0xFFFEu) {\n        return swap_bytes(c);\n    }\n    return c;\n}\n\nstatic unsigned short\nfromLatin1Char(const unsigned short* s, unsigned short c)\n{\n    if (s[0] == 0xFFFEu) {\n        return swap_bytes(c);\n    }\n    return c;\n}\n\n\nstatic  size_t\nlocal_strdup(char **dst, const char *src)\n{\n    if (dst == 0) {\n        return 0;\n    }\n    free(*dst);\n    *dst = 0;\n    if (src != 0) {\n        size_t  n;\n        for (n = 0; src[n] != 0; ++n) { /* calc src string length */\n        }\n        if (n > 0) {    /* string length without zero termination */\n            assert(sizeof(*src) == sizeof(**dst));\n            *dst = lame_calloc(char, n + 1);\n            if (*dst != 0) {\n                memcpy(*dst, src, n * sizeof(**dst));\n                (*dst)[n] = 0;\n                return n;\n            }\n        }\n    }\n    return 0;\n}\n\nstatic  size_t\nlocal_ucs2_strdup(unsigned short **dst, unsigned short const *src)\n{\n    if (dst == 0) {\n        return 0;\n    }\n    free(*dst);         /* free old string pointer */\n    *dst = 0;\n    if (src != 0) {\n        size_t  n;\n        for (n = 0; src[n] != 0; ++n) { /* calc src string length */\n        }\n        if (n > 0) {    /* string length without zero termination */\n            assert(sizeof(*src) >= 2);\n            assert(sizeof(*src) == sizeof(**dst));\n            *dst = lame_calloc(unsigned short, n + 1);\n            if (*dst != 0) {\n                memcpy(*dst, src, n * sizeof(**dst));\n                (*dst)[n] = 0;\n                return n;\n            }\n        }\n    }\n    return 0;\n}\n\n\nstatic  size_t\nlocal_ucs2_strlen(unsigned short const *s)\n{\n    size_t  n = 0;\n    if (s != 0) {\n        while (*s++) {\n            ++n;\n        }\n    }\n    return n;\n}\n\n\nstatic size_t\nlocal_ucs2_substr(unsigned short** dst, unsigned short const* src, size_t start, size_t end)\n{\n    size_t const len = 1 + 1 + ((start < end) ? (end - start) : 0);\n    size_t n = 0;\n    unsigned short *ptr = lame_calloc(unsigned short, len);\n    *dst = ptr;\n    if (ptr == 0 || src == 0) {\n        return 0;\n    }\n    if (hasUcs2ByteOrderMarker(src[0])) {\n        ptr[n++] = src[0];\n        if (start == 0) {\n            ++start;\n        }\n    }\n    while (start < end) {\n        ptr[n++] = src[start++];\n    }\n    ptr[n] = 0;\n    return n;\n}\n\nstatic int\nlocal_ucs2_pos(unsigned short const* str, unsigned short c)\n{\n    int     i;\n    for (i = 0; str != 0 && str[i] != 0; ++i) {\n        if (str[i] == c) {\n            return i;\n        }\n    }\n    return -1;\n}\n\nstatic int\nlocal_char_pos(char const* str, char c)\n{\n    int     i;\n    for (i = 0; str != 0 && str[i] != 0; ++i) {\n        if (str[i] == c) {\n            return i;\n        }\n    }\n    return -1;\n}\n\nstatic int\nmaybeLatin1(unsigned short const* text)\n{\n    if (text) {\n        unsigned short bom = *text++;\n        while (*text) {\n            unsigned short c = toLittleEndian(bom, *text++);\n            if (c > 0x00fe) return 0;\n        }\n    }\n    return 1;\n}\n\nstatic int searchGenre(char const* genre);\nstatic int sloppySearchGenre(char const* genre);\n\nstatic int\nlookupGenre(char const* genre)\n{\n    char   *str;\n    int     num = strtol(genre, &str, 10);\n    /* is the input a string or a valid number? */\n    if (*str) {\n        num = searchGenre(genre);\n        if (num == GENRE_NAME_COUNT) {\n            num = sloppySearchGenre(genre);\n        }\n        if (num == GENRE_NAME_COUNT) {\n            return -2; /* no common genre text found */\n        }\n    }\n    else {\n        if ((num < 0) || (num >= GENRE_NAME_COUNT)) {\n            return -1; /* number unknown */\n        }\n    }\n    return num;\n}\n\nstatic unsigned char *\nwriteLoBytes(unsigned char *frame, unsigned short const *str, size_t n);\n\nstatic char*\nlocal_strdup_utf16_to_latin1(unsigned short const* utf16)\n{\n    size_t  len = local_ucs2_strlen(utf16);\n    unsigned char* latin1 = lame_calloc(unsigned char, len+1);\n    writeLoBytes(latin1, utf16, len);\n    return (char*)latin1;\n}\n\n\nstatic int\nid3tag_set_genre_utf16(lame_t gfp, unsigned short const* text)\n{\n    lame_internal_flags* gfc = gfp->internal_flags;\n    int   ret;\n    if (text == 0) {\n        return -3;\n    }\n    if (!hasUcs2ByteOrderMarker(text[0])) {\n        return -3;\n    }\n    if (maybeLatin1(text)) {\n        char*   latin1 = local_strdup_utf16_to_latin1(text);\n        int     num = lookupGenre(latin1);\n        free(latin1);\n        if (num == -1) return -1; /* number out of range */\n        if (num >= 0) {           /* common genre found  */\n            gfc->tag_spec.flags |= CHANGED_FLAG;\n            gfc->tag_spec.genre_id3v1 = num;\n            copyV1ToV2(gfp, ID_GENRE, genre_names[num]);\n            return 0;\n        }\n    }\n    ret = id3v2_add_ucs2(gfp, ID_GENRE, 0, 0, text);\n    if (ret == 0) {\n        gfc->tag_spec.flags |= CHANGED_FLAG;\n        gfc->tag_spec.genre_id3v1 = GENRE_INDEX_OTHER;\n    }\n    return ret;\n}\n\n/*\nSome existing options for ID3 tag can be specified by --tv option\nas follows.\n--tt <value>, --tv TIT2=value\n--ta <value>, --tv TPE1=value\n--tl <value>, --tv TALB=value\n--ty <value>, --tv TYER=value\n--tn <value>, --tv TRCK=value\n--tg <value>, --tv TCON=value\n(although some are not exactly same)*/\n\nint\nid3tag_set_albumart(lame_t gfp, const char *image, size_t size)\n{\n    int     mimetype = 0;\n    unsigned char const *data = (unsigned char const *) image;\n    lame_internal_flags *gfc = gfp->internal_flags;\n\n    /* determine MIME type from the actual image data */\n    if (2 < size && data[0] == 0xFF && data[1] == 0xD8) {\n        mimetype = MIMETYPE_JPEG;\n    }\n    else if (4 < size && data[0] == 0x89 && strncmp((const char *) &data[1], \"PNG\", 3) == 0) {\n        mimetype = MIMETYPE_PNG;\n    }\n    else if (4 < size && strncmp((const char *) data, \"GIF8\", 4) == 0) {\n        mimetype = MIMETYPE_GIF;\n    }\n    else {\n        return -1;\n    }\n    if (gfc->tag_spec.albumart != 0) {\n        free(gfc->tag_spec.albumart);\n        gfc->tag_spec.albumart = 0;\n        gfc->tag_spec.albumart_size = 0;\n        gfc->tag_spec.albumart_mimetype = MIMETYPE_NONE;\n    }\n    if (size < 1) {\n        return 0;\n    }\n    gfc->tag_spec.albumart = lame_calloc(unsigned char, size);\n    if (gfc->tag_spec.albumart != 0) {\n        memcpy(gfc->tag_spec.albumart, image, size);\n        gfc->tag_spec.albumart_size = (unsigned int)size;\n        gfc->tag_spec.albumart_mimetype = mimetype;\n        gfc->tag_spec.flags |= CHANGED_FLAG;\n        id3tag_add_v2(gfp);\n    }\n    return 0;\n}\n\nstatic unsigned char *\nset_4_byte_value(unsigned char *bytes, uint32_t value)\n{\n    int     i;\n    for (i = 3; i >= 0; --i) {\n        bytes[i] = value & 0xffUL;\n        value >>= 8;\n    }\n    return bytes + 4;\n}\n\nstatic uint32_t\ntoID3v2TagId(char const *s)\n{\n    unsigned int i, x = 0;\n    if (s == 0) {\n        return 0;\n    }\n    for (i = 0; i < 4 && s[i] != 0; ++i) {\n        char const c = s[i];\n        unsigned int const u = 0x0ff & c;\n        x <<= 8;\n        x |= u;\n        if (c < 'A' || 'Z' < c) {\n            if (c < '0' || '9' < c) {\n                return 0;\n            }\n        }\n    }\n    return x;\n}\n\nstatic uint32_t\ntoID3v2TagId_ucs2(unsigned short const *s)\n{\n    unsigned int i, x = 0;\n    unsigned short bom = 0;\n    if (s == 0) {\n        return 0;\n    }\n    bom = s[0];\n    if (hasUcs2ByteOrderMarker(bom)) {\n        ++s;\n    }\n    for (i = 0; i < 4 && s[i] != 0; ++i) {\n        unsigned short const c = toLittleEndian(bom, s[i]);\n        if (c < 'A' || 'Z' < c) {\n            if (c < '0' || '9' < c) {\n                return 0;\n            }\n        }\n        x <<= 8;\n        x |= c;\n    }\n    return x;\n}\n\n#if 0\nstatic int\nisNumericString(uint32_t frame_id)\n{\n    switch (frame_id) {\n    case ID_DATE:\n    case ID_TIME:\n    case ID_TPOS:\n    case ID_TRACK:\n    case ID_YEAR:\n        return 1;\n    }\n    return 0;\n}\n#endif\n\nstatic int\nisMultiFrame(uint32_t frame_id)\n{\n    switch (frame_id) {\n    case ID_TXXX:\n    case ID_WXXX:\n    case ID_COMMENT:\n    case ID_SYLT:\n    case ID_APIC:\n    case ID_GEOB:\n    case ID_PCNT:\n    case ID_AENC:\n    case ID_LINK:\n    case ID_ENCR:\n    case ID_GRID:\n    case ID_PRIV:\n        return 1;\n    }\n    return 0;\n}\n\n#if 0\nstatic int\nisFullTextString(int frame_id)\n{\n    switch (frame_id) {\n    case ID_VSLT:\n    case ID_COMMENT:\n        return 1;\n    }\n    return 0;\n}\n#endif\n\nstatic FrameDataNode *\nfindNode(id3tag_spec const *tag, uint32_t frame_id, FrameDataNode const *last)\n{\n    FrameDataNode *node = last ? last->nxt : tag->v2_head;\n    while (node != 0) {\n        if (node->fid == frame_id) {\n            return node;\n        }\n        node = node->nxt;\n    }\n    return 0;\n}\n\nstatic void\nappendNode(id3tag_spec * tag, FrameDataNode * node)\n{\n    if (tag->v2_tail == 0 || tag->v2_head == 0) {\n        tag->v2_head = node;\n        tag->v2_tail = node;\n    }\n    else {\n        tag->v2_tail->nxt = node;\n        tag->v2_tail = node;\n    }\n}\n\nstatic void\nsetLang(char *dst, char const *src)\n{\n    int     i;\n    if (src == 0 || src[0] == 0) {\n        dst[0] = 'X';\n        dst[1] = 'X';\n        dst[2] = 'X';\n    }\n    else {\n        for (i = 0; i < 3 && src && *src; ++i) {\n            dst[i] = src[i];\n        }\n        for (; i < 3; ++i) {\n            dst[i] = ' ';\n        }\n    }\n}\n\nstatic int\nisSameLang(char const *l1, char const *l2)\n{\n    char    d[3];\n    int     i;\n    setLang(d, l2);\n    for (i = 0; i < 3; ++i) {\n        char    a = tolower(l1[i]);\n        char    b = tolower(d[i]);\n        if (a < ' ')\n            a = ' ';\n        if (b < ' ')\n            b = ' ';\n        if (a != b) {\n            return 0;\n        }\n    }\n    return 1;\n}\n\nstatic int\nisSameDescriptor(FrameDataNode const *node, char const *dsc)\n{\n    size_t  i;\n    if (node->dsc.enc == 1 && node->dsc.dim > 0) {\n        return 0;\n    }\n    for (i = 0; i < node->dsc.dim; ++i) {\n        if (!dsc || node->dsc.ptr.l[i] != dsc[i]) {\n            return 0;\n        }\n    }\n    return 1;\n}\n\nstatic int\nisSameDescriptorUcs2(FrameDataNode const *node, unsigned short const *dsc)\n{\n    size_t  i;\n    if (node->dsc.enc != 1 && node->dsc.dim > 0) {\n        return 0;\n    }\n    for (i = 0; i < node->dsc.dim; ++i) {\n        if (!dsc || node->dsc.ptr.u[i] != dsc[i]) {\n            return 0;\n        }\n    }\n    return 1;\n}\n\nstatic int\nid3v2_add_ucs2(lame_t gfp, uint32_t frame_id, char const *lang, unsigned short const *desc, unsigned short const *text)\n{\n    lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0;\n    if (gfc != 0) {\n        FrameDataNode *node = findNode(&gfc->tag_spec, frame_id, 0);\n        if (isMultiFrame(frame_id)) {\n            while (node) {\n                if (isSameLang(node->lng, lang)) {\n                    if (isSameDescriptorUcs2(node, desc)) {\n                        break;\n                    }\n                }\n                node = findNode(&gfc->tag_spec, frame_id, node);\n            }\n        }\n        if (node == 0) {\n            node = lame_calloc(FrameDataNode, 1);\n            if (node == 0) {\n                return -254; /* memory problem */\n            }\n            appendNode(&gfc->tag_spec, node);\n        }\n        node->fid = frame_id;\n        setLang(node->lng, lang);\n        node->dsc.dim = local_ucs2_strdup(&node->dsc.ptr.u, desc);\n        node->dsc.enc = 1;\n        node->txt.dim = local_ucs2_strdup(&node->txt.ptr.u, text);\n        node->txt.enc = 1;\n        gfc->tag_spec.flags |= (CHANGED_FLAG | ADD_V2_FLAG);\n        return 0;\n    }\n    return -255;\n}\n\nstatic int\nid3v2_add_latin1(lame_t gfp, uint32_t frame_id, char const *lang, char const *desc, char const *text)\n{\n    lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0;\n    if (gfc != 0) {\n        FrameDataNode *node = findNode(&gfc->tag_spec, frame_id, 0);\n        if (isMultiFrame(frame_id)) {\n            while (node) {\n                if (isSameLang(node->lng, lang)) {\n                    if (isSameDescriptor(node, desc)) {\n                        break;\n                    }\n                }\n                node = findNode(&gfc->tag_spec, frame_id, node);\n            }\n        }\n        if (node == 0) {\n            node = lame_calloc(FrameDataNode, 1);\n            if (node == 0) {\n                return -254; /* memory problem */\n            }\n            appendNode(&gfc->tag_spec, node);\n        }\n        node->fid = frame_id;\n        setLang(node->lng, lang);\n        node->dsc.dim = local_strdup(&node->dsc.ptr.l, desc);\n        node->dsc.enc = 0;\n        node->txt.dim = local_strdup(&node->txt.ptr.l, text);\n        node->txt.enc = 0;\n        gfc->tag_spec.flags |= (CHANGED_FLAG | ADD_V2_FLAG);\n        return 0;\n    }\n    return -255;\n}\n\n\nstatic int\nid3tag_set_userinfo_latin1(lame_t gfp, uint32_t id, char const *fieldvalue)\n{\n    char const separator = '=';\n    int     rc = -7;\n    int     a = local_char_pos(fieldvalue, separator);\n    if (a >= 0) {\n        char*   dup = 0;\n        local_strdup(&dup, fieldvalue);\n        dup[a] = 0;\n        rc = id3v2_add_latin1(gfp, id, \"XXX\", dup, dup+a+1);\n        free(dup);\n    }\n    return rc;\n}\n\nstatic int\nid3tag_set_userinfo_ucs2(lame_t gfp, uint32_t id, unsigned short const *fieldvalue)\n{\n    unsigned short const separator = fromLatin1Char(fieldvalue,'=');\n    int     rc = -7;\n    size_t  b = local_ucs2_strlen(fieldvalue);\n    int     a = local_ucs2_pos(fieldvalue, separator);\n    if (a >= 0) { \n        unsigned short* dsc = 0, *val = 0;\n        local_ucs2_substr(&dsc, fieldvalue, 0, a);\n        local_ucs2_substr(&val, fieldvalue, a+1, b);\n        rc = id3v2_add_ucs2(gfp, id, \"XXX\", dsc, val);\n        free(dsc);\n        free(val);\n    }\n    return rc;\n}\n\nint\nid3tag_set_textinfo_utf16(lame_t gfp, char const *id, unsigned short const *text)\n{\n    uint32_t const frame_id = toID3v2TagId(id);\n    if (frame_id == 0) {\n        return -1;\n    }\n    if (text == 0) {\n        return 0;\n    }\n    if (!hasUcs2ByteOrderMarker(text[0])) {\n        return -3;  /* BOM missing */\n    }\n    if (frame_id == ID_TXXX || frame_id == ID_WXXX || frame_id == ID_COMMENT) {\n        return id3tag_set_userinfo_ucs2(gfp, frame_id, text);\n    }\n    if (frame_id == ID_GENRE) {\n        return id3tag_set_genre_utf16(gfp, text);\n    }\n    if (frame_id == ID_PCST) {\n        return id3v2_add_ucs2(gfp, frame_id, 0, 0, text);\n    }\n    if (frame_id == ID_USER) {\n        return id3v2_add_ucs2(gfp, frame_id, \"XXX\", text, 0);\n    }\n    if (frame_id == ID_WFED) {\n        return id3v2_add_ucs2(gfp, frame_id, 0, text, 0); /* iTunes expects WFED to be a text frame */\n    }\n    if (isFrameIdMatching(frame_id, FRAME_ID('T', 0, 0, 0))\n      ||isFrameIdMatching(frame_id, FRAME_ID('W', 0, 0, 0))) {\n#if 0\n        if (isNumericString(frame_id)) {\n            return -2;  /* must be Latin-1 encoded */\n        }\n#endif\n        return id3v2_add_ucs2(gfp, frame_id, 0, 0, text);\n    }\n    return -255;        /* not supported by now */\n}\n\nextern int\nid3tag_set_textinfo_ucs2(lame_t gfp, char const *id, unsigned short const *text);\n\nint\nid3tag_set_textinfo_ucs2(lame_t gfp, char const *id, unsigned short const *text)\n{\n    return id3tag_set_textinfo_utf16(gfp, id, text);\n}\n\nint\nid3tag_set_textinfo_latin1(lame_t gfp, char const *id, char const *text)\n{\n    uint32_t const frame_id = toID3v2TagId(id);\n    if (frame_id == 0) {\n        return -1;\n    }\n    if (text == 0) {\n        return 0;\n    }\n    if (frame_id == ID_TXXX || frame_id == ID_WXXX || frame_id == ID_COMMENT) {\n        return id3tag_set_userinfo_latin1(gfp, frame_id, text);\n    }\n    if (frame_id == ID_GENRE) {\n        return id3tag_set_genre(gfp, text);\n    }\n    if (frame_id == ID_PCST) {\n        return id3v2_add_latin1(gfp, frame_id, 0, 0, text);\n    }\n    if (frame_id == ID_USER) {\n        return id3v2_add_latin1(gfp, frame_id, \"XXX\", text, 0);\n    }\n    if (frame_id == ID_WFED) {\n        return id3v2_add_latin1(gfp, frame_id, 0, text, 0); /* iTunes expects WFED to be a text frame */\n    }\n    if (isFrameIdMatching(frame_id, FRAME_ID('T', 0, 0, 0))\n      ||isFrameIdMatching(frame_id, FRAME_ID('W', 0, 0, 0))) {\n        return id3v2_add_latin1(gfp, frame_id, 0, 0, text);\n    }\n    return -255;        /* not supported by now */\n}\n\n\nint\nid3tag_set_comment_latin1(lame_t gfp, char const *lang, char const *desc, char const *text)\n{\n    return id3v2_add_latin1(gfp, ID_COMMENT, lang, desc, text);\n}\n\n\nint\nid3tag_set_comment_utf16(lame_t gfp, char const *lang, unsigned short const *desc, unsigned short const *text)\n{\n    return id3v2_add_ucs2(gfp, ID_COMMENT, lang, desc, text);\n}\n\nextern int\nid3tag_set_comment_ucs2(lame_t gfp, char const *lang, unsigned short const *desc, unsigned short const *text);\n\n\nint\nid3tag_set_comment_ucs2(lame_t gfp, char const *lang, unsigned short const *desc, unsigned short const *text)\n{\n    return id3tag_set_comment_utf16(gfp, lang, desc, text);\n}\n\n\nvoid\nid3tag_set_title(lame_t gfp, const char *title)\n{\n    lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0;\n    if (gfc && title && *title) {\n        local_strdup(&gfc->tag_spec.title, title);\n        gfc->tag_spec.flags |= CHANGED_FLAG;\n        copyV1ToV2(gfp, ID_TITLE, title);\n    }\n}\n\nvoid\nid3tag_set_artist(lame_t gfp, const char *artist)\n{\n    lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0;\n    if (gfc && artist && *artist) {\n        local_strdup(&gfc->tag_spec.artist, artist);\n        gfc->tag_spec.flags |= CHANGED_FLAG;\n        copyV1ToV2(gfp, ID_ARTIST, artist);\n    }\n}\n\nvoid\nid3tag_set_album(lame_t gfp, const char *album)\n{\n    lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0;\n    if (gfc && album && *album) {\n        local_strdup(&gfc->tag_spec.album, album);\n        gfc->tag_spec.flags |= CHANGED_FLAG;\n        copyV1ToV2(gfp, ID_ALBUM, album);\n    }\n}\n\nvoid\nid3tag_set_year(lame_t gfp, const char *year)\n{\n    lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0;\n    if (gfc && year && *year) {\n        int     num = atoi(year);\n        if (num < 0) {\n            num = 0;\n        }\n        /* limit a year to 4 digits so it fits in a version 1 tag */\n        if (num > 9999) {\n            num = 9999;\n        }\n        if (num) {\n            gfc->tag_spec.year = num;\n            gfc->tag_spec.flags |= CHANGED_FLAG;\n        }\n        copyV1ToV2(gfp, ID_YEAR, year);\n    }\n}\n\nvoid\nid3tag_set_comment(lame_t gfp, const char *comment)\n{\n    lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0;\n    if (gfc && comment && *comment) {\n        local_strdup(&gfc->tag_spec.comment, comment);\n        gfc->tag_spec.flags |= CHANGED_FLAG;\n        {\n            uint32_t const flags = gfc->tag_spec.flags;\n            id3v2_add_latin1(gfp, ID_COMMENT, \"XXX\", \"\", comment);\n            gfc->tag_spec.flags = flags;\n        }\n    }\n}\n\nint\nid3tag_set_track(lame_t gfp, const char *track)\n{\n    char const *trackcount;\n    lame_internal_flags *gfc = gfp != 0 ? gfp->internal_flags : 0;\n    int     ret = 0;\n\n    if (gfc && track && *track) {\n        int     num = atoi(track);\n        /* check for valid ID3v1 track number range */\n        if (num < 1 || num > 255) {\n            num = 0;\n            ret = -1;   /* track number out of ID3v1 range, ignored for ID3v1 */\n            gfc->tag_spec.flags |= (CHANGED_FLAG | ADD_V2_FLAG);\n        }\n        if (num) {\n            gfc->tag_spec.track_id3v1 = num;\n            gfc->tag_spec.flags |= CHANGED_FLAG;\n        }\n        /* Look for the total track count after a \"/\", same restrictions */\n        trackcount = strchr(track, '/');\n        if (trackcount && *trackcount) {\n            gfc->tag_spec.flags |= (CHANGED_FLAG | ADD_V2_FLAG);\n        }\n        copyV1ToV2(gfp, ID_TRACK, track);\n    }\n    return ret;\n}\n\n/* would use real \"strcasecmp\" but it isn't portable */\nstatic int\nlocal_strcasecmp(const char *s1, const char *s2)\n{\n    unsigned char c1;\n    unsigned char c2;\n    do {\n        c1 = tolower(*s1);\n        c2 = tolower(*s2);\n        if (!c1) {\n            break;\n        }\n        ++s1;\n        ++s2;\n    } while (c1 == c2);\n    return c1 - c2;\n}\n\n\nstatic \nconst char* nextUpperAlpha(const char* p, char x)\n{\n    char c;\n    for(c = toupper(*p); *p != 0; c = toupper(*++p)) {\n        if ('A' <= c && c <= 'Z') {\n            if (c != x) {\n                return p;\n            }\n        }\n    }\n    return p;\n}\n\n\nstatic int\nsloppyCompared(const char* p, const char* q)\n{\n    char cp, cq;\n    p = nextUpperAlpha(p, 0);\n    q = nextUpperAlpha(q, 0);\n    cp = toupper(*p);\n    cq = toupper(*q);\n    while (cp == cq) {\n        if (cp == 0) {\n            return 1;\n        }\n        if (p[1] == '.') { /* some abbrevation */\n            while (*q && *q++ != ' ') {\n            }\n        }\n        p = nextUpperAlpha(p, cp);\n        q = nextUpperAlpha(q, cq);\n        cp = toupper(*p);\n        cq = toupper(*q);\n    }\n    return 0;\n}\n\n\nstatic int \nsloppySearchGenre(const char *genre)\n{\n    int i;\n    for (i = 0; i < GENRE_NAME_COUNT; ++i) {\n        if (sloppyCompared(genre, genre_names[i])) {\n            return i;\n        }\n    }\n    return GENRE_NAME_COUNT;\n}\n\n\nstatic int\nsearchGenre(const char* genre)\n{\n    int i;\n    for (i = 0; i < GENRE_NAME_COUNT; ++i) {\n        if (!local_strcasecmp(genre, genre_names[i])) {\n            return i;\n        }\n    }\n    return GENRE_NAME_COUNT;\n}\n\n\nint\nid3tag_set_genre(lame_t gfp, const char *genre)\n{\n    lame_internal_flags *gfc = gfp->internal_flags;\n    int     ret = 0;\n    if (genre && *genre) {\n        int const num = lookupGenre(genre);\n        if (num == -1) return num;\n        gfc->tag_spec.flags |= CHANGED_FLAG;\n        if (num >= 0) {\n            gfc->tag_spec.genre_id3v1 = num;\n            genre = genre_names[num];\n        }\n        else {\n            gfc->tag_spec.genre_id3v1 = GENRE_INDEX_OTHER;\n            gfc->tag_spec.flags |= ADD_V2_FLAG;\n        }\n        copyV1ToV2(gfp, ID_GENRE, genre);\n    }\n    return ret;\n}\n\n\nstatic  size_t\nsizeOfNode(FrameDataNode const *node)\n{\n    size_t  n = 0;\n    if (node) {\n        n = 10;         /* header size */\n        n += 1;         /* text encoding flag */\n        switch (node->txt.enc) {\n        default:\n        case 0:\n            if (node->dsc.dim > 0) {\n                n += node->dsc.dim + 1;\n            }\n            n += node->txt.dim;\n            break;\n        case 1:\n            if (node->dsc.dim > 0) {\n                n += (node->dsc.dim+1) * 2;\n            }\n            n += node->txt.dim * 2;\n            break;\n        }\n    }\n    return n;\n}\n\nstatic  size_t\nsizeOfCommentNode(FrameDataNode const *node)\n{\n    size_t  n = 0;\n    if (node) {\n        n = 10;         /* header size */\n        n += 1;         /* text encoding flag */\n        n += 3;         /* language */\n        switch (node->dsc.enc) {\n        default:\n        case 0:\n            n += 1 + node->dsc.dim;\n            break;\n        case 1:\n            n += 2 + node->dsc.dim * 2;\n            break;\n        }\n        switch (node->txt.enc) {\n        default:\n        case 0:\n            n += node->txt.dim;\n            break;\n        case 1:\n            n += node->txt.dim * 2;\n            break;\n        }\n    }\n    return n;\n}\n\nstatic size_t\nsizeOfWxxxNode(FrameDataNode const *node)\n{\n    size_t  n = 0;\n    if (node) {\n        n = 10;         /* header size */\n        if (node->dsc.dim > 0) {\n            n += 1;         /* text encoding flag */\n            switch (node->dsc.enc) {\n            default:\n            case 0:\n                n += 1 + node->dsc.dim;\n                break;\n            case 1:\n                n += 2 + node->dsc.dim * 2;\n                break;\n            }\n        }\n        if (node->txt.dim > 0) {\n            switch (node->txt.enc) {\n            default:\n            case 0:\n                n += node->txt.dim;\n                break;\n            case 1:\n                n += node->txt.dim - 1; /* UCS2 -> Latin1, skip BOM */\n                break;\n            }\n        }\n    }\n    return n;\n}\n\nstatic unsigned char *\nwriteChars(unsigned char *frame, char const *str, size_t n)\n{\n    while (n--) {\n        *frame++ = *str++;\n    }\n    return frame;\n}\n\nstatic unsigned char *\nwriteUcs2s(unsigned char *frame, unsigned short const *str, size_t n)\n{\n    if (n > 0) {\n        unsigned short const bom = *str;\n        while (n--) {\n            unsigned short const c = toLittleEndian(bom, *str++);\n            *frame++ = 0x00ffu & c;\n            *frame++ = 0x00ffu & (c >> 8);\n        }\n    }\n    return frame;\n}\n\nstatic unsigned char *\nwriteLoBytes(unsigned char *frame, unsigned short const *str, size_t n)\n{\n    if (n > 0) {\n        unsigned short const bom = *str;\n        if (hasUcs2ByteOrderMarker(bom)) {\n            str++; n--; /* skip BOM */\n        }\n        while (n--) {\n            unsigned short const c = toLittleEndian(bom, *str++);\n            if (c < 0x0020u || 0x00ffu < c) {\n                *frame++ = 0x0020; /* blank */\n            }\n            else {\n                *frame++ = c;\n            }\n        }\n    }\n    return frame;\n}\n\nstatic unsigned char *\nset_frame_comment(unsigned char *frame, FrameDataNode const *node)\n{\n    size_t const n = sizeOfCommentNode(node);\n    if (n > 10) {\n        frame = set_4_byte_value(frame, node->fid);\n        frame = set_4_byte_value(frame, (uint32_t) (n - 10));\n        /* clear 2-byte header flags */\n        *frame++ = 0;\n        *frame++ = 0;\n        /* encoding descriptor byte */\n        *frame++ = node->txt.enc == 1 ? 1 : 0;\n        /* 3 bytes language */\n        *frame++ = node->lng[0];\n        *frame++ = node->lng[1];\n        *frame++ = node->lng[2];\n        /* descriptor with zero byte(s) separator */\n        if (node->dsc.enc != 1) {\n            frame = writeChars(frame, node->dsc.ptr.l, node->dsc.dim);\n            *frame++ = 0;\n        }\n        else {\n            frame = writeUcs2s(frame, node->dsc.ptr.u, node->dsc.dim);\n            *frame++ = 0;\n            *frame++ = 0;\n        }\n        /* comment full text */\n        if (node->txt.enc != 1) {\n            frame = writeChars(frame, node->txt.ptr.l, node->txt.dim);\n        }\n        else {\n            frame = writeUcs2s(frame, node->txt.ptr.u, node->txt.dim);\n        }\n    }\n    return frame;\n}\n\nstatic unsigned char *\nset_frame_custom2(unsigned char *frame, FrameDataNode const *node)\n{\n    size_t const n = sizeOfNode(node);\n    if (n > 10) {\n        frame = set_4_byte_value(frame, node->fid);\n        frame = set_4_byte_value(frame, (unsigned long) (n - 10));\n        /* clear 2-byte header flags */\n        *frame++ = 0;\n        *frame++ = 0;\n        /* clear 1 encoding descriptor byte to indicate ISO-8859-1 format */\n        *frame++ = node->txt.enc == 1 ? 1 : 0;\n        if (node->dsc.dim > 0) {\n            if (node->dsc.enc != 1) {\n                frame = writeChars(frame, node->dsc.ptr.l, node->dsc.dim);\n                *frame++ = 0;\n            }\n            else {\n                frame = writeUcs2s(frame, node->dsc.ptr.u, node->dsc.dim);\n                *frame++ = 0;\n                *frame++ = 0;\n            }\n        }\n        if (node->txt.enc != 1) {\n            frame = writeChars(frame, node->txt.ptr.l, node->txt.dim);\n        }\n        else {\n            frame = writeUcs2s(frame, node->txt.ptr.u, node->txt.dim);\n        }\n    }\n    return frame;\n}\n\nstatic unsigned char *\nset_frame_wxxx(unsigned char *frame, FrameDataNode const *node)\n{\n    size_t const n = sizeOfWxxxNode(node);\n    if (n > 10) {\n        frame = set_4_byte_value(frame, node->fid);\n        frame = set_4_byte_value(frame, (unsigned long) (n - 10));\n        /* clear 2-byte header flags */\n        *frame++ = 0;\n        *frame++ = 0;\n        if (node->dsc.dim > 0) {\n            /* clear 1 encoding descriptor byte to indicate ISO-8859-1 format */\n            *frame++ = node->dsc.enc == 1 ? 1 : 0;\n            if (node->dsc.enc != 1) {\n                frame = writeChars(frame, node->dsc.ptr.l, node->dsc.dim);\n                *frame++ = 0;\n            }\n            else {\n                frame = writeUcs2s(frame, node->dsc.ptr.u, node->dsc.dim);\n                *frame++ = 0;\n                *frame++ = 0;\n            }\n        }\n        if (node->txt.enc != 1) {\n            frame = writeChars(frame, node->txt.ptr.l, node->txt.dim);\n        }\n        else {\n            frame = writeLoBytes(frame, node->txt.ptr.u, node->txt.dim);\n        }\n    }\n    return frame;\n}\n\nstatic unsigned char *\nset_frame_apic(unsigned char *frame, const char *mimetype, const unsigned char *data, size_t size)\n{\n    /* ID3v2.3 standard APIC frame:\n     *     <Header for 'Attached picture', ID: \"APIC\">\n     *     Text encoding    $xx\n     *     MIME type        <text string> $00\n     *     Picture type     $xx\n     *     Description      <text string according to encoding> $00 (00)\n     *     Picture data     <binary data>\n     */\n    if (mimetype && data && size) {\n        frame = set_4_byte_value(frame, FRAME_ID('A', 'P', 'I', 'C'));\n        frame = set_4_byte_value(frame, (unsigned long) (4 + strlen(mimetype) + size));\n        /* clear 2-byte header flags */\n        *frame++ = 0;\n        *frame++ = 0;\n        /* clear 1 encoding descriptor byte to indicate ISO-8859-1 format */\n        *frame++ = 0;\n        /* copy mime_type */\n        while (*mimetype) {\n            *frame++ = *mimetype++;\n        }\n        *frame++ = 0;\n        /* set picture type to 0 */\n        *frame++ = 0;\n        /* empty description field */\n        *frame++ = 0;\n        /* copy the image data */\n        while (size--) {\n            *frame++ = *data++;\n        }\n    }\n    return frame;\n}\n\nint\nid3tag_set_fieldvalue(lame_t gfp, const char *fieldvalue)\n{\n    if (fieldvalue && *fieldvalue) {\n        if (strlen(fieldvalue) < 5 || fieldvalue[4] != '=') {\n            return -1;\n        }\n        return id3tag_set_textinfo_latin1(gfp, fieldvalue, &fieldvalue[5]);\n    }\n    return 0;\n}\n\nint\nid3tag_set_fieldvalue_utf16(lame_t gfp, const unsigned short *fieldvalue)\n{\n    if (fieldvalue && *fieldvalue) {\n        size_t dx = hasUcs2ByteOrderMarker(fieldvalue[0]);\n        unsigned short const separator = fromLatin1Char(fieldvalue, '=');\n        char fid[5] = {0,0,0,0,0};\n        uint32_t const frame_id = toID3v2TagId_ucs2(fieldvalue);\n        if (local_ucs2_strlen(fieldvalue) < (5+dx) || fieldvalue[4+dx] != separator) {\n            return -1;\n        }\n        fid[0] = (frame_id >> 24) & 0x0ff;\n        fid[1] = (frame_id >> 16) & 0x0ff;\n        fid[2] = (frame_id >> 8) & 0x0ff;\n        fid[3] = frame_id & 0x0ff;\n        if (frame_id != 0) {\n            unsigned short* txt = 0;\n            int     rc;\n            local_ucs2_substr(&txt, fieldvalue, dx+5, local_ucs2_strlen(fieldvalue));\n            rc = id3tag_set_textinfo_utf16(gfp, fid, txt);\n            free(txt);\n            return rc;\n        }\n    }\n    return -1;\n}\n\nextern int\nid3tag_set_fieldvalue_ucs2(lame_t gfp, const unsigned short *fieldvalue);\n\nint\nid3tag_set_fieldvalue_ucs2(lame_t gfp, const unsigned short *fieldvalue)\n{\n    return id3tag_set_fieldvalue_utf16(gfp, fieldvalue);\n}\n\nsize_t\nlame_get_id3v2_tag(lame_t gfp, unsigned char *buffer, size_t size)\n{\n    lame_internal_flags *gfc;\n    if (gfp == 0) {\n        return 0;\n    }\n    gfc = gfp->internal_flags;\n    if (gfc == 0) {\n        return 0;\n    }\n    if (test_tag_spec_flags(gfc, V1_ONLY_FLAG)) {\n        return 0;\n    }\n#if 0\n    debug_tag_spec_flags(gfc, \"lame_get_id3v2_tag\");\n#endif\n    {\n        int usev2 = test_tag_spec_flags(gfc, ADD_V2_FLAG | V2_ONLY_FLAG);\n        /* calculate length of four fields which may not fit in verion 1 tag */\n        size_t  title_length = gfc->tag_spec.title ? strlen(gfc->tag_spec.title) : 0;\n        size_t  artist_length = gfc->tag_spec.artist ? strlen(gfc->tag_spec.artist) : 0;\n        size_t  album_length = gfc->tag_spec.album ? strlen(gfc->tag_spec.album) : 0;\n        size_t  comment_length = gfc->tag_spec.comment ? strlen(gfc->tag_spec.comment) : 0;\n        /* write tag if explicitly requested or if fields overflow */\n        if ((title_length > 30)\n            || (artist_length > 30)\n            || (album_length > 30)\n            || (comment_length > 30)\n            || (gfc->tag_spec.track_id3v1 && (comment_length > 28))) {\n            usev2 = 1;\n        }\n        if (usev2) {\n            size_t  tag_size;\n            unsigned char *p;\n            size_t  adjusted_tag_size;\n            const char *albumart_mime = NULL;\n            static const char *mime_jpeg = \"image/jpeg\";\n            static const char *mime_png = \"image/png\";\n            static const char *mime_gif = \"image/gif\";\n\n            if (gfp->num_samples != MAX_U_32_NUM) {\n                id3v2AddAudioDuration(gfp, gfp->num_samples);\n            }\n\n            /* calulate size of tag starting with 10-byte tag header */\n            tag_size = 10;\n            if (gfc->tag_spec.albumart && gfc->tag_spec.albumart_size) {\n                switch (gfc->tag_spec.albumart_mimetype) {\n                case MIMETYPE_JPEG:\n                    albumart_mime = mime_jpeg;\n                    break;\n                case MIMETYPE_PNG:\n                    albumart_mime = mime_png;\n                    break;\n                case MIMETYPE_GIF:\n                    albumart_mime = mime_gif;\n                    break;\n                }\n                if (albumart_mime) {\n                    tag_size += 10 + 4 + strlen(albumart_mime) + gfc->tag_spec.albumart_size;\n                }\n            }\n            {\n                id3tag_spec *tag = &gfc->tag_spec;\n                if (tag->v2_head != 0) {\n                    FrameDataNode *node;\n                    for (node = tag->v2_head; node != 0; node = node->nxt) {\n                        if (node->fid == ID_COMMENT || node->fid == ID_USER) {\n                            tag_size += sizeOfCommentNode(node);\n                        }\n                        else if (isFrameIdMatching(node->fid, FRAME_ID('W',0,0,0))) {\n                            tag_size += sizeOfWxxxNode(node);\n                        }\n                        else {\n                            tag_size += sizeOfNode(node);\n                        }\n                    }\n                }\n            }\n            if (test_tag_spec_flags(gfc, PAD_V2_FLAG)) {\n                /* add some bytes of padding */\n                tag_size += gfc->tag_spec.padding_size;\n            }\n            if (size < tag_size) {\n                return tag_size;\n            }\n            if (buffer == 0) {\n                return 0;\n            }\n            p = buffer;\n            /* set tag header starting with file identifier */\n            *p++ = 'I';\n            *p++ = 'D';\n            *p++ = '3';\n            /* set version number word */\n            *p++ = 3;\n            *p++ = 0;\n            /* clear flags byte */\n            *p++ = 0;\n            /* calculate and set tag size = total size - header size */\n            adjusted_tag_size = tag_size - 10;\n            /* encode adjusted size into four bytes where most significant \n             * bit is clear in each byte, for 28-bit total */\n            *p++ = (unsigned char) ((adjusted_tag_size >> 21) & 0x7fu);\n            *p++ = (unsigned char) ((adjusted_tag_size >> 14) & 0x7fu);\n            *p++ = (unsigned char) ((adjusted_tag_size >> 7) & 0x7fu);\n            *p++ = (unsigned char) (adjusted_tag_size & 0x7fu);\n\n            /*\n             * NOTE: The remainder of the tag (frames and padding, if any)\n             * are not \"unsynchronized\" to prevent false MPEG audio headers\n             * from appearing in the bitstream.  Why?  Well, most players\n             * and utilities know how to skip the ID3 version 2 tag by now\n             * even if they don't read its contents, and it's actually\n             * very unlikely that such a false \"sync\" pattern would occur\n             * in just the simple text frames added here.\n             */\n\n            /* set each frame in tag */\n            {\n                id3tag_spec *tag = &gfc->tag_spec;\n                if (tag->v2_head != 0) {\n                    FrameDataNode *node;\n                    for (node = tag->v2_head; node != 0; node = node->nxt) {\n                        if (node->fid == ID_COMMENT || node->fid == ID_USER) {\n                            p = set_frame_comment(p, node);\n                        }\n                        else if (isFrameIdMatching(node->fid,FRAME_ID('W',0,0,0))) {\n                            p = set_frame_wxxx(p, node);\n                        }\n                        else {\n                            p = set_frame_custom2(p, node);\n                        }\n                    }\n                }\n            }\n            if (albumart_mime) {\n                p = set_frame_apic(p, albumart_mime, gfc->tag_spec.albumart,\n                                   gfc->tag_spec.albumart_size);\n            }\n            /* clear any padding bytes */\n            memset(p, 0, tag_size - (p - buffer));\n            return tag_size;\n        }\n    }\n    return 0;\n}\n\nint\nid3tag_write_v2(lame_t gfp)\n{\n    lame_internal_flags *gfc = gfp->internal_flags;\n#if 0\n    debug_tag_spec_flags(gfc, \"write v2\");\n#endif\n    if (test_tag_spec_flags(gfc, V1_ONLY_FLAG)) {\n        return 0;\n    }\n    if (test_tag_spec_flags(gfc, CHANGED_FLAG)) {\n        unsigned char *tag = 0;\n        size_t  tag_size, n;\n\n        n = lame_get_id3v2_tag(gfp, 0, 0);\n        tag = lame_calloc(unsigned char, n);\n        if (tag == 0) {\n            return -1;\n        }\n        tag_size = lame_get_id3v2_tag(gfp, tag, n);\n        if (tag_size > n) {\n            free(tag);\n            return -1;\n        }\n        else {\n            size_t  i;\n            /* write tag directly into bitstream at current position */\n            for (i = 0; i < tag_size; ++i) {\n                add_dummy_byte(gfc, tag[i], 1);\n            }\n        }\n        free(tag);\n        return (int) tag_size; /* ok, tag should not exceed 2GB */\n    }\n    return 0;\n}\n\nstatic unsigned char *\nset_text_field(unsigned char *field, const char *text, size_t size, int pad)\n{\n    while (size--) {\n        if (text && *text) {\n            *field++ = *text++;\n        }\n        else {\n            *field++ = pad;\n        }\n    }\n    return field;\n}\n\nsize_t\nlame_get_id3v1_tag(lame_t gfp, unsigned char *buffer, size_t size)\n{\n    size_t const tag_size = 128;\n    lame_internal_flags *gfc;\n\n    if (gfp == 0) {\n        return 0;\n    }\n    if (size < tag_size) {\n        return tag_size;\n    }\n    gfc = gfp->internal_flags;\n    if (gfc == 0) {\n        return 0;\n    }\n    if (buffer == 0) {\n        return 0;\n    }\n    if (test_tag_spec_flags(gfc, V2_ONLY_FLAG)) {\n        return 0;\n    }\n    if (test_tag_spec_flags(gfc, CHANGED_FLAG)) {\n        unsigned char *p = buffer;\n        int     pad = test_tag_spec_flags(gfc, SPACE_V1_FLAG) ? ' ' : 0;\n        char    year[5];\n\n        /* set tag identifier */\n        *p++ = 'T';\n        *p++ = 'A';\n        *p++ = 'G';\n        /* set each field in tag */\n        p = set_text_field(p, gfc->tag_spec.title, 30, pad);\n        p = set_text_field(p, gfc->tag_spec.artist, 30, pad);\n        p = set_text_field(p, gfc->tag_spec.album, 30, pad);\n        sprintf(year, \"%d\", gfc->tag_spec.year);\n        p = set_text_field(p, gfc->tag_spec.year ? year : NULL, 4, pad);\n        /* limit comment field to 28 bytes if a track is specified */\n        p = set_text_field(p, gfc->tag_spec.comment, gfc->tag_spec.track_id3v1 ? 28 : 30, pad);\n        if (gfc->tag_spec.track_id3v1) {\n            /* clear the next byte to indicate a version 1.1 tag */\n            *p++ = 0;\n            *p++ = gfc->tag_spec.track_id3v1;\n        }\n        *p++ = gfc->tag_spec.genre_id3v1;\n        return tag_size;\n    }\n    return 0;\n}\n\nint\nid3tag_write_v1(lame_t gfp)\n{\n    lame_internal_flags *const gfc = gfp->internal_flags;\n    size_t  i, n, m;\n    unsigned char tag[128];\n\n    m = sizeof(tag);\n    n = lame_get_id3v1_tag(gfp, tag, m);\n    if (n > m) {\n        return 0;\n    }\n    /* write tag directly into bitstream at current position */\n    for (i = 0; i < n; ++i) {\n        add_dummy_byte(gfc, tag[i], 1);\n    }\n    return (int) n;     /* ok, tag has fixed size of 128 bytes, well below 2GB */\n}\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/id3tag.h",
    "content": "\n#ifndef LAME_ID3_H\n#define LAME_ID3_H\n\n\n#define CHANGED_FLAG    (1U << 0)\n#define ADD_V2_FLAG     (1U << 1)\n#define V1_ONLY_FLAG    (1U << 2)\n#define V2_ONLY_FLAG    (1U << 3)\n#define SPACE_V1_FLAG   (1U << 4)\n#define PAD_V2_FLAG     (1U << 5)\n\nenum {\n    MIMETYPE_NONE = 0,\n    MIMETYPE_JPEG,\n    MIMETYPE_PNG,\n    MIMETYPE_GIF,\n};\n\ntypedef struct FrameDataNode {\n    struct FrameDataNode *nxt;\n    uint32_t fid;             /* Frame Identifier                 */\n    char    lng[4];          /* 3-character language descriptor  */\n    struct {\n        union {\n            char   *l;       /* ptr to Latin-1 chars             */\n            unsigned short *u; /* ptr to UCS-2 text                */\n            unsigned char *b; /* ptr to raw bytes                 */\n        } ptr;\n        size_t  dim;\n        int     enc;         /* 0:Latin-1, 1:UCS-2, 2:RAW        */\n    } dsc  , txt;\n} FrameDataNode;\n\n\ntypedef struct id3tag_spec {\n    /* private data members */\n    unsigned int flags;\n    int     year;\n    char   *title;\n    char   *artist;\n    char   *album;\n    char   *comment;\n    int     track_id3v1;\n    int     genre_id3v1;\n    unsigned char *albumart;\n    unsigned int albumart_size;\n    unsigned int padding_size;\n    int     albumart_mimetype;\n    FrameDataNode *v2_head, *v2_tail;\n} id3tag_spec;\n\n\n/* write tag into stream at current position */\nextern int id3tag_write_v2(lame_global_flags * gfp);\nextern int id3tag_write_v1(lame_global_flags * gfp);\n/*\n * NOTE: A version 2 tag will NOT be added unless one of the text fields won't\n * fit in a version 1 tag (e.g. the title string is longer than 30 characters),\n * or the \"id3tag_add_v2\" or \"id3tag_v2_only\" functions are used.\n */\n\n#endif\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/l3side.h",
    "content": "/*\n *\tLayer 3 side include file\n *\n *\tCopyright (c) 1999 Mark Taylor\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\t See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n#ifndef LAME_L3SIDE_H\n#define LAME_L3SIDE_H\n\n/* max scalefactor band, max(SBMAX_l, SBMAX_s*3, (SBMAX_s-3)*3+8) */\n#define SFBMAX (SBMAX_s*3)\n\n/* Layer III side information. */\ntypedef struct {\n    int     l[1 + SBMAX_l];\n    int     s[1 + SBMAX_s];\n    int     psfb21[1 + PSFB21];\n    int     psfb12[1 + PSFB12];\n} scalefac_struct;\n\n\ntypedef struct {\n    FLOAT   l[SBMAX_l];\n    FLOAT   s[SBMAX_s][3];\n} III_psy_xmin;\n\ntypedef struct {\n    III_psy_xmin thm;\n    III_psy_xmin en;\n} III_psy_ratio;\n\ntypedef struct {\n    FLOAT   xr[576];\n    int     l3_enc[576];\n    int     scalefac[SFBMAX];\n    FLOAT   xrpow_max;\n\n    int     part2_3_length;\n    int     big_values;\n    int     count1;\n    int     global_gain;\n    int     scalefac_compress;\n    int     block_type;\n    int     mixed_block_flag;\n    int     table_select[3];\n    int     subblock_gain[3 + 1];\n    int     region0_count;\n    int     region1_count;\n    int     preflag;\n    int     scalefac_scale;\n    int     count1table_select;\n\n    int     part2_length;\n    int     sfb_lmax;\n    int     sfb_smin;\n    int     psy_lmax;\n    int     sfbmax;\n    int     psymax;\n    int     sfbdivide;\n    int     width[SFBMAX];\n    int     window[SFBMAX];\n    int     count1bits;\n    /* added for LSF */\n    const int *sfb_partition_table;\n    int     slen[4];\n\n    int     max_nonzero_coeff;\n    char    energy_above_cutoff[SFBMAX];\n} gr_info;\n\ntypedef struct {\n    gr_info tt[2][2];\n    int     main_data_begin;\n    int     private_bits;\n    int     resvDrain_pre;\n    int     resvDrain_post;\n    int     scfsi[2][4];\n} III_side_info_t;\n\n#endif\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/lame-analysis.h",
    "content": "/*\n *      GTK plotting routines source file\n *\n *      Copyright (c) 1999 Mark Taylor\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n#ifndef LAME_GTKANAL_H\n#define LAME_GTKANAL_H\n\n\n#define READ_AHEAD 40   /* number of frames to read ahead */\n#define MAXMPGLAG READ_AHEAD /* if the mpg123 lag becomes bigger than this\n                                we have to stop */\n#define NUMBACK 6       /* number of frames we can back up */\n#define NUMPINFO (NUMBACK+READ_AHEAD+1)\n\n\n\nstruct plotting_data {\n    int     frameNum;        /* current frame number */\n    int     frameNum123;\n    int     num_samples;     /* number of pcm samples read for this frame */\n    double  frametime;       /* starting time of frame, in seconds */\n    double  pcmdata[2][1600];\n    double  pcmdata2[2][1152 + 1152 - DECDELAY];\n    double  xr[2][2][576];\n    double  mpg123xr[2][2][576];\n    double  ms_ratio[2];\n    double  ms_ener_ratio[2];\n\n    /* L,R, M and S values */\n    double  energy_save[4][BLKSIZE]; /* psymodel is one ahead */\n    double  energy[2][4][BLKSIZE];\n    double  pe[2][4];\n    double  thr[2][4][SBMAX_l];\n    double  en[2][4][SBMAX_l];\n    double  thr_s[2][4][3 * SBMAX_s];\n    double  en_s[2][4][3 * SBMAX_s];\n    double  ers_save[4];     /* psymodel is one ahead */\n    double  ers[2][4];\n\n    double  sfb[2][2][SBMAX_l];\n    double  sfb_s[2][2][3 * SBMAX_s];\n    double  LAMEsfb[2][2][SBMAX_l];\n    double  LAMEsfb_s[2][2][3 * SBMAX_s];\n\n    int     LAMEqss[2][2];\n    int     qss[2][2];\n    int     big_values[2][2];\n    int     sub_gain[2][2][3];\n\n    double  xfsf[2][2][SBMAX_l];\n    double  xfsf_s[2][2][3 * SBMAX_s];\n\n    int     over[2][2];\n    double  tot_noise[2][2];\n    double  max_noise[2][2];\n    double  over_noise[2][2];\n    int     over_SSD[2][2];\n    int     blocktype[2][2];\n    int     scalefac_scale[2][2];\n    int     preflag[2][2];\n    int     mpg123blocktype[2][2];\n    int     mixed[2][2];\n    int     mainbits[2][2];\n    int     sfbits[2][2];\n    int     LAMEmainbits[2][2];\n    int     LAMEsfbits[2][2];\n    int     framesize, stereo, js, ms_stereo, i_stereo, emph, bitrate, sampfreq, maindata;\n    int     crc, padding;\n    int     scfsi[2], mean_bits, resvsize;\n    int     totbits;\n};\n#ifndef plotting_data_defined\n#define plotting_data_defined\ntypedef struct plotting_data plotting_data;\n#endif\n#if 0\nextern plotting_data *pinfo;\n#endif\n#endif\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/lame.c",
    "content": "/* -*- mode: C; mode: fold -*- */\n/*\n *      LAME MP3 encoding engine\n *\n *      Copyright (c) 1999-2000 Mark Taylor\n *      Copyright (c) 2000-2005 Takehiro Tominaga\n *      Copyright (c) 2000-2011 Robert Hegemann\n *      Copyright (c) 2000-2005 Gabriel Bouvigne\n *      Copyright (c) 2000-2004 Alexander Leidinger\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n/* $Id: lame.c,v 1.365 2011/10/18 21:51:20 robert Exp $ */\n\n#ifdef HAVE_CONFIG_H\n# include <config.h>\n#endif\n\n\n#include \"lame.h\"\n#include \"machine.h\"\n\n#include \"encoder.h\"\n#include \"util.h\"\n#include \"lame_global_flags.h\"\n#include \"gain_analysis.h\"\n#include \"bitstream.h\"\n#include \"quantize_pvt.h\"\n#include \"set_get.h\"\n#include \"quantize.h\"\n#include \"psymodel.h\"\n#include \"version.h\"\n#include \"VbrTag.h\"\n#include \"tables.h\"\n\n\n#if defined(__FreeBSD__) && !defined(__alpha__)\n#include <floatingpoint.h>\n#endif\n#ifdef __riscos__\n#include \"asmstuff.h\"\n#endif\n\n#ifdef __sun__\n/* woraround for SunOS 4.x, it has SEEK_* defined here */\n#include <unistd.h>\n#endif\n\n\n#define LAME_DEFAULT_QUALITY 3\n\n\n\nint\nis_lame_global_flags_valid(const lame_global_flags * gfp)\n{\n    if (gfp == NULL)\n        return 0;\n    if (gfp->class_id != LAME_ID)\n        return 0;\n    return 1;\n}\n\n\nint\nis_lame_internal_flags_valid(const lame_internal_flags * gfc)\n{\n    if (gfc == NULL)\n        return 0;\n    if (gfc->class_id != LAME_ID)\n        return 0;\n    return 1;\n}\n\n\n\nstatic  FLOAT\nfilter_coef(FLOAT x)\n{\n    if (x > 1.0)\n        return 0.0;\n    if (x <= 0.0)\n        return 1.0;\n\n    return cos(PI / 2 * x);\n}\n\nstatic void\nlame_init_params_ppflt(lame_internal_flags * gfc)\n{\n    SessionConfig_t *const cfg = &gfc->cfg;\n    \n    /***************************************************************/\n    /* compute info needed for polyphase filter (filter type==0, default) */\n    /***************************************************************/\n\n    int     band, maxband, minband;\n    FLOAT   freq;\n    int     lowpass_band = 32;\n    int     highpass_band = -1;\n\n    if (cfg->lowpass1 > 0) {\n        minband = 999;\n        for (band = 0; band <= 31; band++) {\n            freq = band / 31.0;\n            /* this band and above will be zeroed: */\n            if (freq >= cfg->lowpass2) {\n                lowpass_band = Min(lowpass_band, band);\n            }\n            if (cfg->lowpass1 < freq && freq < cfg->lowpass2) {\n                minband = Min(minband, band);\n            }\n        }\n\n        /* compute the *actual* transition band implemented by\n         * the polyphase filter */\n        if (minband == 999) {\n            cfg->lowpass1 = (lowpass_band - .75) / 31.0;\n        }\n        else {\n            cfg->lowpass1 = (minband - .75) / 31.0;\n        }\n        cfg->lowpass2 = lowpass_band / 31.0;\n    }\n\n    /* make sure highpass filter is within 90% of what the effective\n     * highpass frequency will be */\n    if (cfg->highpass2 > 0) {\n        if (cfg->highpass2 < .9 * (.75 / 31.0)) {\n            cfg->highpass1 = 0;\n            cfg->highpass2 = 0;\n            MSGF(gfc, \"Warning: highpass filter disabled.  \" \"highpass frequency too small\\n\");\n        }\n    }\n\n    if (cfg->highpass2 > 0) {\n        maxband = -1;\n        for (band = 0; band <= 31; band++) {\n            freq = band / 31.0;\n            /* this band and below will be zereod */\n            if (freq <= cfg->highpass1) {\n                highpass_band = Max(highpass_band, band);\n            }\n            if (cfg->highpass1 < freq && freq < cfg->highpass2) {\n                maxband = Max(maxband, band);\n            }\n        }\n        /* compute the *actual* transition band implemented by\n         * the polyphase filter */\n        cfg->highpass1 = highpass_band / 31.0;\n        if (maxband == -1) {\n            cfg->highpass2 = (highpass_band + .75) / 31.0;\n        }\n        else {\n            cfg->highpass2 = (maxband + .75) / 31.0;\n        }\n    }\n\n    for (band = 0; band < 32; band++) {\n        FLOAT fc1, fc2;\n        freq = band / 31.0f;\n        if (cfg->highpass2 > cfg->highpass1) {\n            fc1 = filter_coef((cfg->highpass2 - freq) / (cfg->highpass2 - cfg->highpass1 + 1e-20));\n        }\n        else {\n            fc1 = 1.0f;\n        }\n        if (cfg->lowpass2 > cfg->lowpass1) {\n            fc2 = filter_coef((freq - cfg->lowpass1)  / (cfg->lowpass2 - cfg->lowpass1 + 1e-20));\n        }\n        else {\n            fc2 = 1.0f;\n        }\n        gfc->sv_enc.amp_filter[band] = fc1 * fc2;\n    }\n}\n\n\nstatic void\noptimum_bandwidth(double *const lowerlimit, double *const upperlimit, const unsigned bitrate)\n{\n/*\n *  Input:\n *      bitrate     total bitrate in kbps\n *\n *   Output:\n *      lowerlimit: best lowpass frequency limit for input filter in Hz\n *      upperlimit: best highpass frequency limit for input filter in Hz\n */\n    int     table_index;\n\n    typedef struct {\n        int     bitrate;     /* only indicative value */\n        int     lowpass;\n    } band_pass_t;\n\n    const band_pass_t freq_map[] = {\n        {8, 2000},\n        {16, 3700},\n        {24, 3900},\n        {32, 5500},\n        {40, 7000},\n        {48, 7500},\n        {56, 10000},\n        {64, 11000},\n        {80, 13500},\n        {96, 15100},\n        {112, 15600},\n        {128, 17000},\n        {160, 17500},\n        {192, 18600},\n        {224, 19400},\n        {256, 19700},\n        {320, 20500}\n    };\n\n\n    table_index = nearestBitrateFullIndex(bitrate);\n\n    (void) freq_map[table_index].bitrate;\n    *lowerlimit = freq_map[table_index].lowpass;\n\n\n/*\n *  Now we try to choose a good high pass filtering frequency.\n *  This value is currently not used.\n *    For fu < 16 kHz:  sqrt(fu*fl) = 560 Hz\n *    For fu = 18 kHz:  no high pass filtering\n *  This gives:\n *\n *   2 kHz => 160 Hz\n *   3 kHz => 107 Hz\n *   4 kHz =>  80 Hz\n *   8 kHz =>  40 Hz\n *  16 kHz =>  20 Hz\n *  17 kHz =>  10 Hz\n *  18 kHz =>   0 Hz\n *\n *  These are ad hoc values and these can be optimized if a high pass is available.\n */\n/*    if (f_low <= 16000)\n        f_high = 16000. * 20. / f_low;\n    else if (f_low <= 18000)\n        f_high = 180. - 0.01 * f_low;\n    else\n        f_high = 0.;*/\n\n    /*\n     *  When we sometimes have a good highpass filter, we can add the highpass\n     *  frequency to the lowpass frequency\n     */\n\n    /*if (upperlimit != NULL)\n     *upperlimit = f_high;*/\n    (void) upperlimit;\n}\n\n\nstatic int\noptimum_samplefreq(int lowpassfreq, int input_samplefreq)\n{\n/*\n * Rules:\n *  - if possible, sfb21 should NOT be used\n *\n */\n    int     suggested_samplefreq = 44100;\n\n    if (input_samplefreq >= 48000)\n        suggested_samplefreq = 48000;\n    else if (input_samplefreq >= 44100)\n        suggested_samplefreq = 44100;\n    else if (input_samplefreq >= 32000)\n        suggested_samplefreq = 32000;\n    else if (input_samplefreq >= 24000)\n        suggested_samplefreq = 24000;\n    else if (input_samplefreq >= 22050)\n        suggested_samplefreq = 22050;\n    else if (input_samplefreq >= 16000)\n        suggested_samplefreq = 16000;\n    else if (input_samplefreq >= 12000)\n        suggested_samplefreq = 12000;\n    else if (input_samplefreq >= 11025)\n        suggested_samplefreq = 11025;\n    else if (input_samplefreq >= 8000)\n        suggested_samplefreq = 8000;\n\n    if (lowpassfreq == -1)\n        return suggested_samplefreq;\n\n    if (lowpassfreq <= 15960)\n        suggested_samplefreq = 44100;\n    if (lowpassfreq <= 15250)\n        suggested_samplefreq = 32000;\n    if (lowpassfreq <= 11220)\n        suggested_samplefreq = 24000;\n    if (lowpassfreq <= 9970)\n        suggested_samplefreq = 22050;\n    if (lowpassfreq <= 7230)\n        suggested_samplefreq = 16000;\n    if (lowpassfreq <= 5420)\n        suggested_samplefreq = 12000;\n    if (lowpassfreq <= 4510)\n        suggested_samplefreq = 11025;\n    if (lowpassfreq <= 3970)\n        suggested_samplefreq = 8000;\n\n    if (input_samplefreq < suggested_samplefreq) {\n        /* choose a valid MPEG sample frequency above the input sample frequency\n           to avoid SFB21/12 bitrate bloat\n           rh 061115\n         */\n        if (input_samplefreq > 44100) {\n            return 48000;\n        }\n        if (input_samplefreq > 32000) {\n            return 44100;\n        }\n        if (input_samplefreq > 24000) {\n            return 32000;\n        }\n        if (input_samplefreq > 22050) {\n            return 24000;\n        }\n        if (input_samplefreq > 16000) {\n            return 22050;\n        }\n        if (input_samplefreq > 12000) {\n            return 16000;\n        }\n        if (input_samplefreq > 11025) {\n            return 12000;\n        }\n        if (input_samplefreq > 8000) {\n            return 11025;\n        }\n        return 8000;\n    }\n    return suggested_samplefreq;\n}\n\n\n\n\n\n/* set internal feature flags.  USER should not access these since\n * some combinations will produce strange results */\nstatic void\nlame_init_qval(lame_global_flags * gfp)\n{\n    lame_internal_flags *const gfc = gfp->internal_flags;\n    SessionConfig_t *const cfg = &gfc->cfg;\n\n    switch (gfp->quality) {\n    default:\n    case 9:            /* no psymodel, no noise shaping */\n        cfg->noise_shaping = 0;\n        cfg->noise_shaping_amp = 0;\n        cfg->noise_shaping_stop = 0;\n        cfg->use_best_huffman = 0;\n        cfg->full_outer_loop = 0;\n        break;\n\n    case 8:\n        gfp->quality = 7;\n        /*lint --fallthrough */\n    case 7:            /* use psymodel (for short block and m/s switching), but no noise shapping */\n        cfg->noise_shaping = 0;\n        cfg->noise_shaping_amp = 0;\n        cfg->noise_shaping_stop = 0;\n        cfg->use_best_huffman = 0;\n        cfg->full_outer_loop = 0;\n        if (gfp->VBR == vbr_mt || gfp->VBR == vbr_mtrh) {\n            cfg->full_outer_loop  = -1;\n        }\n        break;\n\n    case 6:\n        if (cfg->noise_shaping == 0)\n            cfg->noise_shaping = 1;\n        cfg->noise_shaping_amp = 0;\n        cfg->noise_shaping_stop = 0;\n        if (cfg->subblock_gain == -1)\n            cfg->subblock_gain = 1;\n        cfg->use_best_huffman = 0;\n        cfg->full_outer_loop = 0;\n        break;\n\n    case 5:\n        if (cfg->noise_shaping == 0)\n            cfg->noise_shaping = 1;\n        cfg->noise_shaping_amp = 0;\n        cfg->noise_shaping_stop = 0;\n        if (cfg->subblock_gain == -1)\n            cfg->subblock_gain = 1;\n        cfg->use_best_huffman = 0;\n        cfg->full_outer_loop = 0;\n        break;\n\n    case 4:\n        if (cfg->noise_shaping == 0)\n            cfg->noise_shaping = 1;\n        cfg->noise_shaping_amp = 0;\n        cfg->noise_shaping_stop = 0;\n        if (cfg->subblock_gain == -1)\n            cfg->subblock_gain = 1;\n        cfg->use_best_huffman = 1;\n        cfg->full_outer_loop = 0;\n        break;\n\n    case 3:\n        if (cfg->noise_shaping == 0)\n            cfg->noise_shaping = 1;\n        cfg->noise_shaping_amp = 1;\n        cfg->noise_shaping_stop = 1;\n        if (cfg->subblock_gain == -1)\n            cfg->subblock_gain = 1;\n        cfg->use_best_huffman = 1;\n        cfg->full_outer_loop = 0;\n        break;\n\n    case 2:\n        if (cfg->noise_shaping == 0)\n            cfg->noise_shaping = 1;\n        if (gfc->sv_qnt.substep_shaping == 0)\n            gfc->sv_qnt.substep_shaping = 2;\n        cfg->noise_shaping_amp = 1;\n        cfg->noise_shaping_stop = 1;\n        if (cfg->subblock_gain == -1)\n            cfg->subblock_gain = 1;\n        cfg->use_best_huffman = 1; /* inner loop */\n        cfg->full_outer_loop = 0;\n        break;\n\n    case 1:\n        if (cfg->noise_shaping == 0)\n            cfg->noise_shaping = 1;\n        if (gfc->sv_qnt.substep_shaping == 0)\n            gfc->sv_qnt.substep_shaping = 2;\n        cfg->noise_shaping_amp = 2;\n        cfg->noise_shaping_stop = 1;\n        if (cfg->subblock_gain == -1)\n            cfg->subblock_gain = 1;\n        cfg->use_best_huffman = 1;\n        cfg->full_outer_loop = 0;\n        break;\n\n    case 0:\n        if (cfg->noise_shaping == 0)\n            cfg->noise_shaping = 1;\n        if (gfc->sv_qnt.substep_shaping == 0)\n            gfc->sv_qnt.substep_shaping = 2;\n        cfg->noise_shaping_amp = 2;\n        cfg->noise_shaping_stop = 1;\n        if (cfg->subblock_gain == -1)\n            cfg->subblock_gain = 1;\n        cfg->use_best_huffman = 1; /*type 2 disabled because of it slowness,\n                                      in favor of full outer loop search */\n        cfg->full_outer_loop = 1;\n        break;\n    }\n\n}\n\n\n\nstatic double\nlinear_int(double a, double b, double m)\n{\n    return a + m * (b - a);\n}\n\n\n\n/********************************************************************\n *   initialize internal params based on data in gf\n *   (globalflags struct filled in by calling program)\n *\n *  OUTLINE:\n *\n * We first have some complex code to determine bitrate,\n * output samplerate and mode.  It is complicated by the fact\n * that we allow the user to set some or all of these parameters,\n * and need to determine best possible values for the rest of them:\n *\n *  1. set some CPU related flags\n *  2. check if we are mono->mono, stereo->mono or stereo->stereo\n *  3.  compute bitrate and output samplerate:\n *          user may have set compression ratio\n *          user may have set a bitrate\n *          user may have set a output samplerate\n *  4. set some options which depend on output samplerate\n *  5. compute the actual compression ratio\n *  6. set mode based on compression ratio\n *\n *  The remaining code is much simpler - it just sets options\n *  based on the mode & compression ratio:\n *\n *   set allow_diff_short based on mode\n *   select lowpass filter based on compression ratio & mode\n *   set the bitrate index, and min/max bitrates for VBR modes\n *   disable VBR tag if it is not appropriate\n *   initialize the bitstream\n *   initialize scalefac_band data\n *   set sideinfo_len (based on channels, CRC, out_samplerate)\n *   write an id3v2 tag into the bitstream\n *   write VBR tag into the bitstream\n *   set mpeg1/2 flag\n *   estimate the number of frames (based on a lot of data)\n *\n *   now we set more flags:\n *   nspsytune:\n *      see code\n *   VBR modes\n *      see code\n *   CBR/ABR\n *      see code\n *\n *  Finally, we set the algorithm flags based on the gfp->quality value\n *  lame_init_qval(gfp);\n *\n ********************************************************************/\nint\nlame_init_params(lame_global_flags * gfp)\n{\n\n    int     i;\n    int     j;\n    lame_internal_flags *const gfc = gfp->internal_flags;\n    SessionConfig_t *const cfg = &gfc->cfg;\n\n    gfc->class_id = 0;\n\n    cfg->enforce_min_bitrate = gfp->VBR_hard_min;\n    cfg->analysis = gfp->analysis;\n    if (cfg->analysis)\n        gfp->write_lame_tag = 0;\n\n    /* some file options not allowed if output is: not specified or stdout */\n    if (gfc->pinfo != NULL)\n        gfp->write_lame_tag = 0; /* disable Xing VBR tag */\n\n    /* report functions */\n    gfc->report_msg = gfp->report.msgf;\n    gfc->report_dbg = gfp->report.debugf;\n    gfc->report_err = gfp->report.errorf;\n\n    if (gfp->asm_optimizations.amd3dnow)\n        gfc->CPU_features.AMD_3DNow = has_3DNow();\n    else\n        gfc->CPU_features.AMD_3DNow = 0;\n\n    if (gfp->asm_optimizations.mmx)\n        gfc->CPU_features.MMX = has_MMX();\n    else\n        gfc->CPU_features.MMX = 0;\n\n    if (gfp->asm_optimizations.sse) {\n        gfc->CPU_features.SSE = has_SSE();\n        gfc->CPU_features.SSE2 = has_SSE2();\n    }\n    else {\n        gfc->CPU_features.SSE = 0;\n        gfc->CPU_features.SSE2 = 0;\n    }\n\n\n    if (NULL == gfc->ATH)\n        gfc->ATH = calloc(1, sizeof(ATH_t));\n\n    if (NULL == gfc->ATH)\n        return -2;      /* maybe error codes should be enumerated in lame.h ?? */\n\n    if (NULL == gfc->sv_rpg.rgdata)\n        gfc->sv_rpg.rgdata = calloc(1, sizeof(replaygain_t));\n    if (NULL == gfc->sv_rpg.rgdata) {\n        freegfc(gfc);\n        gfp->internal_flags = NULL;\n        return -2;\n    }\n\n    cfg->error_protection = gfp->error_protection;\n    cfg->copyright = gfp->copyright;\n    cfg->original = gfp->original;\n    cfg->extension = gfp->extension;\n    cfg->emphasis = gfp->emphasis;\n\n    cfg->channels_in = gfp->num_channels;\n    if (cfg->channels_in == 1)\n        gfp->mode = MONO;\n    cfg->channels_out = (gfp->mode == MONO) ? 1 : 2;\n    if (gfp->mode == MONO)\n        gfp->force_ms = 0; /* don't allow forced mid/side stereo for mono output */\n    cfg->force_ms = gfp->force_ms;\n\n    if (gfp->VBR == vbr_off && gfp->VBR_mean_bitrate_kbps != 128 && gfp->brate == 0)\n        gfp->brate = gfp->VBR_mean_bitrate_kbps;\n\n    switch (gfp->VBR) {\n    case vbr_off:\n    case vbr_mtrh:\n    case vbr_mt:\n        /* these modes can handle free format condition */\n        break;\n    default:\n        gfp->free_format = 0; /* mode can't be mixed with free format */\n        break;\n    }\n\n    cfg->free_format = gfp->free_format;\n\n    if (gfp->VBR == vbr_off && gfp->brate == 0) {\n        /* no bitrate or compression ratio specified, use 11.025 */\n        if (EQ(gfp->compression_ratio, 0))\n            gfp->compression_ratio = 11.025; /* rate to compress a CD down to exactly 128000 bps */\n    }\n\n    /* find bitrate if user specify a compression ratio */\n    if (gfp->VBR == vbr_off && gfp->compression_ratio > 0) {\n\n        if (gfp->samplerate_out == 0)\n            gfp->samplerate_out = map2MP3Frequency((int) (0.97 * gfp->samplerate_in)); /* round up with a margin of 3% */\n\n        /* choose a bitrate for the output samplerate which achieves\n         * specified compression ratio\n         */\n        gfp->brate = gfp->samplerate_out * 16 * cfg->channels_out / (1.e3 * gfp->compression_ratio);\n\n        /* we need the version for the bitrate table look up */\n        cfg->samplerate_index = SmpFrqIndex(gfp->samplerate_out, &cfg->version);\n\n        if (!cfg->free_format) /* for non Free Format find the nearest allowed bitrate */\n            gfp->brate = FindNearestBitrate(gfp->brate, cfg->version, gfp->samplerate_out);\n    }\n    if (gfp->samplerate_out) {\n        if (gfp->samplerate_out < 16000) {\n            gfp->VBR_mean_bitrate_kbps = Max(gfp->VBR_mean_bitrate_kbps, 8);\n            gfp->VBR_mean_bitrate_kbps = Min(gfp->VBR_mean_bitrate_kbps, 64);\n        }\n        else if (gfp->samplerate_out < 32000) {\n            gfp->VBR_mean_bitrate_kbps = Max(gfp->VBR_mean_bitrate_kbps, 8);\n            gfp->VBR_mean_bitrate_kbps = Min(gfp->VBR_mean_bitrate_kbps, 160);\n        }\n        else {\n            gfp->VBR_mean_bitrate_kbps = Max(gfp->VBR_mean_bitrate_kbps, 32);\n            gfp->VBR_mean_bitrate_kbps = Min(gfp->VBR_mean_bitrate_kbps, 320);\n        }\n    }\n    /* WORK IN PROGRESS */\n    /* mapping VBR scale to internal VBR quality settings */\n    if (gfp->samplerate_out == 0 && (gfp->VBR == vbr_mt || gfp->VBR == vbr_mtrh)) {\n        float const qval = gfp->VBR_q + gfp->VBR_q_frac;\n        struct q_map { int sr_a; float qa, qb, ta, tb; int lp; };\n        struct q_map const m[9]\n        = { {48000, 0.0,6.5,  0.0,6.5, 23700}\n          , {44100, 0.0,6.5,  0.0,6.5, 21780}\n          , {32000, 6.5,8.0,  5.2,6.5, 15800}\n          , {24000, 8.0,8.5,  5.2,6.0, 11850}\n          , {22050, 8.5,9.01, 5.2,6.5, 10892}\n          , {16000, 9.01,9.4, 4.9,6.5,  7903}\n          , {12000, 9.4,9.6,  4.5,6.0,  5928}\n          , {11025, 9.6,9.9,  5.1,6.5,  5446}\n          , { 8000, 9.9,10.,  4.9,6.5,  3952}\n        };\n        for (i = 2; i < 9; ++i) {\n            if (gfp->samplerate_in == m[i].sr_a) {\n                if (qval < m[i].qa) {\n                    double d = qval / m[i].qa;\n                    d = d * m[i].ta;\n                    gfp->VBR_q = (int)d;\n                    gfp->VBR_q_frac = d - gfp->VBR_q;\n                }\n            }\n            if (gfp->samplerate_in >= m[i].sr_a) {\n                if (m[i].qa <= qval && qval < m[i].qb) {\n                    float const q_ = m[i].qb-m[i].qa;\n                    float const t_ = m[i].tb-m[i].ta;\n                    double d = m[i].ta + t_ * (qval-m[i].qa) / q_;\n                    gfp->VBR_q = (int)d;\n                    gfp->VBR_q_frac = d - gfp->VBR_q;\n                    gfp->samplerate_out = m[i].sr_a;\n                    if (gfp->lowpassfreq == 0) {\n                        gfp->lowpassfreq = -1;\n                    }\n                    break;\n                }\n            }\n        }\n    }\n\n    /****************************************************************/\n    /* if a filter has not been enabled, see if we should add one: */\n    /****************************************************************/\n    if (gfp->lowpassfreq == 0) {\n        double  lowpass = 16000;\n        double  highpass;\n\n        switch (gfp->VBR) {\n        case vbr_off:{\n                optimum_bandwidth(&lowpass, &highpass, gfp->brate);\n                break;\n            }\n        case vbr_abr:{\n                optimum_bandwidth(&lowpass, &highpass, gfp->VBR_mean_bitrate_kbps);\n                break;\n            }\n        case vbr_rh:{\n                int const x[11] = {\n                    19500, 19000, 18600, 18000, 17500, 16000, 15600, 14900, 12500, 10000, 3950\n                };\n                if (0 <= gfp->VBR_q && gfp->VBR_q <= 9) {\n                    double  a = x[gfp->VBR_q], b = x[gfp->VBR_q + 1], m = gfp->VBR_q_frac;\n                    lowpass = linear_int(a, b, m);\n                }\n                else {\n                    lowpass = 19500;\n                }\n                break;\n            }\n        case vbr_mtrh:\n        case vbr_mt:{\n                int const x[11] = {\n                    24000, 19500, 18500, 18000, 17500, 17000, 16500, 15600, 15200, 7230, 3950\n                };\n                if (0 <= gfp->VBR_q && gfp->VBR_q <= 9) {\n                    double  a = x[gfp->VBR_q], b = x[gfp->VBR_q + 1], m = gfp->VBR_q_frac;\n                    lowpass = linear_int(a, b, m);\n                }\n                else {\n                    lowpass = 21500;\n                }\n                break;\n            }\n        default:{\n                int const x[11] = {\n                    19500, 19000, 18500, 18000, 17500, 16500, 15500, 14500, 12500, 9500, 3950\n                };\n                if (0 <= gfp->VBR_q && gfp->VBR_q <= 9) {\n                    double  a = x[gfp->VBR_q], b = x[gfp->VBR_q + 1], m = gfp->VBR_q_frac;\n                    lowpass = linear_int(a, b, m);\n                }\n                else {\n                    lowpass = 19500;\n                }\n            }\n        }\n\n        if (gfp->mode == MONO && (gfp->VBR == vbr_off || gfp->VBR == vbr_abr))\n            lowpass *= 1.5;\n\n        gfp->lowpassfreq = lowpass;\n    }\n\n    if (gfp->samplerate_out == 0) {\n        if (2 * gfp->lowpassfreq > gfp->samplerate_in) {\n            gfp->lowpassfreq = gfp->samplerate_in / 2;\n        }\n        gfp->samplerate_out = optimum_samplefreq((int) gfp->lowpassfreq, gfp->samplerate_in);\n    }\n    if (gfp->VBR == vbr_mt || gfp->VBR == vbr_mtrh) {\n        gfp->lowpassfreq = Min(24000, gfp->lowpassfreq);\n    }\n    else {\n        gfp->lowpassfreq = Min(20500, gfp->lowpassfreq);\n    }\n    gfp->lowpassfreq = Min(gfp->samplerate_out / 2, gfp->lowpassfreq);\n\n    if (gfp->VBR == vbr_off) {\n        gfp->compression_ratio = gfp->samplerate_out * 16 * cfg->channels_out / (1.e3 * gfp->brate);\n    }\n    if (gfp->VBR == vbr_abr) {\n        gfp->compression_ratio =\n            gfp->samplerate_out * 16 * cfg->channels_out / (1.e3 * gfp->VBR_mean_bitrate_kbps);\n    }\n\n    /* do not compute ReplayGain values and do not find the peak sample\n       if we can't store them */\n    if (!gfp->write_lame_tag) {\n        gfp->findReplayGain = 0;\n        gfp->decode_on_the_fly = 0;\n        cfg->findPeakSample = 0;\n    }\n\n    cfg->findReplayGain = gfp->findReplayGain;\n    cfg->decode_on_the_fly = gfp->decode_on_the_fly;\n\n    if (cfg->decode_on_the_fly)\n        cfg->findPeakSample = 1;\n\n    if (cfg->findReplayGain) {\n        if (InitGainAnalysis(gfc->sv_rpg.rgdata, gfp->samplerate_out) == INIT_GAIN_ANALYSIS_ERROR) {\n            freegfc(gfc);\n            gfp->internal_flags = NULL;\n            return -6;\n        }\n    }\n\n#ifdef DECODE_ON_THE_FLY\n    if (cfg->decode_on_the_fly && !gfp->decode_only) {\n        if (gfc->hip) {\n            hip_decode_exit(gfc->hip);\n        }\n        gfc->hip = hip_decode_init();\n        /* report functions */\n        hip_set_errorf(gfc->hip, gfp->report.errorf);\n        hip_set_debugf(gfc->hip, gfp->report.debugf);\n        hip_set_msgf(gfc->hip, gfp->report.msgf);\n    }\n#endif\n\n    cfg->disable_reservoir = gfp->disable_reservoir;\n    cfg->lowpassfreq = gfp->lowpassfreq;\n    cfg->highpassfreq = gfp->highpassfreq;\n    cfg->samplerate_in = gfp->samplerate_in;\n    cfg->samplerate_out = gfp->samplerate_out;\n    cfg->mode_gr = cfg->samplerate_out <= 24000 ? 1 : 2; /* Number of granules per frame */\n    gfc->ov_enc.encoder_delay = ENCDELAY;\n\n\n    /*\n     *  sample freq       bitrate     compression ratio\n     *     [kHz]      [kbps/channel]   for 16 bit input\n     *     44.1            56               12.6\n     *     44.1            64               11.025\n     *     44.1            80                8.82\n     *     22.05           24               14.7\n     *     22.05           32               11.025\n     *     22.05           40                8.82\n     *     16              16               16.0\n     *     16              24               10.667\n     *\n     */\n    /*\n     *  For VBR, take a guess at the compression_ratio.\n     *  For example:\n     *\n     *    VBR_q    compression     like\n     *     -        4.4         320 kbps/44 kHz\n     *   0...1      5.5         256 kbps/44 kHz\n     *     2        7.3         192 kbps/44 kHz\n     *     4        8.8         160 kbps/44 kHz\n     *     6       11           128 kbps/44 kHz\n     *     9       14.7          96 kbps\n     *\n     *  for lower bitrates, downsample with --resample\n     */\n\n    switch (gfp->VBR) {\n    case vbr_mt:\n    case vbr_rh:\n    case vbr_mtrh:\n        {\n            /*numbers are a bit strange, but they determine the lowpass value */\n            FLOAT const cmp[] = { 5.7, 6.5, 7.3, 8.2, 10, 11.9, 13, 14, 15, 16.5 };\n            gfp->compression_ratio = cmp[gfp->VBR_q];\n        }\n        break;\n    case vbr_abr:\n        gfp->compression_ratio =\n            cfg->samplerate_out * 16 * cfg->channels_out / (1.e3 * gfp->VBR_mean_bitrate_kbps);\n        break;\n    default:\n        gfp->compression_ratio = cfg->samplerate_out * 16 * cfg->channels_out / (1.e3 * gfp->brate);\n        break;\n    }\n\n\n    /* mode = -1 (not set by user) or\n     * mode = MONO (because of only 1 input channel).\n     * If mode has not been set, then select J-STEREO\n     */\n    if (gfp->mode == NOT_SET) {\n        gfp->mode = JOINT_STEREO;\n    }\n\n    cfg->mode = gfp->mode;\n\n\n    /* apply user driven high pass filter */\n    if (cfg->highpassfreq > 0) {\n        cfg->highpass1 = 2. * cfg->highpassfreq;\n\n        if (gfp->highpasswidth >= 0)\n            cfg->highpass2 = 2. * (cfg->highpassfreq + gfp->highpasswidth);\n        else            /* 0% above on default */\n            cfg->highpass2 = (1 + 0.00) * 2. * cfg->highpassfreq;\n\n        cfg->highpass1 /= cfg->samplerate_out;\n        cfg->highpass2 /= cfg->samplerate_out;\n    }\n    else {\n        cfg->highpass1 = 0;\n        cfg->highpass2 = 0;\n    }\n    /* apply user driven low pass filter */\n    cfg->lowpass1 = 0;\n    cfg->lowpass2 = 0;\n    if (cfg->lowpassfreq > 0 && cfg->lowpassfreq < (cfg->samplerate_out / 2) ) {\n        cfg->lowpass2 = 2. * cfg->lowpassfreq;\n        if (gfp->lowpasswidth >= 0) {\n            cfg->lowpass1 = 2. * (cfg->lowpassfreq - gfp->lowpasswidth);\n            if (cfg->lowpass1 < 0) /* has to be >= 0 */\n                cfg->lowpass1 = 0;\n        }\n        else {          /* 0% below on default */\n            cfg->lowpass1 = (1 - 0.00) * 2. * cfg->lowpassfreq;\n        }\n        cfg->lowpass1 /= cfg->samplerate_out;\n        cfg->lowpass2 /= cfg->samplerate_out;\n    }\n\n\n\n\n  /**********************************************************************/\n    /* compute info needed for polyphase filter (filter type==0, default) */\n  /**********************************************************************/\n    lame_init_params_ppflt(gfc);\n\n\n  /*******************************************************\n   * samplerate and bitrate index\n   *******************************************************/\n    cfg->samplerate_index = SmpFrqIndex(cfg->samplerate_out, &cfg->version);\n    if (cfg->samplerate_index < 0) {\n        freegfc(gfc);\n        gfp->internal_flags = NULL;\n        return -1;\n    }\n\n    if (gfp->VBR == vbr_off) {\n        if (cfg->free_format) {\n            gfc->ov_enc.bitrate_index = 0;\n        }\n        else {\n            gfp->brate = FindNearestBitrate(gfp->brate, cfg->version, cfg->samplerate_out);\n            gfc->ov_enc.bitrate_index = BitrateIndex(gfp->brate, cfg->version, cfg->samplerate_out);\n            if (gfc->ov_enc.bitrate_index <= 0) {\n                freegfc(gfc);\n                gfp->internal_flags = NULL;\n                return -1;\n            }\n        }\n    }\n    else {\n        gfc->ov_enc.bitrate_index = 1;\n    }\n\n    init_bit_stream_w(gfc);\n\n    j = cfg->samplerate_index + (3 * cfg->version) + 6 * (cfg->samplerate_out < 16000);\n    for (i = 0; i < SBMAX_l + 1; i++)\n        gfc->scalefac_band.l[i] = sfBandIndex[j].l[i];\n\n    for (i = 0; i < PSFB21 + 1; i++) {\n        int const size = (gfc->scalefac_band.l[22] - gfc->scalefac_band.l[21]) / PSFB21;\n        int const start = gfc->scalefac_band.l[21] + i * size;\n        gfc->scalefac_band.psfb21[i] = start;\n    }\n    gfc->scalefac_band.psfb21[PSFB21] = 576;\n\n    for (i = 0; i < SBMAX_s + 1; i++)\n        gfc->scalefac_band.s[i] = sfBandIndex[j].s[i];\n\n    for (i = 0; i < PSFB12 + 1; i++) {\n        int const size = (gfc->scalefac_band.s[13] - gfc->scalefac_band.s[12]) / PSFB12;\n        int const start = gfc->scalefac_band.s[12] + i * size;\n        gfc->scalefac_band.psfb12[i] = start;\n    }\n    gfc->scalefac_band.psfb12[PSFB12] = 192;\n\n    /* determine the mean bitrate for main data */\n    if (cfg->mode_gr == 2) /* MPEG 1 */\n        cfg->sideinfo_len = (cfg->channels_out == 1) ? 4 + 17 : 4 + 32;\n    else                /* MPEG 2 */\n        cfg->sideinfo_len = (cfg->channels_out == 1) ? 4 + 9 : 4 + 17;\n\n    if (cfg->error_protection)\n        cfg->sideinfo_len += 2;\n\n    gfc->class_id = LAME_ID;\n\n    {\n        int     k;\n\n        for (k = 0; k < 19; k++)\n            gfc->sv_enc.pefirbuf[k] = 700 * cfg->mode_gr * cfg->channels_out;\n\n        if (gfp->ATHtype == -1)\n            gfp->ATHtype = 4;\n    }\n\n    assert(gfp->VBR_q <= 9);\n    assert(gfp->VBR_q >= 0);\n\n    switch (gfp->VBR) {\n\n    case vbr_mt:\n    case vbr_mtrh:{\n            if (gfp->strict_ISO < 0) {\n                gfp->strict_ISO = MDB_MAXIMUM;\n            }\n            if (gfp->useTemporal < 0) {\n                gfp->useTemporal = 0; /* off by default for this VBR mode */\n            }\n\n            (void) apply_preset(gfp, 500 - (gfp->VBR_q * 10), 0);\n            /*  The newer VBR code supports only a limited\n               subset of quality levels:\n               9-5=5 are the same, uses x^3/4 quantization\n               4-0=0 are the same  5 plus best huffman divide code\n             */\n            if (gfp->quality < 0)\n                gfp->quality = LAME_DEFAULT_QUALITY;\n            if (gfp->quality < 5)\n                gfp->quality = 0;\n            if (gfp->quality > 7)\n                gfp->quality = 7;\n\n            /*  sfb21 extra only with MPEG-1 at higher sampling rates\n             */\n            if (gfp->experimentalY)\n                gfc->sv_qnt.sfb21_extra = 0;\n            else\n                gfc->sv_qnt.sfb21_extra = (cfg->samplerate_out > 44000);\n\n            gfc->iteration_loop = VBR_new_iteration_loop;\n            break;\n\n        }\n    case vbr_rh:{\n\n            (void) apply_preset(gfp, 500 - (gfp->VBR_q * 10), 0);\n\n            /*  sfb21 extra only with MPEG-1 at higher sampling rates\n             */\n            if (gfp->experimentalY)\n                gfc->sv_qnt.sfb21_extra = 0;\n            else\n                gfc->sv_qnt.sfb21_extra = (cfg->samplerate_out > 44000);\n\n            /*  VBR needs at least the output of GPSYCHO,\n             *  so we have to garantee that by setting a minimum\n             *  quality level, actually level 6 does it.\n             *  down to level 6\n             */\n            if (gfp->quality > 6)\n                gfp->quality = 6;\n\n\n            if (gfp->quality < 0)\n                gfp->quality = LAME_DEFAULT_QUALITY;\n\n            gfc->iteration_loop = VBR_old_iteration_loop;\n            break;\n        }\n\n    default:           /* cbr/abr */  {\n            vbr_mode vbrmode;\n\n            /*  no sfb21 extra with CBR code\n             */\n            gfc->sv_qnt.sfb21_extra = 0;\n\n            if (gfp->quality < 0)\n                gfp->quality = LAME_DEFAULT_QUALITY;\n\n\n            vbrmode = gfp->VBR;\n            if (vbrmode == vbr_off)\n                (void) lame_set_VBR_mean_bitrate_kbps(gfp, gfp->brate);\n            /* second, set parameters depending on bitrate */\n            (void) apply_preset(gfp, gfp->VBR_mean_bitrate_kbps, 0);\n            gfp->VBR = vbrmode;\n\n            if (vbrmode == vbr_off) {\n                gfc->iteration_loop = CBR_iteration_loop;\n            }\n            else {\n                gfc->iteration_loop = ABR_iteration_loop;\n            }\n            break;\n        }\n    }\n\n    /*initialize default values common for all modes */\n\n    gfc->sv_qnt.mask_adjust = gfp->maskingadjust;\n    gfc->sv_qnt.mask_adjust_short = gfp->maskingadjust_short;\n\n    /*  just another daily changing developer switch  */\n    if (gfp->tune) {\n        gfc->sv_qnt.mask_adjust += gfp->tune_value_a;\n        gfc->sv_qnt.mask_adjust_short += gfp->tune_value_a;\n    }\n\n\n    if (gfp->VBR != vbr_off) { /* choose a min/max bitrate for VBR */\n        /* if the user didn't specify VBR_max_bitrate: */\n        cfg->vbr_min_bitrate_index = 1; /* default: allow   8 kbps (MPEG-2) or  32 kbps (MPEG-1) */\n        cfg->vbr_max_bitrate_index = 14; /* default: allow 160 kbps (MPEG-2) or 320 kbps (MPEG-1) */\n        if (cfg->samplerate_out < 16000)\n            cfg->vbr_max_bitrate_index = 8; /* default: allow 64 kbps (MPEG-2.5) */\n        if (gfp->VBR_min_bitrate_kbps) {\n            gfp->VBR_min_bitrate_kbps =\n                FindNearestBitrate(gfp->VBR_min_bitrate_kbps, cfg->version, cfg->samplerate_out);\n            cfg->vbr_min_bitrate_index =\n                BitrateIndex(gfp->VBR_min_bitrate_kbps, cfg->version, cfg->samplerate_out);\n            if (cfg->vbr_min_bitrate_index < 0)\n                return -1;\n        }\n        if (gfp->VBR_max_bitrate_kbps) {\n            gfp->VBR_max_bitrate_kbps =\n                FindNearestBitrate(gfp->VBR_max_bitrate_kbps, cfg->version, cfg->samplerate_out);\n            cfg->vbr_max_bitrate_index =\n                BitrateIndex(gfp->VBR_max_bitrate_kbps, cfg->version, cfg->samplerate_out);\n            if (cfg->vbr_max_bitrate_index < 0)\n                return -1;\n        }\n        gfp->VBR_min_bitrate_kbps = bitrate_table[cfg->version][cfg->vbr_min_bitrate_index];\n        gfp->VBR_max_bitrate_kbps = bitrate_table[cfg->version][cfg->vbr_max_bitrate_index];\n        gfp->VBR_mean_bitrate_kbps =\n            Min(bitrate_table[cfg->version][cfg->vbr_max_bitrate_index],\n                gfp->VBR_mean_bitrate_kbps);\n        gfp->VBR_mean_bitrate_kbps =\n            Max(bitrate_table[cfg->version][cfg->vbr_min_bitrate_index],\n                gfp->VBR_mean_bitrate_kbps);\n    }\n\n    cfg->preset = gfp->preset;\n    cfg->write_lame_tag = gfp->write_lame_tag;\n    cfg->vbr = gfp->VBR;\n    gfc->sv_qnt.substep_shaping = gfp->substep_shaping;\n    cfg->noise_shaping = gfp->noise_shaping;\n    cfg->subblock_gain = gfp->subblock_gain;\n    cfg->use_best_huffman = gfp->use_best_huffman;\n    cfg->avg_bitrate = gfp->brate;\n    cfg->vbr_avg_bitrate_kbps = gfp->VBR_mean_bitrate_kbps;\n    cfg->compression_ratio = gfp->compression_ratio;\n\n    /* initialize internal qval settings */\n    lame_init_qval(gfp);\n\n\n    /*  automatic ATH adjustment on\n     */\n    if (gfp->athaa_type < 0)\n        gfc->ATH->use_adjust = 3;\n    else\n        gfc->ATH->use_adjust = gfp->athaa_type;\n\n\n    /* initialize internal adaptive ATH settings  -jd */\n    gfc->ATH->aa_sensitivity_p = pow(10.0, gfp->athaa_sensitivity / -10.0);\n\n\n    if (gfp->short_blocks == short_block_not_set) {\n        gfp->short_blocks = short_block_allowed;\n    }\n\n    /*Note Jan/2003: Many hardware decoders cannot handle short blocks in regular\n       stereo mode unless they are coupled (same type in both channels)\n       it is a rare event (1 frame per min. or so) that LAME would use\n       uncoupled short blocks, so lets turn them off until we decide\n       how to handle this.  No other encoders allow uncoupled short blocks,\n       even though it is in the standard.  */\n    /* rh 20040217: coupling makes no sense for mono and dual-mono streams\n     */\n    if (gfp->short_blocks == short_block_allowed\n        && (cfg->mode == JOINT_STEREO || cfg->mode == STEREO)) {\n        gfp->short_blocks = short_block_coupled;\n    }\n\n    cfg->short_blocks = gfp->short_blocks;\n\n\n    if (lame_get_quant_comp(gfp) < 0)\n        (void) lame_set_quant_comp(gfp, 1);\n    if (lame_get_quant_comp_short(gfp) < 0)\n        (void) lame_set_quant_comp_short(gfp, 0);\n\n    if (lame_get_msfix(gfp) < 0)\n        lame_set_msfix(gfp, 0);\n\n    /* select psychoacoustic model */\n    (void) lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 1);\n\n    if (gfp->ATHtype < 0)\n        gfp->ATHtype = 4;\n\n    if (gfp->ATHcurve < 0)\n        gfp->ATHcurve = 4;\n\n    if (gfp->interChRatio < 0)\n        gfp->interChRatio = 0;\n\n    if (gfp->useTemporal < 0)\n        gfp->useTemporal = 1; /* on by default */\n\n\n    cfg->interChRatio = gfp->interChRatio;\n    cfg->msfix = gfp->msfix;\n    cfg->ATH_offset_db = 0-gfp->ATH_lower_db;\n    cfg->ATH_offset_factor = powf(10.f, cfg->ATH_offset_db * 0.1f);\n    cfg->ATHcurve = gfp->ATHcurve;\n    cfg->ATHtype = gfp->ATHtype;\n    cfg->ATHonly = gfp->ATHonly;\n    cfg->ATHshort = gfp->ATHshort;\n    cfg->noATH = gfp->noATH;\n\n    cfg->quant_comp = gfp->quant_comp;\n    cfg->quant_comp_short = gfp->quant_comp_short;\n\n    cfg->use_temporal_masking_effect = gfp->useTemporal;\n    cfg->use_safe_joint_stereo = gfp->exp_nspsytune & 2;\n    {\n        cfg->adjust_bass_db = (gfp->exp_nspsytune >> 2) & 63;\n        if (cfg->adjust_bass_db >= 32.f)\n            cfg->adjust_bass_db -= 64.f;\n        cfg->adjust_bass_db *= 0.25f;\n\n        cfg->adjust_alto_db = (gfp->exp_nspsytune >> 8) & 63;\n        if (cfg->adjust_alto_db >= 32.f)\n            cfg->adjust_alto_db -= 64.f;\n        cfg->adjust_alto_db *= 0.25f;\n\n        cfg->adjust_treble_db = (gfp->exp_nspsytune >> 14) & 63;\n        if (cfg->adjust_treble_db >= 32.f)\n            cfg->adjust_treble_db -= 64.f;\n        cfg->adjust_treble_db *= 0.25f;\n\n        /*  to be compatible with Naoki's original code, the next 6 bits\n         *  define only the amount of changing treble for sfb21 */\n        cfg->adjust_sfb21_db = (gfp->exp_nspsytune >> 20) & 63;\n        if (cfg->adjust_sfb21_db >= 32.f)\n            cfg->adjust_sfb21_db -= 64.f;\n        cfg->adjust_sfb21_db *= 0.25f;\n        cfg->adjust_sfb21_db += cfg->adjust_treble_db;\n    }\n\n    /* Setting up the PCM input data transform matrix, to apply \n     * user defined re-scaling, and or two-to-one channel downmix.\n     */\n    {\n        FLOAT   m[2][2] = { {1.0f, 0.0f}, {0.0f, 1.0f} };\n\n        /* user selected scaling of the samples */\n        m[0][0] *= gfp->scale;\n        m[0][1] *= gfp->scale;\n        m[1][0] *= gfp->scale;\n        m[1][1] *= gfp->scale;\n        /* user selected scaling of the channel 0 (left) samples */\n        m[0][0] *= gfp->scale_left;\n        m[0][1] *= gfp->scale_left;\n        /* user selected scaling of the channel 1 (right) samples */\n        m[1][0] *= gfp->scale_right;\n        m[1][1] *= gfp->scale_right;\n        /* Downsample to Mono if 2 channels in and 1 channel out */\n        if (cfg->channels_in == 2 && cfg->channels_out == 1) {\n            m[0][0] = 0.5f * (m[0][0] + m[1][0]);\n            m[0][1] = 0.5f * (m[0][1] + m[1][1]);\n            m[1][0] = 0;\n            m[1][1] = 0;\n        }\n        cfg->pcm_transform[0][0] = m[0][0];\n        cfg->pcm_transform[0][1] = m[0][1];\n        cfg->pcm_transform[1][0] = m[1][0];\n        cfg->pcm_transform[1][1] = m[1][1];\n    }\n\n    /* padding method as described in\n     * \"MPEG-Layer3 / Bitstream Syntax and Decoding\"\n     * by Martin Sieler, Ralph Sperschneider\n     *\n     * note: there is no padding for the very first frame\n     *\n     * Robert Hegemann 2000-06-22\n     */\n    gfc->sv_enc.slot_lag = gfc->sv_enc.frac_SpF = 0;\n    if (cfg->vbr == vbr_off)\n        gfc->sv_enc.slot_lag = gfc->sv_enc.frac_SpF\n            = ((cfg->version + 1) * 72000L * cfg->avg_bitrate) % cfg->samplerate_out;\n\n    (void) lame_init_bitstream(gfp);\n\n    iteration_init(gfc);\n    (void) psymodel_init(gfp);\n\n    cfg->buffer_constraint = get_max_frame_buffer_size_by_constraint(cfg, gfp->strict_ISO);\n    return 0;\n}\n\nstatic void\nconcatSep(char* dest, char const* sep, char const* str)\n{\n    if (*dest != 0) strcat(dest, sep);\n    strcat(dest, str);\n}\n\n/*\n *  print_config\n *\n *  Prints some selected information about the coding parameters via\n *  the macro command MSGF(), which is currently mapped to lame_errorf\n *  (reports via a error function?), which is a printf-like function\n *  for <stderr>.\n */\n\nvoid\nlame_print_config(const lame_global_flags * gfp)\n{\n    lame_internal_flags const *const gfc = gfp->internal_flags;\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    double const out_samplerate = cfg->samplerate_out;\n    double const in_samplerate = cfg->samplerate_in;\n\n    MSGF(gfc, \"LAME %s %s (%s)\\n\", get_lame_version(), get_lame_os_bitness(), get_lame_url());\n\n#if (LAME_ALPHA_VERSION)\n    MSGF(gfc, \"warning: alpha versions should be used for testing only\\n\");\n#endif\n    if (gfc->CPU_features.MMX\n        || gfc->CPU_features.AMD_3DNow || gfc->CPU_features.SSE || gfc->CPU_features.SSE2) {\n        char    text[256] = { 0 };\n        int     fft_asm_used = 0;\n#ifdef HAVE_NASM\n        if (gfc->CPU_features.AMD_3DNow) {\n            fft_asm_used = 1;\n        }\n        else if (gfc->CPU_features.SSE) {\n            fft_asm_used = 2;\n        }\n#else\n# if defined( HAVE_XMMINTRIN_H ) && defined( MIN_ARCH_SSE )\n        {\n            fft_asm_used = 3;\n        }\n# endif\n#endif\n        if (gfc->CPU_features.MMX) {\n#ifdef MMX_choose_table\n            concatSep(text, \", \", \"MMX (ASM used)\");\n#else\n            concatSep(text, \", \", \"MMX\");\n#endif\n        }\n        if (gfc->CPU_features.AMD_3DNow) {\n            concatSep(text, \", \", (fft_asm_used == 1) ? \"3DNow! (ASM used)\" : \"3DNow!\");\n        }\n        if (gfc->CPU_features.SSE) {\n#if defined(HAVE_XMMINTRIN_H)\n            concatSep(text, \", \", \"SSE (ASM used)\");\n#else\n            concatSep(text, \", \", (fft_asm_used == 2) ? \"SSE (ASM used)\" : \"SSE\");\n#endif\n        }\n        if (gfc->CPU_features.SSE2) {\n            concatSep(text, \", \", (fft_asm_used == 3) ? \"SSE2 (ASM used)\" : \"SSE2\");\n        }\n        MSGF(gfc, \"CPU features: %s\\n\", text);\n    }\n\n    if (cfg->channels_in == 2 && cfg->channels_out == 1 /* mono */ ) {\n        MSGF(gfc, \"Autoconverting from stereo to mono. Setting encoding to mono mode.\\n\");\n    }\n\n    if (isResamplingNecessary(cfg)) {\n        MSGF(gfc, \"Resampling:  input %g kHz  output %g kHz\\n\",\n             1.e-3 * in_samplerate, 1.e-3 * out_samplerate);\n    }\n\n    if (cfg->highpass2 > 0.)\n        MSGF(gfc,\n             \"Using polyphase highpass filter, transition band: %5.0f Hz - %5.0f Hz\\n\",\n             0.5 * cfg->highpass1 * out_samplerate, 0.5 * cfg->highpass2 * out_samplerate);\n    if (0. < cfg->lowpass1 || 0. < cfg->lowpass2) {\n        MSGF(gfc,\n             \"Using polyphase lowpass filter, transition band: %5.0f Hz - %5.0f Hz\\n\",\n             0.5 * cfg->lowpass1 * out_samplerate, 0.5 * cfg->lowpass2 * out_samplerate);\n    }\n    else {\n        MSGF(gfc, \"polyphase lowpass filter disabled\\n\");\n    }\n\n    if (cfg->free_format) {\n        MSGF(gfc, \"Warning: many decoders cannot handle free format bitstreams\\n\");\n        if (cfg->avg_bitrate > 320) {\n            MSGF(gfc,\n                 \"Warning: many decoders cannot handle free format bitrates >320 kbps (see documentation)\\n\");\n        }\n    }\n}\n\n\n/**     rh:\n *      some pretty printing is very welcome at this point!\n *      so, if someone is willing to do so, please do it!\n *      add more, if you see more...\n */\nvoid\nlame_print_internals(const lame_global_flags * gfp)\n{\n    lame_internal_flags const *const gfc = gfp->internal_flags;\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    const char *pc = \"\";\n\n    /*  compiler/processor optimizations, operational, etc.\n     */\n    MSGF(gfc, \"\\nmisc:\\n\\n\");\n\n    MSGF(gfc, \"\\tscaling: %g\\n\", gfp->scale);\n    MSGF(gfc, \"\\tch0 (left) scaling: %g\\n\", gfp->scale_left);\n    MSGF(gfc, \"\\tch1 (right) scaling: %g\\n\", gfp->scale_right);\n    switch (cfg->use_best_huffman) {\n    default:\n        pc = \"normal\";\n        break;\n    case 1:\n        pc = \"best (outside loop)\";\n        break;\n    case 2:\n        pc = \"best (inside loop, slow)\";\n        break;\n    }\n    MSGF(gfc, \"\\thuffman search: %s\\n\", pc);\n    MSGF(gfc, \"\\texperimental Y=%d\\n\", gfp->experimentalY);\n    MSGF(gfc, \"\\t...\\n\");\n\n    /*  everything controlling the stream format\n     */\n    MSGF(gfc, \"\\nstream format:\\n\\n\");\n    switch (cfg->version) {\n    case 0:\n        pc = \"2.5\";\n        break;\n    case 1:\n        pc = \"1\";\n        break;\n    case 2:\n        pc = \"2\";\n        break;\n    default:\n        pc = \"?\";\n        break;\n    }\n    MSGF(gfc, \"\\tMPEG-%s Layer 3\\n\", pc);\n    switch (cfg->mode) {\n    case JOINT_STEREO:\n        pc = \"joint stereo\";\n        break;\n    case STEREO:\n        pc = \"stereo\";\n        break;\n    case DUAL_CHANNEL:\n        pc = \"dual channel\";\n        break;\n    case MONO:\n        pc = \"mono\";\n        break;\n    case NOT_SET:\n        pc = \"not set (error)\";\n        break;\n    default:\n        pc = \"unknown (error)\";\n        break;\n    }\n    MSGF(gfc, \"\\t%d channel - %s\\n\", cfg->channels_out, pc);\n\n    switch (cfg->vbr) {\n    case vbr_off:\n        pc = \"off\";\n        break;\n    default:\n        pc = \"all\";\n        break;\n    }\n    MSGF(gfc, \"\\tpadding: %s\\n\", pc);\n\n    if (vbr_default == cfg->vbr)\n        pc = \"(default)\";\n    else if (cfg->free_format)\n        pc = \"(free format)\";\n    else\n        pc = \"\";\n    switch (cfg->vbr) {\n    case vbr_off:\n        MSGF(gfc, \"\\tconstant bitrate - CBR %s\\n\", pc);\n        break;\n    case vbr_abr:\n        MSGF(gfc, \"\\tvariable bitrate - ABR %s\\n\", pc);\n        break;\n    case vbr_rh:\n        MSGF(gfc, \"\\tvariable bitrate - VBR rh %s\\n\", pc);\n        break;\n    case vbr_mt:\n        MSGF(gfc, \"\\tvariable bitrate - VBR mt %s\\n\", pc);\n        break;\n    case vbr_mtrh:\n        MSGF(gfc, \"\\tvariable bitrate - VBR mtrh %s\\n\", pc);\n        break;\n    default:\n        MSGF(gfc, \"\\t ?? oops, some new one ?? \\n\");\n        break;\n    }\n    if (cfg->write_lame_tag)\n        MSGF(gfc, \"\\tusing LAME Tag\\n\");\n    MSGF(gfc, \"\\t...\\n\");\n\n    /*  everything controlling psychoacoustic settings, like ATH, etc.\n     */\n    MSGF(gfc, \"\\npsychoacoustic:\\n\\n\");\n\n    switch (cfg->short_blocks) {\n    default:\n    case short_block_not_set:\n        pc = \"?\";\n        break;\n    case short_block_allowed:\n        pc = \"allowed\";\n        break;\n    case short_block_coupled:\n        pc = \"channel coupled\";\n        break;\n    case short_block_dispensed:\n        pc = \"dispensed\";\n        break;\n    case short_block_forced:\n        pc = \"forced\";\n        break;\n    }\n    MSGF(gfc, \"\\tusing short blocks: %s\\n\", pc);\n    MSGF(gfc, \"\\tsubblock gain: %d\\n\", cfg->subblock_gain);\n    MSGF(gfc, \"\\tadjust masking: %g dB\\n\", gfc->sv_qnt.mask_adjust);\n    MSGF(gfc, \"\\tadjust masking short: %g dB\\n\", gfc->sv_qnt.mask_adjust_short);\n    MSGF(gfc, \"\\tquantization comparison: %d\\n\", cfg->quant_comp);\n    MSGF(gfc, \"\\t ^ comparison short blocks: %d\\n\", cfg->quant_comp_short);\n    MSGF(gfc, \"\\tnoise shaping: %d\\n\", cfg->noise_shaping);\n    MSGF(gfc, \"\\t ^ amplification: %d\\n\", cfg->noise_shaping_amp);\n    MSGF(gfc, \"\\t ^ stopping: %d\\n\", cfg->noise_shaping_stop);\n\n    pc = \"using\";\n    if (cfg->ATHshort)\n        pc = \"the only masking for short blocks\";\n    if (cfg->ATHonly)\n        pc = \"the only masking\";\n    if (cfg->noATH)\n        pc = \"not used\";\n    MSGF(gfc, \"\\tATH: %s\\n\", pc);\n    MSGF(gfc, \"\\t ^ type: %d\\n\", cfg->ATHtype);\n    MSGF(gfc, \"\\t ^ shape: %g%s\\n\", cfg->ATHcurve, \" (only for type 4)\");\n    MSGF(gfc, \"\\t ^ level adjustement: %g dB\\n\", cfg->ATH_offset_db);\n    MSGF(gfc, \"\\t ^ adjust type: %d\\n\", gfc->ATH->use_adjust);\n    MSGF(gfc, \"\\t ^ adjust sensitivity power: %f\\n\", gfc->ATH->aa_sensitivity_p);\n\n    MSGF(gfc, \"\\texperimental psy tunings by Naoki Shibata\\n\");\n    MSGF(gfc, \"\\t   adjust masking bass=%g dB, alto=%g dB, treble=%g dB, sfb21=%g dB\\n\",\n         10 * log10(gfc->sv_qnt.longfact[0]),\n         10 * log10(gfc->sv_qnt.longfact[7]),\n         10 * log10(gfc->sv_qnt.longfact[14]), 10 * log10(gfc->sv_qnt.longfact[21]));\n\n    pc = cfg->use_temporal_masking_effect ? \"yes\" : \"no\";\n    MSGF(gfc, \"\\tusing temporal masking effect: %s\\n\", pc);\n    MSGF(gfc, \"\\tinterchannel masking ratio: %g\\n\", cfg->interChRatio);\n    MSGF(gfc, \"\\t...\\n\");\n\n    /*  that's all ?\n     */\n    MSGF(gfc, \"\\n\");\n    return;\n}\n\n\nstatic void\nsave_gain_values(lame_internal_flags * gfc)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    RpgStateVar_t const *const rsv = &gfc->sv_rpg;\n    RpgResult_t *const rov = &gfc->ov_rpg;\n    /* save the ReplayGain value */\n    if (cfg->findReplayGain) {\n        FLOAT const RadioGain = (FLOAT) GetTitleGain(rsv->rgdata);\n        if (NEQ(RadioGain, GAIN_NOT_ENOUGH_SAMPLES)) {\n            rov->RadioGain = (int) floor(RadioGain * 10.0 + 0.5); /* round to nearest */\n        }\n        else {\n            rov->RadioGain = 0;\n        }\n    }\n\n    /* find the gain and scale change required for no clipping */\n    if (cfg->findPeakSample) {\n        rov->noclipGainChange = (int) ceil(log10(rov->PeakSample / 32767.0) * 20.0 * 10.0); /* round up */\n\n        if (rov->noclipGainChange > 0) { /* clipping occurs */\n            rov->noclipScale = floor((32767.0f / rov->PeakSample) * 100.0f) / 100.0f; /* round down */\n        }\n        else            /* no clipping */\n            rov->noclipScale = -1.0f;\n    }\n}\n\n\n\nstatic int\nupdate_inbuffer_size(lame_internal_flags * gfc, const int nsamples)\n{\n    EncStateVar_t *const esv = &gfc->sv_enc;\n    if (esv->in_buffer_0 == 0 || esv->in_buffer_nsamples < nsamples) {\n        if (esv->in_buffer_0) {\n            free(esv->in_buffer_0);\n        }\n        if (esv->in_buffer_1) {\n            free(esv->in_buffer_1);\n        }\n        esv->in_buffer_0 = calloc(nsamples, sizeof(sample_t));\n        esv->in_buffer_1 = calloc(nsamples, sizeof(sample_t));\n        esv->in_buffer_nsamples = nsamples;\n    }\n    if (esv->in_buffer_0 == NULL || esv->in_buffer_1 == NULL) {\n        if (esv->in_buffer_0) {\n            free(esv->in_buffer_0);\n        }\n        if (esv->in_buffer_1) {\n            free(esv->in_buffer_1);\n        }\n        esv->in_buffer_0 = 0;\n        esv->in_buffer_1 = 0;\n        esv->in_buffer_nsamples = 0;\n        ERRORF(gfc, \"Error: can't allocate in_buffer buffer\\n\");\n        return -2;\n    }\n    return 0;\n}\n\n\nstatic int\ncalcNeeded(SessionConfig_t const * cfg)\n{\n    int     mf_needed;\n    int     pcm_samples_per_frame = 576 * cfg->mode_gr;\n\n    /* some sanity checks */\n#if ENCDELAY < MDCTDELAY\n# error ENCDELAY is less than MDCTDELAY, see encoder.h\n#endif\n#if FFTOFFSET > BLKSIZE\n# error FFTOFFSET is greater than BLKSIZE, see encoder.h\n#endif\n\n    mf_needed = BLKSIZE + pcm_samples_per_frame - FFTOFFSET; /* amount needed for FFT */\n    /*mf_needed = Max(mf_needed, 286 + 576 * (1 + gfc->mode_gr)); */\n    mf_needed = Max(mf_needed, 512 + pcm_samples_per_frame - 32);\n\n    assert(MFSIZE >= mf_needed);\n    \n    return mf_needed;\n}\n\n\n/*\n * THE MAIN LAME ENCODING INTERFACE\n * mt 3/00\n *\n * input pcm data, output (maybe) mp3 frames.\n * This routine handles all buffering, resampling and filtering for you.\n * The required mp3buffer_size can be computed from num_samples,\n * samplerate and encoding rate, but here is a worst case estimate:\n *\n * mp3buffer_size in bytes = 1.25*num_samples + 7200\n *\n * return code = number of bytes output in mp3buffer.  can be 0\n *\n * NOTE: this routine uses LAME's internal PCM data representation,\n * 'sample_t'.  It should not be used by any application.\n * applications should use lame_encode_buffer(),\n *                         lame_encode_buffer_float()\n *                         lame_encode_buffer_int()\n * etc... depending on what type of data they are working with.\n*/\nstatic int\nlame_encode_buffer_sample_t(lame_internal_flags * gfc,\n                            int nsamples, unsigned char *mp3buf, const int mp3buf_size)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    EncStateVar_t *const esv = &gfc->sv_enc;\n    int     pcm_samples_per_frame = 576 * cfg->mode_gr;\n    int     mp3size = 0, ret, i, ch, mf_needed;\n    int     mp3out;\n    sample_t *mfbuf[2];\n    sample_t *in_buffer[2];\n\n    if (gfc->class_id != LAME_ID)\n        return -3;\n\n    if (nsamples == 0)\n        return 0;\n\n    /* copy out any tags that may have been written into bitstream */\n    mp3out = copy_buffer(gfc, mp3buf, mp3buf_size, 0);\n    if (mp3out < 0)\n        return mp3out;  /* not enough buffer space */\n    mp3buf += mp3out;\n    mp3size += mp3out;\n\n    in_buffer[0] = esv->in_buffer_0;\n    in_buffer[1] = esv->in_buffer_1;\n\n    mf_needed = calcNeeded(cfg);\n\n    mfbuf[0] = esv->mfbuf[0];\n    mfbuf[1] = esv->mfbuf[1];\n\n    while (nsamples > 0) {\n        sample_t const *in_buffer_ptr[2];\n        int     n_in = 0;    /* number of input samples processed with fill_buffer */\n        int     n_out = 0;   /* number of samples output with fill_buffer */\n        /* n_in <> n_out if we are resampling */\n\n        in_buffer_ptr[0] = in_buffer[0];\n        in_buffer_ptr[1] = in_buffer[1];\n        /* copy in new samples into mfbuf, with resampling */\n        fill_buffer(gfc, mfbuf, &in_buffer_ptr[0], nsamples, &n_in, &n_out);\n\n        /* compute ReplayGain of resampled input if requested */\n        if (cfg->findReplayGain && !cfg->decode_on_the_fly)\n            if (AnalyzeSamples\n                (gfc->sv_rpg.rgdata, &mfbuf[0][esv->mf_size], &mfbuf[1][esv->mf_size], n_out,\n                 cfg->channels_out) == GAIN_ANALYSIS_ERROR)\n                return -6;\n\n\n\n        /* update in_buffer counters */\n        nsamples -= n_in;\n        in_buffer[0] += n_in;\n        if (cfg->channels_out == 2)\n            in_buffer[1] += n_in;\n\n        /* update mfbuf[] counters */\n        esv->mf_size += n_out;\n        assert(esv->mf_size <= MFSIZE);\n        \n        /* lame_encode_flush may have set gfc->mf_sample_to_encode to 0\n         * so we have to reinitialize it here when that happened.\n         */\n        if (esv->mf_samples_to_encode < 1) {\n            esv->mf_samples_to_encode = ENCDELAY + POSTDELAY;\n        }        \n        esv->mf_samples_to_encode += n_out;\n\n\n        if (esv->mf_size >= mf_needed) {\n            /* encode the frame.  */\n            /* mp3buf              = pointer to current location in buffer */\n            /* mp3buf_size         = size of original mp3 output buffer */\n            /*                     = 0 if we should not worry about the */\n            /*                       buffer size because calling program is  */\n            /*                       to lazy to compute it */\n            /* mp3size             = size of data written to buffer so far */\n            /* mp3buf_size-mp3size = amount of space avalable  */\n\n            int     buf_size = mp3buf_size - mp3size;\n            if (mp3buf_size == 0)\n                buf_size = 0;\n\n            ret = lame_encode_mp3_frame(gfc, mfbuf[0], mfbuf[1], mp3buf, buf_size);\n\n            if (ret < 0)\n                return ret;\n            mp3buf += ret;\n            mp3size += ret;\n\n            /* shift out old samples */\n            esv->mf_size -= pcm_samples_per_frame;\n            esv->mf_samples_to_encode -= pcm_samples_per_frame;\n            for (ch = 0; ch < cfg->channels_out; ch++)\n                for (i = 0; i < esv->mf_size; i++)\n                    mfbuf[ch][i] = mfbuf[ch][i + pcm_samples_per_frame];\n        }\n    }\n    assert(nsamples == 0);\n\n    return mp3size;\n}\n\nenum PCMSampleType \n{   pcm_short_type\n,   pcm_int_type\n,   pcm_long_type\n,   pcm_float_type\n,   pcm_double_type\n};\n\nstatic void\nlame_copy_inbuffer(lame_internal_flags* gfc, \n                   void const* l, void const* r, int nsamples,\n                   enum PCMSampleType pcm_type, int jump, FLOAT s)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    EncStateVar_t *const esv = &gfc->sv_enc;\n    sample_t* ib0 = esv->in_buffer_0;\n    sample_t* ib1 = esv->in_buffer_1;\n    FLOAT   m[2][2];\n\n    /* Apply user defined re-scaling */\n    m[0][0] = s * cfg->pcm_transform[0][0];\n    m[0][1] = s * cfg->pcm_transform[0][1];\n    m[1][0] = s * cfg->pcm_transform[1][0];\n    m[1][1] = s * cfg->pcm_transform[1][1];\n\n    /* make a copy of input buffer, changing type to sample_t */\n#define COPY_AND_TRANSFORM(T) \\\n{ \\\n    T const *bl = l, *br = r; \\\n    int     i; \\\n    for (i = 0; i < nsamples; i++) { \\\n        sample_t const xl = *bl; \\\n        sample_t const xr = *br; \\\n        sample_t const u = xl * m[0][0] + xr * m[0][1]; \\\n        sample_t const v = xl * m[1][0] + xr * m[1][1]; \\\n        ib0[i] = u; \\\n        ib1[i] = v; \\\n        bl += jump; \\\n        br += jump; \\\n    } \\\n}\n    switch ( pcm_type ) {\n    case pcm_short_type: \n        COPY_AND_TRANSFORM(short int);\n        break;\n    case pcm_int_type:\n        COPY_AND_TRANSFORM(int);\n        break;\n    case pcm_long_type:\n        COPY_AND_TRANSFORM(long int);\n        break;\n    case pcm_float_type:\n        COPY_AND_TRANSFORM(float);\n        break;\n    case pcm_double_type:\n        COPY_AND_TRANSFORM(double);\n        break;\n    }\n}\n\n\nstatic int\nlame_encode_buffer_template(lame_global_flags * gfp,\n                            void const* buffer_l, void const* buffer_r, const int nsamples,\n                            unsigned char *mp3buf, const int mp3buf_size, enum PCMSampleType pcm_type, int aa, FLOAT norm)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        lame_internal_flags *const gfc = gfp->internal_flags;\n        if (is_lame_internal_flags_valid(gfc)) {\n            SessionConfig_t const *const cfg = &gfc->cfg;\n\n            if (nsamples == 0)\n                return 0;\n\n            if (update_inbuffer_size(gfc, nsamples) != 0) {\n                return -2;\n            }\n            /* make a copy of input buffer, changing type to sample_t */\n            if (cfg->channels_in > 1) {\n                if (buffer_l == 0 || buffer_r == 0) {\n                    return 0;\n                }\n                lame_copy_inbuffer(gfc, buffer_l, buffer_r, nsamples, pcm_type, aa, norm);\n            }\n            else {\n                if (buffer_l == 0) {\n                    return 0;\n                }\n                lame_copy_inbuffer(gfc, buffer_l, buffer_l, nsamples, pcm_type, aa, norm);\n            }\n\n            return lame_encode_buffer_sample_t(gfc, nsamples, mp3buf, mp3buf_size);\n        }\n    }\n    return -3;\n}\n\nint\nlame_encode_buffer(lame_global_flags * gfp,\n                   const short int pcm_l[], const short int pcm_r[], const int nsamples,\n                   unsigned char *mp3buf, const int mp3buf_size)\n{\n    return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_short_type, 1, 1.0);\n}\n\n\nint\nlame_encode_buffer_float(lame_global_flags * gfp,\n                         const float pcm_l[], const float pcm_r[], const int nsamples,\n                         unsigned char *mp3buf, const int mp3buf_size)\n{\n    /* input is assumed to be normalized to +/- 32768 for full scale */\n    return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_float_type, 1, 1.0);\n}\n\n\nint\nlame_encode_buffer_ieee_float(lame_t gfp,\n                         const float pcm_l[], const float pcm_r[], const int nsamples,\n                         unsigned char *mp3buf, const int mp3buf_size)\n{\n    /* input is assumed to be normalized to +/- 1.0 for full scale */\n    return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_float_type, 1, 32767.0);\n}\n\n\nint\nlame_encode_buffer_interleaved_ieee_float(lame_t gfp,\n                         const float pcm[], const int nsamples,\n                         unsigned char *mp3buf, const int mp3buf_size)\n{\n    /* input is assumed to be normalized to +/- 1.0 for full scale */\n    return lame_encode_buffer_template(gfp, pcm, pcm+1, nsamples, mp3buf, mp3buf_size, pcm_float_type, 2, 32767.0);\n}\n\n\nint\nlame_encode_buffer_ieee_double(lame_t gfp,\n                         const double pcm_l[], const double pcm_r[], const int nsamples,\n                         unsigned char *mp3buf, const int mp3buf_size)\n{\n    /* input is assumed to be normalized to +/- 1.0 for full scale */\n    return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_double_type, 1, 32767.0);\n}\n\n\nint\nlame_encode_buffer_interleaved_ieee_double(lame_t gfp,\n                         const double pcm[], const int nsamples,\n                         unsigned char *mp3buf, const int mp3buf_size)\n{\n    /* input is assumed to be normalized to +/- 1.0 for full scale */\n    return lame_encode_buffer_template(gfp, pcm, pcm+1, nsamples, mp3buf, mp3buf_size, pcm_double_type, 2, 32767.0);\n}\n\n\nint\nlame_encode_buffer_int(lame_global_flags * gfp,\n                       const int pcm_l[], const int pcm_r[], const int nsamples,\n                       unsigned char *mp3buf, const int mp3buf_size)\n{\n    /* input is assumed to be normalized to +/- MAX_INT for full scale */\n    FLOAT const norm = (1.0 / (1L << (8 * sizeof(int) - 16)));\n    return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_int_type, 1, norm);\n}\n\n\nint\nlame_encode_buffer_long2(lame_global_flags * gfp,\n                         const long pcm_l[],  const long pcm_r[], const int nsamples,\n                         unsigned char *mp3buf, const int mp3buf_size)\n{\n    /* input is assumed to be normalized to +/- MAX_LONG for full scale */\n    FLOAT const norm = (1.0 / (1L << (8 * sizeof(long) - 16)));\n    return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_long_type, 1, norm);\n}\n\n\nint\nlame_encode_buffer_long(lame_global_flags * gfp,\n                        const long pcm_l[], const long pcm_r[], const int nsamples,\n                        unsigned char *mp3buf, const int mp3buf_size)\n{\n    /* input is assumed to be normalized to +/- 32768 for full scale */\n    return lame_encode_buffer_template(gfp, pcm_l, pcm_r, nsamples, mp3buf, mp3buf_size, pcm_long_type, 1, 1.0);\n}\n\n\n\nint\nlame_encode_buffer_interleaved(lame_global_flags * gfp,\n                               short int pcm[], int nsamples,\n                               unsigned char *mp3buf, int mp3buf_size)\n{\n    /* input is assumed to be normalized to +/- MAX_SHORT for full scale */\n    return lame_encode_buffer_template(gfp, pcm, pcm+1, nsamples, mp3buf, mp3buf_size, pcm_short_type, 2, 1.0);\n}\n\n\n\n\n/*****************************************************************\n Flush mp3 buffer, pad with ancillary data so last frame is complete.\n Reset reservoir size to 0\n but keep all PCM samples and MDCT data in memory\n This option is used to break a large file into several mp3 files\n that when concatenated together will decode with no gaps\n Because we set the reservoir=0, they will also decode seperately\n with no errors.\n*********************************************************************/\nint\nlame_encode_flush_nogap(lame_global_flags * gfp, unsigned char *mp3buffer, int mp3buffer_size)\n{\n    int     rc = -3;\n    if (is_lame_global_flags_valid(gfp)) {\n        lame_internal_flags *const gfc = gfp->internal_flags;\n        if (is_lame_internal_flags_valid(gfc)) {\n            flush_bitstream(gfc);\n            rc = copy_buffer(gfc, mp3buffer, mp3buffer_size, 1);\n            save_gain_values(gfc);\n        }\n    }\n    return rc;\n}\n\n\n/* called by lame_init_params.  You can also call this after flush_nogap\n   if you want to write new id3v2 and Xing VBR tags into the bitstream */\nint\nlame_init_bitstream(lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        lame_internal_flags *const gfc = gfp->internal_flags;\n        if (gfc != 0) {\n            gfc->ov_enc.frame_number = 0;\n\n            if (gfp->write_id3tag_automatic) {\n                (void) id3tag_write_v2(gfp);\n            }\n            /* initialize histogram data optionally used by frontend */\n            memset(gfc->ov_enc.bitrate_channelmode_hist, 0,\n                   sizeof(gfc->ov_enc.bitrate_channelmode_hist));\n            memset(gfc->ov_enc.bitrate_blocktype_hist, 0,\n                   sizeof(gfc->ov_enc.bitrate_blocktype_hist));\n\n            gfc->ov_rpg.PeakSample = 0.0;\n\n            /* Write initial VBR Header to bitstream and init VBR data */\n            if (gfc->cfg.write_lame_tag)\n                (void) InitVbrTag(gfp);\n\n\n            return 0;\n        }\n    }\n    return -3;\n}\n\n\n/*****************************************************************/\n/* flush internal PCM sample buffers, then mp3 buffers           */\n/* then write id3 v1 tags into bitstream.                        */\n/*****************************************************************/\n\nint\nlame_encode_flush(lame_global_flags * gfp, unsigned char *mp3buffer, int mp3buffer_size)\n{\n    lame_internal_flags *gfc;\n    SessionConfig_t const *cfg;\n    EncStateVar_t *esv;\n    short int buffer[2][1152];\n    int     imp3 = 0, mp3count, mp3buffer_size_remaining;\n\n    /* we always add POSTDELAY=288 padding to make sure granule with real\n     * data can be complety decoded (because of 50% overlap with next granule */\n    int     end_padding;\n    int     frames_left;\n    int     samples_to_encode;\n    int     pcm_samples_per_frame;\n    int     mf_needed;\n    int     is_resampling_necessary;\n    double  resample_ratio = 1;\n\n    if (!is_lame_global_flags_valid(gfp)) {\n        return -3;\n    }\n    gfc = gfp->internal_flags;\n    if (!is_lame_internal_flags_valid(gfc)) {\n        return -3;\n    }\n    cfg = &gfc->cfg;\n    esv = &gfc->sv_enc;\n    \n    /* Was flush already called? */\n    if (esv->mf_samples_to_encode < 1) {\n        return 0;\n    }\n    pcm_samples_per_frame = 576 * cfg->mode_gr;\n    mf_needed = calcNeeded(cfg);\n\n    samples_to_encode = esv->mf_samples_to_encode - POSTDELAY;\n\n    memset(buffer, 0, sizeof(buffer));\n    mp3count = 0;\n\n    is_resampling_necessary = isResamplingNecessary(cfg);\n    if (is_resampling_necessary) {\n        resample_ratio = (double)cfg->samplerate_in / (double)cfg->samplerate_out;\n        /* delay due to resampling; needs to be fixed, if resampling code gets changed */\n        samples_to_encode += 16. / resample_ratio;\n    }\n    end_padding = pcm_samples_per_frame - (samples_to_encode % pcm_samples_per_frame);\n    if (end_padding < 576)\n        end_padding += pcm_samples_per_frame;\n    gfc->ov_enc.encoder_padding = end_padding;\n    \n    frames_left = (samples_to_encode + end_padding) / pcm_samples_per_frame;\n    while (frames_left > 0 && imp3 >= 0) {\n        int const frame_num = gfc->ov_enc.frame_number;\n        int     bunch = mf_needed - esv->mf_size;\n\n        bunch *= resample_ratio;\n        if (bunch > 1152) bunch = 1152;\n        if (bunch < 1) bunch = 1;\n\n        mp3buffer_size_remaining = mp3buffer_size - mp3count;\n\n        /* if user specifed buffer size = 0, dont check size */\n        if (mp3buffer_size == 0)\n            mp3buffer_size_remaining = 0;\n\n        /* send in a frame of 0 padding until all internal sample buffers\n         * are flushed\n         */\n        imp3 = lame_encode_buffer(gfp, buffer[0], buffer[1], bunch,\n                                  mp3buffer, mp3buffer_size_remaining);\n\n        mp3buffer += imp3;\n        mp3count += imp3;\n        frames_left -= ((frame_num != gfc->ov_enc.frame_number) ? 1 : 0);\n    }\n    /* Set esv->mf_samples_to_encode to 0, so we may detect\n     * and break loops calling it more than once in a row.\n     */\n    esv->mf_samples_to_encode = 0;\n\n    if (imp3 < 0) {\n        /* some type of fatal error */\n        return imp3;\n    }\n\n    mp3buffer_size_remaining = mp3buffer_size - mp3count;\n    /* if user specifed buffer size = 0, dont check size */\n    if (mp3buffer_size == 0)\n        mp3buffer_size_remaining = 0;\n\n    /* mp3 related stuff.  bit buffer might still contain some mp3 data */\n    flush_bitstream(gfc);\n    imp3 = copy_buffer(gfc, mp3buffer, mp3buffer_size_remaining, 1);\n    save_gain_values(gfc);\n    if (imp3 < 0) {\n        /* some type of fatal error */\n        return imp3;\n    }\n    mp3buffer += imp3;\n    mp3count += imp3;\n    mp3buffer_size_remaining = mp3buffer_size - mp3count;\n    /* if user specifed buffer size = 0, dont check size */\n    if (mp3buffer_size == 0)\n        mp3buffer_size_remaining = 0;\n\n    if (gfp->write_id3tag_automatic) {\n        /* write a id3 tag to the bitstream */\n        (void) id3tag_write_v1(gfp);\n\n        imp3 = copy_buffer(gfc, mp3buffer, mp3buffer_size_remaining, 0);\n\n        if (imp3 < 0) {\n            return imp3;\n        }\n        mp3count += imp3;\n    }\n#if 0\n    {\n        int const ed = gfc->ov_enc.encoder_delay;\n        int const ep = gfc->ov_enc.encoder_padding;\n        int const ns = (gfc->ov_enc.frame_number * pcm_samples_per_frame) - (ed + ep);\n        double  duration = ns;\n        duration /= cfg->samplerate_out;\n        MSGF(gfc, \"frames=%d\\n\", gfc->ov_enc.frame_number);\n        MSGF(gfc, \"pcm_samples_per_frame=%d\\n\", pcm_samples_per_frame);\n        MSGF(gfc, \"encoder delay=%d\\n\", ed);\n        MSGF(gfc, \"encoder padding=%d\\n\", ep);\n        MSGF(gfc, \"sample count=%d (%g)\\n\", ns, cfg->samplerate_in * duration);\n        MSGF(gfc, \"duration=%g sec\\n\", duration);\n    }\n#endif\n    return mp3count;\n}\n\n/***********************************************************************\n *\n *      lame_close ()\n *\n *  frees internal buffers\n *\n ***********************************************************************/\n\nint\nlame_close(lame_global_flags * gfp)\n{\n    int     ret = 0;\n    if (gfp && gfp->class_id == LAME_ID) {\n        lame_internal_flags *const gfc = gfp->internal_flags;\n        gfp->class_id = 0;\n        if (NULL == gfc || gfc->class_id != LAME_ID) {\n            ret = -3;\n        }\n        if (NULL != gfc) {\n            gfc->class_id = 0;\n            /* this routine will free all malloc'd data in gfc, and then free gfc: */\n            freegfc(gfc);\n            gfp->internal_flags = NULL;\n        }\n        if (gfp->lame_allocated_gfp) {\n            gfp->lame_allocated_gfp = 0;\n            free(gfp);\n        }\n    }\n    return ret;\n}\n\n/*****************************************************************/\n/* flush internal mp3 buffers, and free internal buffers         */\n/*****************************************************************/\n#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED\nint CDECL\nlame_encode_finish(lame_global_flags * gfp, unsigned char *mp3buffer, int mp3buffer_size);\n#else\n#endif\n\nint\nlame_encode_finish(lame_global_flags * gfp, unsigned char *mp3buffer, int mp3buffer_size)\n{\n    int const ret = lame_encode_flush(gfp, mp3buffer, mp3buffer_size);\n\n    (void) lame_close(gfp);\n\n    return ret;\n}\n\n/*****************************************************************/\n/* write VBR Xing header, and ID3 version 1 tag, if asked for    */\n/*****************************************************************/\nvoid    lame_mp3_tags_fid(lame_global_flags * gfp, FILE * fpStream);\n\nvoid\nlame_mp3_tags_fid(lame_global_flags * gfp, FILE * fpStream)\n{\n    lame_internal_flags *gfc;\n    SessionConfig_t const *cfg;\n    if (!is_lame_global_flags_valid(gfp)) {\n        return;\n    }\n    gfc = gfp->internal_flags;\n    if (!is_lame_internal_flags_valid(gfc)) {\n        return;\n    }\n    cfg = &gfc->cfg;\n    if (!cfg->write_lame_tag) {\n        return;\n    }\n    /* Write Xing header again */\n    if (fpStream && !fseek(fpStream, 0, SEEK_SET)) {\n        int     rc = PutVbrTag(gfp, fpStream);\n        switch (rc) {\n        default:\n            /* OK */\n            break;\n\n        case -1:\n            ERRORF(gfc, \"Error: could not update LAME tag.\\n\");\n            break;\n\n        case -2:\n            ERRORF(gfc, \"Error: could not update LAME tag, file not seekable.\\n\");\n            break;\n\n        case -3:\n            ERRORF(gfc, \"Error: could not update LAME tag, file not readable.\\n\");\n            break;\n        }\n    }\n}\n\n\n\n/* initialize mp3 encoder */\n#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED\nstatic\n#else\n#endif\nint\nlame_init_old(lame_global_flags * gfp)\n{\n    lame_internal_flags *gfc;\n    SessionConfig_t *cfg;\n\n    disable_FPE();      /* disable floating point exceptions */\n\n    memset(gfp, 0, sizeof(lame_global_flags));\n\n    gfp->class_id = LAME_ID;\n\n    if (NULL == (gfc = gfp->internal_flags = calloc(1, sizeof(lame_internal_flags))))\n        return -1;\n\n    cfg = &gfc->cfg;\n\n    /* Global flags.  set defaults here for non-zero values */\n    /* see lame.h for description */\n    /* set integer values to -1 to mean that LAME will compute the\n     * best value, UNLESS the calling program as set it\n     * (and the value is no longer -1)\n     */\n    gfp->strict_ISO = MDB_MAXIMUM;\n\n    gfp->mode = NOT_SET;\n    gfp->original = 1;\n    gfp->samplerate_in = 44100;\n    gfp->num_channels = 2;\n    gfp->num_samples = MAX_U_32_NUM;\n\n    gfp->write_lame_tag = 1;\n    gfp->quality = -1;\n    gfp->short_blocks = short_block_not_set;\n    gfp->subblock_gain = -1;\n\n    gfp->lowpassfreq = 0;\n    gfp->highpassfreq = 0;\n    gfp->lowpasswidth = -1;\n    gfp->highpasswidth = -1;\n\n    gfp->VBR = vbr_off;\n    gfp->VBR_q = 4;\n    gfp->ATHcurve = -1;\n    gfp->VBR_mean_bitrate_kbps = 128;\n    gfp->VBR_min_bitrate_kbps = 0;\n    gfp->VBR_max_bitrate_kbps = 0;\n    gfp->VBR_hard_min = 0;\n    cfg->vbr_min_bitrate_index = 1; /* not  0 ????? */\n    cfg->vbr_max_bitrate_index = 13; /* not 14 ????? */\n\n    gfp->quant_comp = -1;\n    gfp->quant_comp_short = -1;\n\n    gfp->msfix = -1;\n\n    gfc->sv_qnt.OldValue[0] = 180;\n    gfc->sv_qnt.OldValue[1] = 180;\n    gfc->sv_qnt.CurrentStep[0] = 4;\n    gfc->sv_qnt.CurrentStep[1] = 4;\n    gfc->sv_qnt.masking_lower = 1;\n\n    gfp->attackthre = -1;\n    gfp->attackthre_s = -1;\n\n    gfp->scale = 1;\n    gfp->scale_left = 1;\n    gfp->scale_right = 1;\n\n    gfp->athaa_type = -1;\n    gfp->ATHtype = -1;  /* default = -1 = set in lame_init_params */\n    /* 2 = equal loudness curve */\n    gfp->athaa_sensitivity = 0.0; /* no offset */\n    gfp->useTemporal = -1;\n    gfp->interChRatio = -1;\n\n    /* The reason for\n     *       int mf_samples_to_encode = ENCDELAY + POSTDELAY;\n     * ENCDELAY = internal encoder delay.  And then we have to add POSTDELAY=288\n     * because of the 50% MDCT overlap.  A 576 MDCT granule decodes to\n     * 1152 samples.  To synthesize the 576 samples centered under this granule\n     * we need the previous granule for the first 288 samples (no problem), and\n     * the next granule for the next 288 samples (not possible if this is last\n     * granule).  So we need to pad with 288 samples to make sure we can\n     * encode the 576 samples we are interested in.\n     */\n    gfc->sv_enc.mf_samples_to_encode = ENCDELAY + POSTDELAY;\n    gfc->ov_enc.encoder_padding = 0;\n    gfc->sv_enc.mf_size = ENCDELAY - MDCTDELAY; /* we pad input with this many 0's */\n\n    gfp->findReplayGain = 0;\n    gfp->decode_on_the_fly = 0;\n\n    gfc->cfg.decode_on_the_fly = 0;\n    gfc->cfg.findReplayGain = 0;\n    gfc->cfg.findPeakSample = 0;\n\n    gfc->ov_rpg.RadioGain = 0;\n    gfc->ov_rpg.noclipGainChange = 0;\n    gfc->ov_rpg.noclipScale = -1.0;\n\n    gfp->asm_optimizations.mmx = 1;\n    gfp->asm_optimizations.amd3dnow = 1;\n    gfp->asm_optimizations.sse = 1;\n\n    gfp->preset = 0;\n\n    gfp->write_id3tag_automatic = 1;\n\n    gfp->report.debugf = &lame_report_def;\n    gfp->report.errorf = &lame_report_def;\n    gfp->report.msgf = &lame_report_def;\n    return 0;\n}\n\n\nlame_global_flags *\nlame_init(void)\n{\n    lame_global_flags *gfp;\n    int     ret;\n\n    init_log_table();\n\n    gfp = calloc(1, sizeof(lame_global_flags));\n    if (gfp == NULL)\n        return NULL;\n\n    ret = lame_init_old(gfp);\n    if (ret != 0) {\n        free(gfp);\n        return NULL;\n    }\n\n    gfp->lame_allocated_gfp = 1;\n    return gfp;\n}\n\n\n/***********************************************************************\n *\n *  some simple statistics\n *\n *  Robert Hegemann 2000-10-11\n *\n ***********************************************************************/\n\n/*  histogram of used bitrate indexes:\n *  One has to weight them to calculate the average bitrate in kbps\n *\n *  bitrate indices:\n *  there are 14 possible bitrate indices, 0 has the special meaning\n *  \"free format\" which is not possible to mix with VBR and 15 is forbidden\n *  anyway.\n *\n *  stereo modes:\n *  0: LR   number of left-right encoded frames\n *  1: LR-I number of left-right and intensity encoded frames\n *  2: MS   number of mid-side encoded frames\n *  3: MS-I number of mid-side and intensity encoded frames\n *\n *  4: number of encoded frames\n *\n */\n\nvoid\nlame_bitrate_kbps(const lame_global_flags * gfp, int bitrate_kbps[14])\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        lame_internal_flags const *const gfc = gfp->internal_flags;\n        if (is_lame_internal_flags_valid(gfc)) {\n            SessionConfig_t const *const cfg = &gfc->cfg;\n            int     i;\n            if (cfg->free_format) {\n                for (i = 0; i < 14; i++)\n                    bitrate_kbps[i] = -1;\n                bitrate_kbps[0] = cfg->avg_bitrate;\n            }\n            else {\n                for (i = 0; i < 14; i++)\n                    bitrate_kbps[i] = bitrate_table[cfg->version][i + 1];\n            }\n        }\n    }\n}\n\n\nvoid\nlame_bitrate_hist(const lame_global_flags * gfp, int bitrate_count[14])\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        lame_internal_flags const *const gfc = gfp->internal_flags;\n        if (is_lame_internal_flags_valid(gfc)) {\n            SessionConfig_t const *const cfg = &gfc->cfg;\n            EncResult_t const *const eov = &gfc->ov_enc;\n            int     i;\n\n            if (cfg->free_format) {\n                for (i = 0; i < 14; i++) {\n                    bitrate_count[i] = 0;\n                }\n                bitrate_count[0] = eov->bitrate_channelmode_hist[0][4];\n            }\n            else {\n                for (i = 0; i < 14; i++) {\n                    bitrate_count[i] = eov->bitrate_channelmode_hist[i + 1][4];\n                }\n            }\n        }\n    }\n}\n\n\nvoid\nlame_stereo_mode_hist(const lame_global_flags * gfp, int stmode_count[4])\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        lame_internal_flags const *const gfc = gfp->internal_flags;\n        if (is_lame_internal_flags_valid(gfc)) {\n            EncResult_t const *const eov = &gfc->ov_enc;\n            int     i;\n\n            for (i = 0; i < 4; i++) {\n                stmode_count[i] = eov->bitrate_channelmode_hist[15][i];\n            }\n        }\n    }\n}\n\n\n\nvoid\nlame_bitrate_stereo_mode_hist(const lame_global_flags * gfp, int bitrate_stmode_count[14][4])\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        lame_internal_flags const *const gfc = gfp->internal_flags;\n        if (is_lame_internal_flags_valid(gfc)) {\n            SessionConfig_t const *const cfg = &gfc->cfg;\n            EncResult_t const *const eov = &gfc->ov_enc;\n            int     i;\n            int     j;\n\n            if (cfg->free_format) {\n                for (j = 0; j < 14; j++)\n                    for (i = 0; i < 4; i++) {\n                        bitrate_stmode_count[j][i] = 0;\n                    }\n                for (i = 0; i < 4; i++) {\n                    bitrate_stmode_count[0][i] = eov->bitrate_channelmode_hist[0][i];\n                }\n            }\n            else {\n                for (j = 0; j < 14; j++) {\n                    for (i = 0; i < 4; i++) {\n                        bitrate_stmode_count[j][i] = eov->bitrate_channelmode_hist[j + 1][i];\n                    }\n                }\n            }\n        }\n    }\n}\n\n\nvoid\nlame_block_type_hist(const lame_global_flags * gfp, int btype_count[6])\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        lame_internal_flags const *const gfc = gfp->internal_flags;\n        if (is_lame_internal_flags_valid(gfc)) {\n            EncResult_t const *const eov = &gfc->ov_enc;\n            int     i;\n\n            for (i = 0; i < 6; ++i) {\n                btype_count[i] = eov->bitrate_blocktype_hist[15][i];\n            }\n        }\n    }\n}\n\n\n\nvoid\nlame_bitrate_block_type_hist(const lame_global_flags * gfp, int bitrate_btype_count[14][6])\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        lame_internal_flags const *const gfc = gfp->internal_flags;\n        if (is_lame_internal_flags_valid(gfc)) {\n            SessionConfig_t const *const cfg = &gfc->cfg;\n            EncResult_t const *const eov = &gfc->ov_enc;\n            int     i, j;\n\n            if (cfg->free_format) {\n                for (j = 0; j < 14; ++j) {\n                    for (i = 0; i < 6; ++i) {\n                        bitrate_btype_count[j][i] = 0;\n                    }\n                }\n                for (i = 0; i < 6; ++i) {\n                    bitrate_btype_count[0][i] = eov->bitrate_blocktype_hist[0][i];\n                }\n            }\n            else {\n                for (j = 0; j < 14; ++j) {\n                    for (i = 0; i < 6; ++i) {\n                        bitrate_btype_count[j][i] = eov->bitrate_blocktype_hist[j + 1][i];\n                    }\n                }\n            }\n        }\n    }\n}\n\n/* end of lame.c */\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/lame.h",
    "content": "/*\n *\tInterface to MP3 LAME encoding engine\n *\n *\tCopyright (c) 1999 Mark Taylor\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n/* $Id: lame.h,v 1.189.2.1 2012/01/08 23:49:58 robert Exp $ */\n\n#ifndef LAME_LAME_H\n#define LAME_LAME_H\n\n/* for size_t typedef */\n#include <stddef.h>\n/* for va_list typedef */\n#include <stdarg.h>\n/* for FILE typedef, TODO: remove when removing lame_mp3_tags_fid */\n#include <stdio.h>\n\n#if defined(__cplusplus)\nextern \"C\" {\n#endif\n\ntypedef void (*lame_report_function)(const char *format, va_list ap);\n\n#if defined(WIN32) || defined(_WIN32)\n#undef CDECL\n#define CDECL __cdecl\n#else\n#define CDECL\n#endif\n\n#define DEPRECATED_OR_OBSOLETE_CODE_REMOVED 1\n\ntypedef enum vbr_mode_e {\n  vbr_off=0,\n  vbr_mt,               /* obsolete, same as vbr_mtrh */\n  vbr_rh,\n  vbr_abr,\n  vbr_mtrh,\n  vbr_max_indicator,    /* Don't use this! It's used for sanity checks.       */\n  vbr_default=vbr_mtrh    /* change this to change the default VBR mode of LAME */\n} vbr_mode;\n\n\n/* MPEG modes */\ntypedef enum MPEG_mode_e {\n  STEREO = 0,\n  JOINT_STEREO,\n  DUAL_CHANNEL,   /* LAME doesn't supports this! */\n  MONO,\n  NOT_SET,\n  MAX_INDICATOR   /* Don't use this! It's used for sanity checks. */\n} MPEG_mode;\n\n/* Padding types */\ntypedef enum Padding_type_e {\n  PAD_NO = 0,\n  PAD_ALL,\n  PAD_ADJUST,\n  PAD_MAX_INDICATOR   /* Don't use this! It's used for sanity checks. */\n} Padding_type;\n\n\n\n/*presets*/\ntypedef enum preset_mode_e {\n    /*values from 8 to 320 should be reserved for abr bitrates*/\n    /*for abr I'd suggest to directly use the targeted bitrate as a value*/\n    ABR_8 = 8,\n    ABR_320 = 320,\n\n    V9 = 410, /*Vx to match Lame and VBR_xx to match FhG*/\n    VBR_10 = 410,\n    V8 = 420,\n    VBR_20 = 420,\n    V7 = 430,\n    VBR_30 = 430,\n    V6 = 440,\n    VBR_40 = 440,\n    V5 = 450,\n    VBR_50 = 450,\n    V4 = 460,\n    VBR_60 = 460,\n    V3 = 470,\n    VBR_70 = 470,\n    V2 = 480,\n    VBR_80 = 480,\n    V1 = 490,\n    VBR_90 = 490,\n    V0 = 500,\n    VBR_100 = 500,\n\n\n\n    /*still there for compatibility*/\n    R3MIX = 1000,\n    STANDARD = 1001,\n    EXTREME = 1002,\n    INSANE = 1003,\n    STANDARD_FAST = 1004,\n    EXTREME_FAST = 1005,\n    MEDIUM = 1006,\n    MEDIUM_FAST = 1007\n} preset_mode;\n\n\n/*asm optimizations*/\ntypedef enum asm_optimizations_e {\n    MMX = 1,\n    AMD_3DNOW = 2,\n    SSE = 3\n} asm_optimizations;\n\n\n/* psychoacoustic model */\ntypedef enum Psy_model_e {\n    PSY_GPSYCHO = 1,\n    PSY_NSPSYTUNE = 2\n} Psy_model;\n\n\n/* buffer considerations */\ntypedef enum buffer_constraint_e {\n    MDB_DEFAULT=0,\n    MDB_STRICT_ISO=1,\n    MDB_MAXIMUM=2\n} buffer_constraint;\n\n\nstruct lame_global_struct;\ntypedef struct lame_global_struct lame_global_flags;\ntypedef lame_global_flags *lame_t;\n\n\n\n\n/***********************************************************************\n *\n *  The LAME API\n *  These functions should be called, in this order, for each\n *  MP3 file to be encoded.  See the file \"API\" for more documentation\n *\n ***********************************************************************/\n\n\n/*\n * REQUIRED:\n * initialize the encoder.  sets default for all encoder parameters,\n * returns NULL if some malloc()'s failed\n * otherwise returns pointer to structure needed for all future\n * API calls.\n */\nlame_global_flags * CDECL lame_init(void);\n#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED\n#else\n/* obsolete version */\nint CDECL lame_init_old(lame_global_flags *);\n#endif\n\n/*\n * OPTIONAL:\n * set as needed to override defaults\n */\n\n/********************************************************************\n *  input stream description\n ***********************************************************************/\n/* number of samples.  default = 2^32-1   */\nint CDECL lame_set_num_samples(lame_global_flags *, unsigned long);\nunsigned long CDECL lame_get_num_samples(const lame_global_flags *);\n\n/* input sample rate in Hz.  default = 44100hz */\nint CDECL lame_set_in_samplerate(lame_global_flags *, int);\nint CDECL lame_get_in_samplerate(const lame_global_flags *);\n\n/* number of channels in input stream. default=2  */\nint CDECL lame_set_num_channels(lame_global_flags *, int);\nint CDECL lame_get_num_channels(const lame_global_flags *);\n\n/*\n  scale the input by this amount before encoding.  default=1\n  (not used by decoding routines)\n*/\nint CDECL lame_set_scale(lame_global_flags *, float);\nfloat CDECL lame_get_scale(const lame_global_flags *);\n\n/*\n  scale the channel 0 (left) input by this amount before encoding.  default=1\n  (not used by decoding routines)\n*/\nint CDECL lame_set_scale_left(lame_global_flags *, float);\nfloat CDECL lame_get_scale_left(const lame_global_flags *);\n\n/*\n  scale the channel 1 (right) input by this amount before encoding.  default=1\n  (not used by decoding routines)\n*/\nint CDECL lame_set_scale_right(lame_global_flags *, float);\nfloat CDECL lame_get_scale_right(const lame_global_flags *);\n\n/*\n  output sample rate in Hz.  default = 0, which means LAME picks best value\n  based on the amount of compression.  MPEG only allows:\n  MPEG1    32, 44.1,   48khz\n  MPEG2    16, 22.05,  24\n  MPEG2.5   8, 11.025, 12\n  (not used by decoding routines)\n*/\nint CDECL lame_set_out_samplerate(lame_global_flags *, int);\nint CDECL lame_get_out_samplerate(const lame_global_flags *);\n\n\n/********************************************************************\n *  general control parameters\n ***********************************************************************/\n/* 1=cause LAME to collect data for an MP3 frame analyzer. default=0 */\nint CDECL lame_set_analysis(lame_global_flags *, int);\nint CDECL lame_get_analysis(const lame_global_flags *);\n\n/*\n  1 = write a Xing VBR header frame.\n  default = 1\n  this variable must have been added by a Hungarian notation Windows programmer :-)\n*/\nint CDECL lame_set_bWriteVbrTag(lame_global_flags *, int);\nint CDECL lame_get_bWriteVbrTag(const lame_global_flags *);\n\n/* 1=decode only.  use lame/mpglib to convert mp3/ogg to wav.  default=0 */\nint CDECL lame_set_decode_only(lame_global_flags *, int);\nint CDECL lame_get_decode_only(const lame_global_flags *);\n\n#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED\n#else\n/* 1=encode a Vorbis .ogg file.  default=0 */\n/* DEPRECATED */\nint CDECL lame_set_ogg(lame_global_flags *, int);\nint CDECL lame_get_ogg(const lame_global_flags *);\n#endif\n\n/*\n  internal algorithm selection.  True quality is determined by the bitrate\n  but this variable will effect quality by selecting expensive or cheap algorithms.\n  quality=0..9.  0=best (very slow).  9=worst.\n  recommended:  2     near-best quality, not too slow\n                5     good quality, fast\n                7     ok quality, really fast\n*/\nint CDECL lame_set_quality(lame_global_flags *, int);\nint CDECL lame_get_quality(const lame_global_flags *);\n\n/*\n  mode = 0,1,2,3 = stereo, jstereo, dual channel (not supported), mono\n  default: lame picks based on compression ration and input channels\n*/\nint CDECL lame_set_mode(lame_global_flags *, MPEG_mode);\nMPEG_mode CDECL lame_get_mode(const lame_global_flags *);\n\n#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED\n#else\n/*\n  mode_automs.  Use a M/S mode with a switching threshold based on\n  compression ratio\n  DEPRECATED\n*/\nint CDECL lame_set_mode_automs(lame_global_flags *, int);\nint CDECL lame_get_mode_automs(const lame_global_flags *);\n#endif\n\n/*\n  force_ms.  Force M/S for all frames.  For testing only.\n  default = 0 (disabled)\n*/\nint CDECL lame_set_force_ms(lame_global_flags *, int);\nint CDECL lame_get_force_ms(const lame_global_flags *);\n\n/* use free_format?  default = 0 (disabled) */\nint CDECL lame_set_free_format(lame_global_flags *, int);\nint CDECL lame_get_free_format(const lame_global_flags *);\n\n/* perform ReplayGain analysis?  default = 0 (disabled) */\nint CDECL lame_set_findReplayGain(lame_global_flags *, int);\nint CDECL lame_get_findReplayGain(const lame_global_flags *);\n\n/* decode on the fly. Search for the peak sample. If the ReplayGain\n * analysis is enabled then perform the analysis on the decoded data\n * stream. default = 0 (disabled)\n * NOTE: if this option is set the build-in decoder should not be used */\nint CDECL lame_set_decode_on_the_fly(lame_global_flags *, int);\nint CDECL lame_get_decode_on_the_fly(const lame_global_flags *);\n\n#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED\n#else\n/* DEPRECATED: now does the same as lame_set_findReplayGain()\n   default = 0 (disabled) */\nint CDECL lame_set_ReplayGain_input(lame_global_flags *, int);\nint CDECL lame_get_ReplayGain_input(const lame_global_flags *);\n\n/* DEPRECATED: now does the same as\n   lame_set_decode_on_the_fly() && lame_set_findReplayGain()\n   default = 0 (disabled) */\nint CDECL lame_set_ReplayGain_decode(lame_global_flags *, int);\nint CDECL lame_get_ReplayGain_decode(const lame_global_flags *);\n\n/* DEPRECATED: now does the same as lame_set_decode_on_the_fly()\n   default = 0 (disabled) */\nint CDECL lame_set_findPeakSample(lame_global_flags *, int);\nint CDECL lame_get_findPeakSample(const lame_global_flags *);\n#endif\n\n/* counters for gapless encoding */\nint CDECL lame_set_nogap_total(lame_global_flags*, int);\nint CDECL lame_get_nogap_total(const lame_global_flags*);\n\nint CDECL lame_set_nogap_currentindex(lame_global_flags* , int);\nint CDECL lame_get_nogap_currentindex(const lame_global_flags*);\n\n\n/*\n * OPTIONAL:\n * Set printf like error/debug/message reporting functions.\n * The second argument has to be a pointer to a function which looks like\n *   void my_debugf(const char *format, va_list ap)\n *   {\n *       (void) vfprintf(stdout, format, ap);\n *   }\n * If you use NULL as the value of the pointer in the set function, the\n * lame buildin function will be used (prints to stderr).\n * To quiet any output you have to replace the body of the example function\n * with just \"return;\" and use it in the set function.\n */\nint CDECL lame_set_errorf(lame_global_flags *, lame_report_function);\nint CDECL lame_set_debugf(lame_global_flags *, lame_report_function);\nint CDECL lame_set_msgf  (lame_global_flags *, lame_report_function);\n\n\n\n/* set one of brate compression ratio.  default is compression ratio of 11.  */\nint CDECL lame_set_brate(lame_global_flags *, int);\nint CDECL lame_get_brate(const lame_global_flags *);\nint CDECL lame_set_compression_ratio(lame_global_flags *, float);\nfloat CDECL lame_get_compression_ratio(const lame_global_flags *);\n\n\nint CDECL lame_set_preset( lame_global_flags*  gfp, int );\nint CDECL lame_set_asm_optimizations( lame_global_flags*  gfp, int, int );\n\n\n\n/********************************************************************\n *  frame params\n ***********************************************************************/\n/* mark as copyright.  default=0 */\nint CDECL lame_set_copyright(lame_global_flags *, int);\nint CDECL lame_get_copyright(const lame_global_flags *);\n\n/* mark as original.  default=1 */\nint CDECL lame_set_original(lame_global_flags *, int);\nint CDECL lame_get_original(const lame_global_flags *);\n\n/* error_protection.  Use 2 bytes from each frame for CRC checksum. default=0 */\nint CDECL lame_set_error_protection(lame_global_flags *, int);\nint CDECL lame_get_error_protection(const lame_global_flags *);\n\n#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED\n#else\n/* padding_type. 0=pad no frames  1=pad all frames 2=adjust padding(default) */\nint CDECL lame_set_padding_type(lame_global_flags *, Padding_type);\nPadding_type CDECL lame_get_padding_type(const lame_global_flags *);\n#endif\n\n/* MP3 'private extension' bit  Meaningless.  default=0 */\nint CDECL lame_set_extension(lame_global_flags *, int);\nint CDECL lame_get_extension(const lame_global_flags *);\n\n/* enforce strict ISO compliance.  default=0 */\nint CDECL lame_set_strict_ISO(lame_global_flags *, int);\nint CDECL lame_get_strict_ISO(const lame_global_flags *);\n\n\n/********************************************************************\n * quantization/noise shaping\n ***********************************************************************/\n\n/* disable the bit reservoir. For testing only. default=0 */\nint CDECL lame_set_disable_reservoir(lame_global_flags *, int);\nint CDECL lame_get_disable_reservoir(const lame_global_flags *);\n\n/* select a different \"best quantization\" function. default=0  */\nint CDECL lame_set_quant_comp(lame_global_flags *, int);\nint CDECL lame_get_quant_comp(const lame_global_flags *);\nint CDECL lame_set_quant_comp_short(lame_global_flags *, int);\nint CDECL lame_get_quant_comp_short(const lame_global_flags *);\n\nint CDECL lame_set_experimentalX(lame_global_flags *, int); /* compatibility*/\nint CDECL lame_get_experimentalX(const lame_global_flags *);\n\n/* another experimental option.  for testing only */\nint CDECL lame_set_experimentalY(lame_global_flags *, int);\nint CDECL lame_get_experimentalY(const lame_global_flags *);\n\n/* another experimental option.  for testing only */\nint CDECL lame_set_experimentalZ(lame_global_flags *, int);\nint CDECL lame_get_experimentalZ(const lame_global_flags *);\n\n/* Naoki's psycho acoustic model.  default=0 */\nint CDECL lame_set_exp_nspsytune(lame_global_flags *, int);\nint CDECL lame_get_exp_nspsytune(const lame_global_flags *);\n\nvoid CDECL lame_set_msfix(lame_global_flags *, double);\nfloat CDECL lame_get_msfix(const lame_global_flags *);\n\n\n/********************************************************************\n * VBR control\n ***********************************************************************/\n/* Types of VBR.  default = vbr_off = CBR */\nint CDECL lame_set_VBR(lame_global_flags *, vbr_mode);\nvbr_mode CDECL lame_get_VBR(const lame_global_flags *);\n\n/* VBR quality level.  0=highest  9=lowest  */\nint CDECL lame_set_VBR_q(lame_global_flags *, int);\nint CDECL lame_get_VBR_q(const lame_global_flags *);\n\n/* VBR quality level.  0=highest  9=lowest, Range [0,...,10[  */\nint CDECL lame_set_VBR_quality(lame_global_flags *, float);\nfloat CDECL lame_get_VBR_quality(const lame_global_flags *);\n\n/* Ignored except for VBR=vbr_abr (ABR mode) */\nint CDECL lame_set_VBR_mean_bitrate_kbps(lame_global_flags *, int);\nint CDECL lame_get_VBR_mean_bitrate_kbps(const lame_global_flags *);\n\nint CDECL lame_set_VBR_min_bitrate_kbps(lame_global_flags *, int);\nint CDECL lame_get_VBR_min_bitrate_kbps(const lame_global_flags *);\n\nint CDECL lame_set_VBR_max_bitrate_kbps(lame_global_flags *, int);\nint CDECL lame_get_VBR_max_bitrate_kbps(const lame_global_flags *);\n\n/*\n  1=strictly enforce VBR_min_bitrate.  Normally it will be violated for\n  analog silence\n*/\nint CDECL lame_set_VBR_hard_min(lame_global_flags *, int);\nint CDECL lame_get_VBR_hard_min(const lame_global_flags *);\n\n/* for preset */\n#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED\n#else\nint CDECL lame_set_preset_expopts(lame_global_flags *, int);\n#endif\n\n/********************************************************************\n * Filtering control\n ***********************************************************************/\n/* freq in Hz to apply lowpass. Default = 0 = lame chooses.  -1 = disabled */\nint CDECL lame_set_lowpassfreq(lame_global_flags *, int);\nint CDECL lame_get_lowpassfreq(const lame_global_flags *);\n/* width of transition band, in Hz.  Default = one polyphase filter band */\nint CDECL lame_set_lowpasswidth(lame_global_flags *, int);\nint CDECL lame_get_lowpasswidth(const lame_global_flags *);\n\n/* freq in Hz to apply highpass. Default = 0 = lame chooses.  -1 = disabled */\nint CDECL lame_set_highpassfreq(lame_global_flags *, int);\nint CDECL lame_get_highpassfreq(const lame_global_flags *);\n/* width of transition band, in Hz.  Default = one polyphase filter band */\nint CDECL lame_set_highpasswidth(lame_global_flags *, int);\nint CDECL lame_get_highpasswidth(const lame_global_flags *);\n\n\n/********************************************************************\n * psycho acoustics and other arguments which you should not change\n * unless you know what you are doing\n ***********************************************************************/\n\n/* only use ATH for masking */\nint CDECL lame_set_ATHonly(lame_global_flags *, int);\nint CDECL lame_get_ATHonly(const lame_global_flags *);\n\n/* only use ATH for short blocks */\nint CDECL lame_set_ATHshort(lame_global_flags *, int);\nint CDECL lame_get_ATHshort(const lame_global_flags *);\n\n/* disable ATH */\nint CDECL lame_set_noATH(lame_global_flags *, int);\nint CDECL lame_get_noATH(const lame_global_flags *);\n\n/* select ATH formula */\nint CDECL lame_set_ATHtype(lame_global_flags *, int);\nint CDECL lame_get_ATHtype(const lame_global_flags *);\n\n/* lower ATH by this many db */\nint CDECL lame_set_ATHlower(lame_global_flags *, float);\nfloat CDECL lame_get_ATHlower(const lame_global_flags *);\n\n/* select ATH adaptive adjustment type */\nint CDECL lame_set_athaa_type( lame_global_flags *, int);\nint CDECL lame_get_athaa_type( const lame_global_flags *);\n\n#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED\n#else\n/* select the loudness approximation used by the ATH adaptive auto-leveling  */\nint CDECL lame_set_athaa_loudapprox( lame_global_flags *, int);\nint CDECL lame_get_athaa_loudapprox( const lame_global_flags *);\n#endif\n\n/* adjust (in dB) the point below which adaptive ATH level adjustment occurs */\nint CDECL lame_set_athaa_sensitivity( lame_global_flags *, float);\nfloat CDECL lame_get_athaa_sensitivity( const lame_global_flags* );\n\n#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED\n#else\n/* OBSOLETE: predictability limit (ISO tonality formula) */\nint CDECL lame_set_cwlimit(lame_global_flags *, int);\nint CDECL lame_get_cwlimit(const lame_global_flags *);\n#endif\n\n/*\n  allow blocktypes to differ between channels?\n  default: 0 for jstereo, 1 for stereo\n*/\nint CDECL lame_set_allow_diff_short(lame_global_flags *, int);\nint CDECL lame_get_allow_diff_short(const lame_global_flags *);\n\n/* use temporal masking effect (default = 1) */\nint CDECL lame_set_useTemporal(lame_global_flags *, int);\nint CDECL lame_get_useTemporal(const lame_global_flags *);\n\n/* use temporal masking effect (default = 1) */\nint CDECL lame_set_interChRatio(lame_global_flags *, float);\nfloat CDECL lame_get_interChRatio(const lame_global_flags *);\n\n/* disable short blocks */\nint CDECL lame_set_no_short_blocks(lame_global_flags *, int);\nint CDECL lame_get_no_short_blocks(const lame_global_flags *);\n\n/* force short blocks */\nint CDECL lame_set_force_short_blocks(lame_global_flags *, int);\nint CDECL lame_get_force_short_blocks(const lame_global_flags *);\n\n/* Input PCM is emphased PCM (for instance from one of the rarely\n   emphased CDs), it is STRONGLY not recommended to use this, because\n   psycho does not take it into account, and last but not least many decoders\n   ignore these bits */\nint CDECL lame_set_emphasis(lame_global_flags *, int);\nint CDECL lame_get_emphasis(const lame_global_flags *);\n\n\n\n/************************************************************************/\n/* internal variables, cannot be set...                                 */\n/* provided because they may be of use to calling application           */\n/************************************************************************/\n/* version  0=MPEG-2  1=MPEG-1  (2=MPEG-2.5)     */\nint CDECL lame_get_version(const lame_global_flags *);\n\n/* encoder delay   */\nint CDECL lame_get_encoder_delay(const lame_global_flags *);\n\n/*\n  padding appended to the input to make sure decoder can fully decode\n  all input.  Note that this value can only be calculated during the\n  call to lame_encoder_flush().  Before lame_encoder_flush() has\n  been called, the value of encoder_padding = 0.\n*/\nint CDECL lame_get_encoder_padding(const lame_global_flags *);\n\n/* size of MPEG frame */\nint CDECL lame_get_framesize(const lame_global_flags *);\n\n/* number of PCM samples buffered, but not yet encoded to mp3 data. */\nint CDECL lame_get_mf_samples_to_encode( const lame_global_flags*  gfp );\n\n/*\n  size (bytes) of mp3 data buffered, but not yet encoded.\n  this is the number of bytes which would be output by a call to\n  lame_encode_flush_nogap.  NOTE: lame_encode_flush() will return\n  more bytes than this because it will encode the reamining buffered\n  PCM samples before flushing the mp3 buffers.\n*/\nint CDECL lame_get_size_mp3buffer( const lame_global_flags*  gfp );\n\n/* number of frames encoded so far */\nint CDECL lame_get_frameNum(const lame_global_flags *);\n\n/*\n  lame's estimate of the total number of frames to be encoded\n   only valid if calling program set num_samples\n*/\nint CDECL lame_get_totalframes(const lame_global_flags *);\n\n/* RadioGain value. Multiplied by 10 and rounded to the nearest. */\nint CDECL lame_get_RadioGain(const lame_global_flags *);\n\n/* AudiophileGain value. Multipled by 10 and rounded to the nearest. */\nint CDECL lame_get_AudiophileGain(const lame_global_flags *);\n\n/* the peak sample */\nfloat CDECL lame_get_PeakSample(const lame_global_flags *);\n\n/* Gain change required for preventing clipping. The value is correct only if\n   peak sample searching was enabled. If negative then the waveform\n   already does not clip. The value is multiplied by 10 and rounded up. */\nint CDECL lame_get_noclipGainChange(const lame_global_flags *);\n\n/* user-specified scale factor required for preventing clipping. Value is\n   correct only if peak sample searching was enabled and no user-specified\n   scaling was performed. If negative then either the waveform already does\n   not clip or the value cannot be determined */\nfloat CDECL lame_get_noclipScale(const lame_global_flags *);\n\n\n\n\n\n\n\n/*\n * REQUIRED:\n * sets more internal configuration based on data provided above.\n * returns -1 if something failed.\n */\nint CDECL lame_init_params(lame_global_flags *);\n\n\n/*\n * OPTIONAL:\n * get the version number, in a string. of the form:\n * \"3.63 (beta)\" or just \"3.63\".\n */\nconst char*  CDECL get_lame_version       ( void );\nconst char*  CDECL get_lame_short_version ( void );\nconst char*  CDECL get_lame_very_short_version ( void );\nconst char*  CDECL get_psy_version        ( void );\nconst char*  CDECL get_lame_url           ( void );\nconst char*  CDECL get_lame_os_bitness    ( void );\n\n/*\n * OPTIONAL:\n * get the version numbers in numerical form.\n */\ntypedef struct {\n    /* generic LAME version */\n    int major;\n    int minor;\n    int alpha;               /* 0 if not an alpha version                  */\n    int beta;                /* 0 if not a beta version                    */\n\n    /* version of the psy model */\n    int psy_major;\n    int psy_minor;\n    int psy_alpha;           /* 0 if not an alpha version                  */\n    int psy_beta;            /* 0 if not a beta version                    */\n\n    /* compile time features */\n    const char *features;    /* Don't make assumptions about the contents! */\n} lame_version_t;\nvoid CDECL get_lame_version_numerical(lame_version_t *);\n\n\n/*\n * OPTIONAL:\n * print internal lame configuration to message handler\n */\nvoid CDECL lame_print_config(const lame_global_flags*  gfp);\n\nvoid CDECL lame_print_internals( const lame_global_flags *gfp);\n\n\n/*\n * input pcm data, output (maybe) mp3 frames.\n * This routine handles all buffering, resampling and filtering for you.\n *\n * return code     number of bytes output in mp3buf. Can be 0\n *                 -1:  mp3buf was too small\n *                 -2:  malloc() problem\n *                 -3:  lame_init_params() not called\n *                 -4:  psycho acoustic problems\n *\n * The required mp3buf_size can be computed from num_samples,\n * samplerate and encoding rate, but here is a worst case estimate:\n *\n * mp3buf_size in bytes = 1.25*num_samples + 7200\n *\n * I think a tighter bound could be:  (mt, March 2000)\n * MPEG1:\n *    num_samples*(bitrate/8)/samplerate + 4*1152*(bitrate/8)/samplerate + 512\n * MPEG2:\n *    num_samples*(bitrate/8)/samplerate + 4*576*(bitrate/8)/samplerate + 256\n *\n * but test first if you use that!\n *\n * set mp3buf_size = 0 and LAME will not check if mp3buf_size is\n * large enough.\n *\n * NOTE:\n * if gfp->num_channels=2, but gfp->mode = 3 (mono), the L & R channels\n * will be averaged into the L channel before encoding only the L channel\n * This will overwrite the data in buffer_l[] and buffer_r[].\n *\n*/\nint CDECL lame_encode_buffer (\n        lame_global_flags*  gfp,           /* global context handle         */\n        const short int     buffer_l [],   /* PCM data for left channel     */\n        const short int     buffer_r [],   /* PCM data for right channel    */\n        const int           nsamples,      /* number of samples per channel */\n        unsigned char*      mp3buf,        /* pointer to encoded MP3 stream */\n        const int           mp3buf_size ); /* number of valid octets in this\n                                              stream                        */\n\n/*\n * as above, but input has L & R channel data interleaved.\n * NOTE:\n * num_samples = number of samples in the L (or R)\n * channel, not the total number of samples in pcm[]\n */\nint CDECL lame_encode_buffer_interleaved(\n        lame_global_flags*  gfp,           /* global context handlei        */\n        short int           pcm[],         /* PCM data for left and right\n                                              channel, interleaved          */\n        int                 num_samples,   /* number of samples per channel,\n                                              _not_ number of samples in\n                                              pcm[]                         */\n        unsigned char*      mp3buf,        /* pointer to encoded MP3 stream */\n        int                 mp3buf_size ); /* number of valid octets in this\n                                              stream                        */\n\n\n/* as lame_encode_buffer, but for 'float's.\n * !! NOTE: !! data must still be scaled to be in the same range as\n * short int, +/- 32768\n */\nint CDECL lame_encode_buffer_float(\n        lame_global_flags*  gfp,           /* global context handle         */\n        const float         pcm_l [],      /* PCM data for left channel     */\n        const float         pcm_r [],      /* PCM data for right channel    */\n        const int           nsamples,      /* number of samples per channel */\n        unsigned char*      mp3buf,        /* pointer to encoded MP3 stream */\n        const int           mp3buf_size ); /* number of valid octets in this\n                                              stream                        */\n\n/* as lame_encode_buffer, but for 'float's.\n * !! NOTE: !! data must be scaled to +/- 1 full scale\n */\nint CDECL lame_encode_buffer_ieee_float(\n        lame_t          gfp,\n        const float     pcm_l [],          /* PCM data for left channel     */\n        const float     pcm_r [],          /* PCM data for right channel    */\n        const int       nsamples,\n        unsigned char * mp3buf,\n        const int       mp3buf_size);\nint CDECL lame_encode_buffer_interleaved_ieee_float(\n        lame_t          gfp,\n        const float     pcm[],             /* PCM data for left and right\n                                              channel, interleaved          */\n        const int       nsamples,\n        unsigned char * mp3buf,\n        const int       mp3buf_size);\n\n/* as lame_encode_buffer, but for 'double's.\n * !! NOTE: !! data must be scaled to +/- 1 full scale\n */\nint CDECL lame_encode_buffer_ieee_double(\n        lame_t          gfp,\n        const double    pcm_l [],          /* PCM data for left channel     */\n        const double    pcm_r [],          /* PCM data for right channel    */\n        const int       nsamples,\n        unsigned char * mp3buf,\n        const int       mp3buf_size);\nint CDECL lame_encode_buffer_interleaved_ieee_double(\n        lame_t          gfp,\n        const double    pcm[],             /* PCM data for left and right\n                                              channel, interleaved          */\n        const int       nsamples,\n        unsigned char * mp3buf,\n        const int       mp3buf_size);\n\n/* as lame_encode_buffer, but for long's\n * !! NOTE: !! data must still be scaled to be in the same range as\n * short int, +/- 32768\n *\n * This scaling was a mistake (doesn't allow one to exploit full\n * precision of type 'long'.  Use lame_encode_buffer_long2() instead.\n *\n */\nint CDECL lame_encode_buffer_long(\n        lame_global_flags*  gfp,           /* global context handle         */\n        const long     buffer_l [],       /* PCM data for left channel     */\n        const long     buffer_r [],       /* PCM data for right channel    */\n        const int           nsamples,      /* number of samples per channel */\n        unsigned char*      mp3buf,        /* pointer to encoded MP3 stream */\n        const int           mp3buf_size ); /* number of valid octets in this\n                                              stream                        */\n\n/* Same as lame_encode_buffer_long(), but with correct scaling.\n * !! NOTE: !! data must still be scaled to be in the same range as\n * type 'long'.   Data should be in the range:  +/- 2^(8*size(long)-1)\n *\n */\nint CDECL lame_encode_buffer_long2(\n        lame_global_flags*  gfp,           /* global context handle         */\n        const long     buffer_l [],       /* PCM data for left channel     */\n        const long     buffer_r [],       /* PCM data for right channel    */\n        const int           nsamples,      /* number of samples per channel */\n        unsigned char*      mp3buf,        /* pointer to encoded MP3 stream */\n        const int           mp3buf_size ); /* number of valid octets in this\n                                              stream                        */\n\n/* as lame_encode_buffer, but for int's\n * !! NOTE: !! input should be scaled to the maximum range of 'int'\n * If int is 4 bytes, then the values should range from\n * +/- 2147483648.\n *\n * This routine does not (and cannot, without loosing precision) use\n * the same scaling as the rest of the lame_encode_buffer() routines.\n *\n */\nint CDECL lame_encode_buffer_int(\n        lame_global_flags*  gfp,           /* global context handle         */\n        const int      buffer_l [],       /* PCM data for left channel     */\n        const int      buffer_r [],       /* PCM data for right channel    */\n        const int           nsamples,      /* number of samples per channel */\n        unsigned char*      mp3buf,        /* pointer to encoded MP3 stream */\n        const int           mp3buf_size ); /* number of valid octets in this\n                                              stream                        */\n\n\n\n\n\n/*\n * REQUIRED:\n * lame_encode_flush will flush the intenal PCM buffers, padding with\n * 0's to make sure the final frame is complete, and then flush\n * the internal MP3 buffers, and thus may return a\n * final few mp3 frames.  'mp3buf' should be at least 7200 bytes long\n * to hold all possible emitted data.\n *\n * will also write id3v1 tags (if any) into the bitstream\n *\n * return code = number of bytes output to mp3buf. Can be 0\n */\nint CDECL lame_encode_flush(\n        lame_global_flags *  gfp,    /* global context handle                 */\n        unsigned char*       mp3buf, /* pointer to encoded MP3 stream         */\n        int                  size);  /* number of valid octets in this stream */\n\n/*\n * OPTIONAL:\n * lame_encode_flush_nogap will flush the internal mp3 buffers and pad\n * the last frame with ancillary data so it is a complete mp3 frame.\n *\n * 'mp3buf' should be at least 7200 bytes long\n * to hold all possible emitted data.\n *\n * After a call to this routine, the outputed mp3 data is complete, but\n * you may continue to encode new PCM samples and write future mp3 data\n * to a different file.  The two mp3 files will play back with no gaps\n * if they are concatenated together.\n *\n * This routine will NOT write id3v1 tags into the bitstream.\n *\n * return code = number of bytes output to mp3buf. Can be 0\n */\nint CDECL lame_encode_flush_nogap(\n        lame_global_flags *  gfp,    /* global context handle                 */\n        unsigned char*       mp3buf, /* pointer to encoded MP3 stream         */\n        int                  size);  /* number of valid octets in this stream */\n\n/*\n * OPTIONAL:\n * Normally, this is called by lame_init_params().  It writes id3v2 and\n * Xing headers into the front of the bitstream, and sets frame counters\n * and bitrate histogram data to 0.  You can also call this after\n * lame_encode_flush_nogap().\n */\nint CDECL lame_init_bitstream(\n        lame_global_flags *  gfp);    /* global context handle                 */\n\n\n\n/*\n * OPTIONAL:    some simple statistics\n * a bitrate histogram to visualize the distribution of used frame sizes\n * a stereo mode histogram to visualize the distribution of used stereo\n *   modes, useful in joint-stereo mode only\n *   0: LR    left-right encoded\n *   1: LR-I  left-right and intensity encoded (currently not supported)\n *   2: MS    mid-side encoded\n *   3: MS-I  mid-side and intensity encoded (currently not supported)\n *\n * attention: don't call them after lame_encode_finish\n * suggested: lame_encode_flush -> lame_*_hist -> lame_close\n */\n\nvoid CDECL lame_bitrate_hist(\n        const lame_global_flags * gfp,\n        int bitrate_count[14] );\nvoid CDECL lame_bitrate_kbps(\n        const lame_global_flags * gfp,\n        int bitrate_kbps [14] );\nvoid CDECL lame_stereo_mode_hist(\n        const lame_global_flags * gfp,\n        int stereo_mode_count[4] );\n\nvoid CDECL lame_bitrate_stereo_mode_hist (\n        const lame_global_flags * gfp,\n        int bitrate_stmode_count[14][4] );\n\nvoid CDECL lame_block_type_hist (\n        const lame_global_flags * gfp,\n        int btype_count[6] );\n\nvoid CDECL lame_bitrate_block_type_hist (\n        const lame_global_flags * gfp,\n        int bitrate_btype_count[14][6] );\n\n#if (DEPRECATED_OR_OBSOLETE_CODE_REMOVED && 0)\n#else\n/*\n * OPTIONAL:\n * lame_mp3_tags_fid will rewrite a Xing VBR tag to the mp3 file with file\n * pointer fid.  These calls perform forward and backwards seeks, so make\n * sure fid is a real file.  Make sure lame_encode_flush has been called,\n * and all mp3 data has been written to the file before calling this\n * function.\n * NOTE:\n * if VBR  tags are turned off by the user, or turned off by LAME because\n * the output is not a regular file, this call does nothing\n * NOTE:\n * LAME wants to read from the file to skip an optional ID3v2 tag, so\n * make sure you opened the file for writing and reading.\n * NOTE:\n * You can call lame_get_lametag_frame instead, if you want to insert\n * the lametag yourself.\n*/\nvoid CDECL lame_mp3_tags_fid(lame_global_flags *, FILE* fid);\n#endif\n\n/*\n * OPTIONAL:\n * lame_get_lametag_frame copies the final LAME-tag into 'buffer'.\n * The function returns the number of bytes copied into buffer, or\n * the required buffer size, if the provided buffer is too small.\n * Function failed, if the return value is larger than 'size'!\n * Make sure lame_encode flush has been called before calling this function.\n * NOTE:\n * if VBR  tags are turned off by the user, or turned off by LAME,\n * this call does nothing and returns 0.\n * NOTE:\n * LAME inserted an empty frame in the beginning of mp3 audio data,\n * which you have to replace by the final LAME-tag frame after encoding.\n * In case there is no ID3v2 tag, usually this frame will be the very first\n * data in your mp3 file. If you put some other leading data into your\n * file, you'll have to do some bookkeeping about where to write this buffer.\n */\nsize_t CDECL lame_get_lametag_frame(\n        const lame_global_flags *, unsigned char* buffer, size_t size);\n\n/*\n * REQUIRED:\n * final call to free all remaining buffers\n */\nint  CDECL lame_close (lame_global_flags *);\n\n#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED\n#else\n/*\n * OBSOLETE:\n * lame_encode_finish combines lame_encode_flush() and lame_close() in\n * one call.  However, once this call is made, the statistics routines\n * will no longer work because the data will have been cleared, and\n * lame_mp3_tags_fid() cannot be called to add data to the VBR header\n */\nint CDECL lame_encode_finish(\n        lame_global_flags*  gfp,\n        unsigned char*      mp3buf,\n        int                 size );\n#endif\n\n\n\n\n\n\n/*********************************************************************\n *\n * decoding\n *\n * a simple interface to mpglib, part of mpg123, is also included if\n * libmp3lame is compiled with HAVE_MPGLIB\n *\n *********************************************************************/\n\nstruct hip_global_struct;\ntypedef struct hip_global_struct hip_global_flags;\ntypedef hip_global_flags *hip_t;\n\n\ntypedef struct {\n  int header_parsed;   /* 1 if header was parsed and following data was\n                          computed                                       */\n  int stereo;          /* number of channels                             */\n  int samplerate;      /* sample rate                                    */\n  int bitrate;         /* bitrate                                        */\n  int mode;            /* mp3 frame type                                 */\n  int mode_ext;        /* mp3 frame type                                 */\n  int framesize;       /* number of samples per mp3 frame                */\n\n  /* this data is only computed if mpglib detects a Xing VBR header */\n  unsigned long nsamp; /* number of samples in mp3 file.                 */\n  int totalframes;     /* total number of frames in mp3 file             */\n\n  /* this data is not currently computed by the mpglib routines */\n  int framenum;        /* frames decoded counter                         */\n} mp3data_struct;\n\n/* required call to initialize decoder */\nhip_t CDECL hip_decode_init(void);\n\n/* cleanup call to exit decoder  */\nint CDECL hip_decode_exit(hip_t gfp);\n\n/* HIP reporting functions */\nvoid CDECL hip_set_errorf(hip_t gfp, lame_report_function f);\nvoid CDECL hip_set_debugf(hip_t gfp, lame_report_function f);\nvoid CDECL hip_set_msgf  (hip_t gfp, lame_report_function f);\n\n/*********************************************************************\n * input 1 mp3 frame, output (maybe) pcm data.\n *\n *  nout = hip_decode(hip, mp3buf,len,pcm_l,pcm_r);\n *\n * input:\n *    len          :  number of bytes of mp3 data in mp3buf\n *    mp3buf[len]  :  mp3 data to be decoded\n *\n * output:\n *    nout:  -1    : decoding error\n *            0    : need more data before we can complete the decode\n *           >0    : returned 'nout' samples worth of data in pcm_l,pcm_r\n *    pcm_l[nout]  : left channel data\n *    pcm_r[nout]  : right channel data\n *\n *********************************************************************/\nint CDECL hip_decode( hip_t           gfp\n                    , unsigned char * mp3buf\n                    , size_t          len\n                    , short           pcm_l[]\n                    , short           pcm_r[]\n                    );\n\n/* same as hip_decode, and also returns mp3 header data */\nint CDECL hip_decode_headers( hip_t           gfp\n                            , unsigned char*  mp3buf\n                            , size_t          len\n                            , short           pcm_l[]\n                            , short           pcm_r[]\n                            , mp3data_struct* mp3data\n                            );\n\n/* same as hip_decode, but returns at most one frame */\nint CDECL hip_decode1( hip_t          gfp\n                     , unsigned char* mp3buf\n                     , size_t         len\n                     , short          pcm_l[]\n                     , short          pcm_r[]\n                     );\n\n/* same as hip_decode1, but returns at most one frame and mp3 header data */\nint CDECL hip_decode1_headers( hip_t           gfp\n                             , unsigned char*  mp3buf\n                             , size_t          len\n                             , short           pcm_l[]\n                             , short           pcm_r[]\n                             , mp3data_struct* mp3data\n                             );\n\n/* same as hip_decode1_headers, but also returns enc_delay and enc_padding\n   from VBR Info tag, (-1 if no info tag was found) */\nint CDECL hip_decode1_headersB( hip_t gfp\n                              , unsigned char*   mp3buf\n                              , size_t           len\n                              , short            pcm_l[]\n                              , short            pcm_r[]\n                              , mp3data_struct*  mp3data\n                              , int             *enc_delay\n                              , int             *enc_padding\n                              );\n\n\n\n/* OBSOLETE:\n * lame_decode... functions are there to keep old code working\n * but it is strongly recommended to replace calls by hip_decode...\n * function calls, see above.\n */\n#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED\n#else\nint CDECL lame_decode_init(void);\nint CDECL lame_decode(\n        unsigned char *  mp3buf,\n        int              len,\n        short            pcm_l[],\n        short            pcm_r[] );\nint CDECL lame_decode_headers(\n        unsigned char*   mp3buf,\n        int              len,\n        short            pcm_l[],\n        short            pcm_r[],\n        mp3data_struct*  mp3data );\nint CDECL lame_decode1(\n        unsigned char*  mp3buf,\n        int             len,\n        short           pcm_l[],\n        short           pcm_r[] );\nint CDECL lame_decode1_headers(\n        unsigned char*   mp3buf,\n        int              len,\n        short            pcm_l[],\n        short            pcm_r[],\n        mp3data_struct*  mp3data );\nint CDECL lame_decode1_headersB(\n        unsigned char*   mp3buf,\n        int              len,\n        short            pcm_l[],\n        short            pcm_r[],\n        mp3data_struct*  mp3data,\n        int              *enc_delay,\n        int              *enc_padding );\nint CDECL lame_decode_exit(void);\n\n#endif /* obsolete lame_decode API calls */\n\n\n/*********************************************************************\n *\n * id3tag stuff\n *\n *********************************************************************/\n\n/*\n * id3tag.h -- Interface to write ID3 version 1 and 2 tags.\n *\n * Copyright (C) 2000 Don Melton.\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.\n */\n\n/* utility to obtain alphabetically sorted list of genre names with numbers */\nvoid CDECL id3tag_genre_list(\n        void (*handler)(int, const char *, void *),\n        void*  cookie);\n\nvoid CDECL id3tag_init     (lame_t gfp);\n\n/* force addition of version 2 tag */\nvoid CDECL id3tag_add_v2   (lame_t gfp);\n\n/* add only a version 1 tag */\nvoid CDECL id3tag_v1_only  (lame_t gfp);\n\n/* add only a version 2 tag */\nvoid CDECL id3tag_v2_only  (lame_t gfp);\n\n/* pad version 1 tag with spaces instead of nulls */\nvoid CDECL id3tag_space_v1 (lame_t gfp);\n\n/* pad version 2 tag with extra 128 bytes */\nvoid CDECL id3tag_pad_v2   (lame_t gfp);\n\n/* pad version 2 tag with extra n bytes */\nvoid CDECL id3tag_set_pad  (lame_t gfp, size_t n);\n\nvoid CDECL id3tag_set_title(lame_t gfp, const char* title);\nvoid CDECL id3tag_set_artist(lame_t gfp, const char* artist);\nvoid CDECL id3tag_set_album(lame_t gfp, const char* album);\nvoid CDECL id3tag_set_year(lame_t gfp, const char* year);\nvoid CDECL id3tag_set_comment(lame_t gfp, const char* comment);\n            \n/* return -1 result if track number is out of ID3v1 range\n                    and ignored for ID3v1 */\nint CDECL id3tag_set_track(lame_t gfp, const char* track);\n\n/* return non-zero result if genre name or number is invalid\n  result 0: OK\n  result -1: genre number out of range\n  result -2: no valid ID3v1 genre name, mapped to ID3v1 'Other'\n             but taken as-is for ID3v2 genre tag */\nint CDECL id3tag_set_genre(lame_t gfp, const char* genre);\n\n/* return non-zero result if field name is invalid */\nint CDECL id3tag_set_fieldvalue(lame_t gfp, const char* fieldvalue);\n\n/* return non-zero result if image type is invalid */\nint CDECL id3tag_set_albumart(lame_t gfp, const char* image, size_t size);\n\n/* lame_get_id3v1_tag copies ID3v1 tag into buffer.\n * Function returns number of bytes copied into buffer, or number\n * of bytes rquired if buffer 'size' is too small.\n * Function fails, if returned value is larger than 'size'.\n * NOTE:\n * This functions does nothing, if user/LAME disabled ID3v1 tag.\n */\nsize_t CDECL lame_get_id3v1_tag(lame_t gfp, unsigned char* buffer, size_t size);\n\n/* lame_get_id3v2_tag copies ID3v2 tag into buffer.\n * Function returns number of bytes copied into buffer, or number\n * of bytes rquired if buffer 'size' is too small.\n * Function fails, if returned value is larger than 'size'.\n * NOTE:\n * This functions does nothing, if user/LAME disabled ID3v2 tag.\n */\nsize_t CDECL lame_get_id3v2_tag(lame_t gfp, unsigned char* buffer, size_t size);\n\n/* normaly lame_init_param writes ID3v2 tags into the audio stream\n * Call lame_set_write_id3tag_automatic(gfp, 0) before lame_init_param\n * to turn off this behaviour and get ID3v2 tag with above function\n * write it yourself into your file.\n */\nvoid CDECL lame_set_write_id3tag_automatic(lame_global_flags * gfp, int);\nint CDECL lame_get_write_id3tag_automatic(lame_global_flags const* gfp);\n\n/* experimental */\nint CDECL id3tag_set_textinfo_latin1(lame_t gfp, char const *id, char const *text);\n\n/* experimental */\nint CDECL id3tag_set_comment_latin1(lame_t gfp, char const *lang, char const *desc, char const *text);\n\n#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED\n#else\n/* experimental */\nint CDECL id3tag_set_textinfo_ucs2(lame_t gfp, char const *id, unsigned short const *text);\n\n/* experimental */\nint CDECL id3tag_set_comment_ucs2(lame_t gfp, char const *lang,\n                                  unsigned short const *desc, unsigned short const *text);\n\n/* experimental */\nint CDECL id3tag_set_fieldvalue_ucs2(lame_t gfp, const unsigned short *fieldvalue);\n#endif\n\n/* experimental */\nint CDECL id3tag_set_fieldvalue_utf16(lame_t gfp, const unsigned short *fieldvalue);\n\n/* experimental */\nint CDECL id3tag_set_textinfo_utf16(lame_t gfp, char const *id, unsigned short const *text);\n\n/* experimental */\nint CDECL id3tag_set_comment_utf16(lame_t gfp, char const *lang, unsigned short const *desc, unsigned short const *text);\n\n\n/***********************************************************************\n*\n*  list of valid bitrates [kbps] & sample frequencies [Hz].\n*  first index: 0: MPEG-2   values  (sample frequencies 16...24 kHz)\n*               1: MPEG-1   values  (sample frequencies 32...48 kHz)\n*               2: MPEG-2.5 values  (sample frequencies  8...12 kHz)\n***********************************************************************/\n\nextern const int     bitrate_table    [3][16];\nextern const int     samplerate_table [3][ 4];\n\n/* access functions for use in DLL, global vars are not exported */\nint CDECL lame_get_bitrate(int mpeg_version, int table_index);\nint CDECL lame_get_samplerate(int mpeg_version, int table_index);\n\n\n/* maximum size of albumart image (128KB), which affects LAME_MAXMP3BUFFER\n   as well since lame_encode_buffer() also returns ID3v2 tag data */\n#define LAME_MAXALBUMART    (128 * 1024)\n\n/* maximum size of mp3buffer needed if you encode at most 1152 samples for\n   each call to lame_encode_buffer.  see lame_encode_buffer() below  \n   (LAME_MAXMP3BUFFER is now obsolete)  */\n#define LAME_MAXMP3BUFFER   (16384 + LAME_MAXALBUMART)\n\n\ntypedef enum {\n    LAME_OKAY             =   0,\n    LAME_NOERROR          =   0,\n    LAME_GENERICERROR     =  -1,\n    LAME_NOMEM            = -10,\n    LAME_BADBITRATE       = -11,\n    LAME_BADSAMPFREQ      = -12,\n    LAME_INTERNALERROR    = -13,\n\n    FRONTEND_READERROR    = -80,\n    FRONTEND_WRITEERROR   = -81,\n    FRONTEND_FILETOOLARGE = -82\n\n} lame_errorcodes_t;\n\n#if defined(__cplusplus)\n}\n#endif\n#endif /* LAME_LAME_H */\n\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/lame_global_flags.h",
    "content": "#ifndef LAME_GLOBAL_FLAGS_H\n#define LAME_GLOBAL_FLAGS_H\n\n#ifndef lame_internal_flags_defined\n#define lame_internal_flags_defined\nstruct lame_internal_flags;\ntypedef struct lame_internal_flags lame_internal_flags;\n#endif\n\n\ntypedef enum short_block_e {\n    short_block_not_set = -1, /* allow LAME to decide */\n    short_block_allowed = 0, /* LAME may use them, even different block types for L/R */\n    short_block_coupled, /* LAME may use them, but always same block types in L/R */\n    short_block_dispensed, /* LAME will not use short blocks, long blocks only */\n    short_block_forced  /* LAME will not use long blocks, short blocks only */\n} short_block_t;\n\n/***********************************************************************\n*\n*  Control Parameters set by User.  These parameters are here for\n*  backwards compatibility with the old, non-shared lib API.\n*  Please use the lame_set_variablename() functions below\n*\n*\n***********************************************************************/\nstruct lame_global_struct {\n    unsigned int class_id;\n\n    /* input description */\n    unsigned long num_samples; /* number of samples. default=2^32-1           */\n    int     num_channels;    /* input number of channels. default=2         */\n    int     samplerate_in;   /* input_samp_rate in Hz. default=44.1 kHz     */\n    int     samplerate_out;  /* output_samp_rate.\n                                default: LAME picks best value\n                                at least not used for MP3 decoding:\n                                Remember 44.1 kHz MP3s and AC97           */\n    float   scale;           /* scale input by this amount before encoding\n                                at least not used for MP3 decoding          */\n    float   scale_left;      /* scale input of channel 0 (left) by this\n                                amount before encoding                      */\n    float   scale_right;     /* scale input of channel 1 (right) by this\n                                amount before encoding                      */\n\n    /* general control params */\n    int     analysis;        /* collect data for a MP3 frame analyzer?      */\n    int     write_lame_tag;  /* add Xing VBR tag?                           */\n    int     decode_only;     /* use lame/mpglib to convert mp3 to wav       */\n    int     quality;         /* quality setting 0=best,  9=worst  default=5 */\n    MPEG_mode mode;          /* see enum in lame.h\n                                default = LAME picks best value             */\n    int     force_ms;        /* force M/S mode.  requires mode=1            */\n    int     free_format;     /* use free format? default=0                  */\n    int     findReplayGain;  /* find the RG value? default=0       */\n    int     decode_on_the_fly; /* decode on the fly? default=0                */\n    int     write_id3tag_automatic; /* 1 (default) writes ID3 tags, 0 not */\n\n    int     nogap_total;\n    int     nogap_current;\n\n    int     substep_shaping;\n    int     noise_shaping;\n    int     subblock_gain;   /*  0 = no, 1 = yes */\n    int     use_best_huffman; /* 0 = no.  1=outside loop  2=inside loop(slow) */\n\n    /*\n     * set either brate>0  or compression_ratio>0, LAME will compute\n     * the value of the variable not set.\n     * Default is compression_ratio = 11.025\n     */\n    int     brate;           /* bitrate                                    */\n    float   compression_ratio; /* sizeof(wav file)/sizeof(mp3 file)          */\n\n\n    /* frame params */\n    int     copyright;       /* mark as copyright. default=0           */\n    int     original;        /* mark as original. default=1            */\n    int     extension;       /* the MP3 'private extension' bit.\n                                Meaningless                            */\n    int     emphasis;        /* Input PCM is emphased PCM (for\n                                instance from one of the rarely\n                                emphased CDs), it is STRONGLY not\n                                recommended to use this, because\n                                psycho does not take it into account,\n                                and last but not least many decoders\n                                don't care about these bits          */\n    int     error_protection; /* use 2 bytes per frame for a CRC\n                                 checksum. default=0                    */\n    int     strict_ISO;      /* enforce ISO spec as much as possible   */\n\n    int     disable_reservoir; /* use bit reservoir?                     */\n\n    /* quantization/noise shaping */\n    int     quant_comp;\n    int     quant_comp_short;\n    int     experimentalY;\n    int     experimentalZ;\n    int     exp_nspsytune;\n\n    int     preset;\n\n    /* VBR control */\n    vbr_mode VBR;\n    float   VBR_q_frac;      /* Range [0,...,1[ */\n    int     VBR_q;           /* Range [0,...,9] */\n    int     VBR_mean_bitrate_kbps;\n    int     VBR_min_bitrate_kbps;\n    int     VBR_max_bitrate_kbps;\n    int     VBR_hard_min;    /* strictly enforce VBR_min_bitrate\n                                normaly, it will be violated for analog\n                                silence                                 */\n\n\n    /* resampling and filtering */\n    int     lowpassfreq;     /* freq in Hz. 0=lame choses.\n                                -1=no filter                          */\n    int     highpassfreq;    /* freq in Hz. 0=lame choses.\n                                -1=no filter                          */\n    int     lowpasswidth;    /* freq width of filter, in Hz\n                                (default=15%)                         */\n    int     highpasswidth;   /* freq width of filter, in Hz\n                                (default=15%)                         */\n\n\n\n    /*\n     * psycho acoustics and other arguments which you should not change\n     * unless you know what you are doing\n     */\n    float   maskingadjust;\n    float   maskingadjust_short;\n    int     ATHonly;         /* only use ATH                         */\n    int     ATHshort;        /* only use ATH for short blocks        */\n    int     noATH;           /* disable ATH                          */\n    int     ATHtype;         /* select ATH formula                   */\n    float   ATHcurve;        /* change ATH formula 4 shape           */\n    float   ATH_lower_db;    /* lower ATH by this many db            */\n    int     athaa_type;      /* select ATH auto-adjust scheme        */\n    float   athaa_sensitivity; /* dB, tune active region of auto-level */\n    short_block_t short_blocks;\n    int     useTemporal;     /* use temporal masking effect          */\n    float   interChRatio;\n    float   msfix;           /* Naoki's adjustment of Mid/Side maskings */\n\n    int     tune;            /* 0 off, 1 on */\n    float   tune_value_a;    /* used to pass values for debugging and stuff */\n\n    float   attackthre;      /* attack threshold for L/R/M channel */\n    float   attackthre_s;    /* attack threshold for S channel */\n\n\n    struct {\n        void    (*msgf) (const char *format, va_list ap);\n        void    (*debugf) (const char *format, va_list ap);\n        void    (*errorf) (const char *format, va_list ap);\n    } report;\n\n  /************************************************************************/\n    /* internal variables, do not set...                                    */\n    /* provided because they may be of use to calling application           */\n  /************************************************************************/\n\n    int     lame_allocated_gfp; /* is this struct owned by calling\n                                   program or lame?                     */\n\n\n\n  /**************************************************************************/\n    /* more internal variables are stored in this structure:                  */\n  /**************************************************************************/\n    lame_internal_flags *internal_flags;\n\n\n    struct {\n        int     mmx;\n        int     amd3dnow;\n        int     sse;\n\n    } asm_optimizations;\n};\n\nint     is_lame_global_flags_valid(const lame_global_flags * gfp);\n\n#endif /* LAME_GLOBAL_FLAGS_H */\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/lameerror.h",
    "content": "/*\n *  A collection of LAME Error Codes\n *\n *  Please use the constants defined here instead of some arbitrary\n *  values. Currently the values starting at -10 to avoid intersection\n *  with the -1, -2, -3 and -4 used in the current code.\n *\n *  May be this should be a part of the include/lame.h.\n */\n\ntypedef enum {\n    LAME_OKAY = 0,\n    LAME_NOERROR = 0,\n    LAME_GENERICERROR = -1,\n    LAME_NOMEM = -10,\n    LAME_BADBITRATE = -11,\n    LAME_BADSAMPFREQ = -12,\n    LAME_INTERNALERROR = -13,\n\n    FRONTEND_READERROR = -80,\n    FRONTEND_WRITEERROR = -81,\n    FRONTEND_FILETOOLARGE = -82,\n\n} lame_errorcodes_t;\n\n/* end of lameerror.h */\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/machine.h",
    "content": "/*\n *      Machine dependent defines/includes for LAME.\n *\n *      Copyright (c) 1999 A.L. Faber\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n#ifndef LAME_MACHINE_H\n#define LAME_MACHINE_H\n\n#include \"version.h\"\n\n#if (LAME_RELEASE_VERSION == 0)\n#undef NDEBUG\n#endif\n\n#include <stdio.h>\n#include <assert.h>\n\n#ifdef STDC_HEADERS\n# include <stdlib.h>\n# include <string.h>\n#else\n# ifndef HAVE_STRCHR\n#  define strchr index\n#  define strrchr rindex\n# endif\nchar   *strchr(), *strrchr();\n# ifndef HAVE_MEMCPY\n#  define memcpy(d, s, n) bcopy ((s), (d), (n))\n#  define memmove(d, s, n) bcopy ((s), (d), (n))\n# endif\n#endif\n\n#if  defined(__riscos__)  &&  defined(FPA10)\n# include \"ymath.h\"\n#else\n# include <math.h>\n#endif\n#include <limits.h>\n\n#include <ctype.h>\n\n#ifdef HAVE_ERRNO_H\n# include <errno.h>\n#endif\n#ifdef HAVE_FCNTL_H\n# include <fcntl.h>\n#endif\n\n#if defined(macintosh)\n# include <types.h>\n# include <stat.h>\n#else\n# include <sys/types.h>\n# include <sys/stat.h>\n#endif\n\n#ifdef HAVE_INTTYPES_H\n# include <inttypes.h>\n#else\n# ifdef HAVE_STDINT_H\n#  include <stdint.h>\n# endif\n#endif\n\n#ifdef WITH_DMALLOC\n#include <dmalloc.h>\n#endif\n\n/*\n * 3 different types of pow() functions:\n *   - table lookup\n *   - pow()\n *   - exp()   on some machines this is claimed to be faster than pow()\n */\n\n#define POW20(x) (assert(0 <= (x+Q_MAX2) && x < Q_MAX), pow20[x+Q_MAX2])\n/*#define POW20(x)  pow(2.0,((double)(x)-210)*.25) */\n/*#define POW20(x)  exp( ((double)(x)-210)*(.25*LOG2) ) */\n\n#define IPOW20(x)  (assert(0 <= x && x < Q_MAX), ipow20[x])\n/*#define IPOW20(x)  exp( -((double)(x)-210)*.1875*LOG2 ) */\n/*#define IPOW20(x)  pow(2.0,-((double)(x)-210)*.1875) */\n\n/* in case this is used without configure */\n#ifndef inline\n# define inline\n#endif\n\n#if defined(_MSC_VER)\n# undef inline\n# define inline _inline\n#elif defined(__SASC) || defined(__GNUC__) || defined(__ICC) || defined(__ECC)\n/* if __GNUC__ we always want to inline, not only if the user requests it */\n# undef inline\n# define inline __inline\n#endif\n\n#if    defined(_MSC_VER)\n# pragma warning( disable : 4244 )\n/*# pragma warning( disable : 4305 ) */\n#endif\n\n/*\n * FLOAT    for variables which require at least 32 bits\n * FLOAT8   for variables which require at least 64 bits\n *\n * On some machines, 64 bit will be faster than 32 bit.  Also, some math\n * routines require 64 bit float, so setting FLOAT=float will result in a\n * lot of conversions.\n */\n\n#if ( defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MINGW32__) )\n# define WIN32_LEAN_AND_MEAN\n# include <windows.h>\n# include <float.h>\n# define FLOAT_MAX FLT_MAX\n#else\n# ifndef FLOAT\ntypedef float FLOAT;\n#  ifdef FLT_MAX\n#   define FLOAT_MAX FLT_MAX\n#  else\n#   define FLOAT_MAX 1e37 /* approx */\n#  endif\n# endif\n#endif\n\n#ifndef FLOAT8\ntypedef double FLOAT8;\n# ifdef DBL_MAX\n#  define FLOAT8_MAX DBL_MAX\n# else\n#  define FLOAT8_MAX 1e99 /* approx */\n# endif\n#else\n# ifdef FLT_MAX\n#  define FLOAT8_MAX FLT_MAX\n# else\n#  define FLOAT8_MAX 1e37 /* approx */\n# endif\n#endif\n\n/* sample_t must be floating point, at least 32 bits */\ntypedef FLOAT sample_t;\n\n#define dimension_of(array) (sizeof(array)/sizeof(array[0]))\n#define beyond(array) (array+dimension_of(array))\n#define compiletime_assert(expression) extern char static_assert_##FILE##_##LINE[expression?1:0]\n\n#if 1\n#define EQ(a,b) (\\\n(fabs(a) > fabs(b)) \\\n ? (fabs((a)-(b)) <= (fabs(a) * 1e-6f)) \\\n : (fabs((a)-(b)) <= (fabs(b) * 1e-6f)))\n#else\n#define EQ(a,b) (fabs((a)-(b))<1E-37)\n#endif\n\n#define NEQ(a,b) (!EQ(a,b))\n\n#endif\n\n#ifdef _MSC_VER\n#  if _MSC_VER < 1400\n#  define fabsf fabs\n#  define powf pow\n#  define log10f log10\n#  endif\n#endif\n\n\n/* end of machine.h */\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/mpglib_interface.c",
    "content": "/* -*- mode: C; mode: fold -*- */\n/*\n *      LAME MP3 encoding engine\n *\n *      Copyright (c) 1999-2000 Mark Taylor\n *      Copyright (c) 2003 Olcios\n *      Copyright (c) 2008 Robert Hegemann\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n/* $Id: mpglib_interface.c,v 1.42 2011/05/07 16:05:17 rbrito Exp $ */\n\n#ifdef HAVE_CONFIG_H\n# include <config.h>\n#endif\n\n#ifdef HAVE_MPGLIB\n#define hip_global_struct mpstr_tag \n#include \"lame.h\"\n#include \"machine.h\"\n#include \"encoder.h\"\n#include \"interface.h\"\n\n#include \"util.h\"\n\n\n\n#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED\n/*\n * OBSOLETE:\n * - kept to let it link\n * - forward declaration to silence compiler\n */\nint CDECL lame_decode_init(void);\nint CDECL lame_decode(\n        unsigned char *  mp3buf,\n        int              len,\n        short            pcm_l[],\n        short            pcm_r[] );\nint CDECL lame_decode_headers(\n        unsigned char*   mp3buf,\n        int              len,\n        short            pcm_l[],\n        short            pcm_r[],\n        mp3data_struct*  mp3data );\nint CDECL lame_decode1(\n        unsigned char*  mp3buf,\n        int             len,\n        short           pcm_l[],\n        short           pcm_r[] );\nint CDECL lame_decode1_headers(\n        unsigned char*   mp3buf,\n        int              len,\n        short            pcm_l[],\n        short            pcm_r[],\n        mp3data_struct*  mp3data );\nint CDECL lame_decode1_headersB(\n        unsigned char*   mp3buf,\n        int              len,\n        short            pcm_l[],\n        short            pcm_r[],\n        mp3data_struct*  mp3data,\n        int              *enc_delay,\n        int              *enc_padding );\nint CDECL lame_decode_exit(void);\n#endif\n\n\nstatic MPSTR   mp;\n\nint\nlame_decode_exit(void)\n{\n    ExitMP3(&mp);\n    return 0;\n}\n\n\nint\nlame_decode_init(void)\n{\n    (void) InitMP3(&mp);\n    return 0;\n}\n\n\n\n\n/* copy mono samples */\n#define COPY_MONO(DST_TYPE, SRC_TYPE)                                                           \\\n    DST_TYPE *pcm_l = (DST_TYPE *)pcm_l_raw;                                                    \\\n    SRC_TYPE const *p_samples = (SRC_TYPE const *)p;                                            \\\n    for (i = 0; i < processed_samples; i++)                                                     \\\n      *pcm_l++ = (DST_TYPE)(*p_samples++);\n\n/* copy stereo samples */\n#define COPY_STEREO(DST_TYPE, SRC_TYPE)                                                         \\\n    DST_TYPE *pcm_l = (DST_TYPE *)pcm_l_raw, *pcm_r = (DST_TYPE *)pcm_r_raw;                    \\\n    SRC_TYPE const *p_samples = (SRC_TYPE const *)p;                                            \\\n    for (i = 0; i < processed_samples; i++) {                                                   \\\n      *pcm_l++ = (DST_TYPE)(*p_samples++);                                                      \\\n      *pcm_r++ = (DST_TYPE)(*p_samples++);                                                      \\\n    }\n\n\n\n/*\n * For lame_decode:  return code\n * -1     error\n *  0     ok, but need more data before outputing any samples\n *  n     number of samples output.  either 576 or 1152 depending on MP3 file.\n */\n\nstatic int\ndecode1_headersB_clipchoice(PMPSTR pmp, unsigned char *buffer, int len,\n                            char pcm_l_raw[], char pcm_r_raw[], mp3data_struct * mp3data,\n                            int *enc_delay, int *enc_padding,\n                            char *p, size_t psize, int decoded_sample_size,\n                            int (*decodeMP3_ptr) (PMPSTR, unsigned char *, int, char *, int,\n                            int *))\n{\n    static const int smpls[2][4] = {\n        /* Layer   I    II   III */\n        {0, 384, 1152, 1152}, /* MPEG-1     */\n        {0, 384, 1152, 576} /* MPEG-2(.5) */\n    };\n\n    int     processed_bytes;\n    int     processed_samples; /* processed samples per channel */\n    int     ret;\n    int     i;\n\n    mp3data->header_parsed = 0;\n\n    ret = (*decodeMP3_ptr) (pmp, buffer, len, p, (int) psize, &processed_bytes);\n    /* three cases:  \n     * 1. headers parsed, but data not complete\n     *       pmp->header_parsed==1 \n     *       pmp->framesize=0           \n     *       pmp->fsizeold=size of last frame, or 0 if this is first frame\n     *\n     * 2. headers, data parsed, but ancillary data not complete\n     *       pmp->header_parsed==1 \n     *       pmp->framesize=size of frame           \n     *       pmp->fsizeold=size of last frame, or 0 if this is first frame\n     *\n     * 3. frame fully decoded:  \n     *       pmp->header_parsed==0 \n     *       pmp->framesize=0           \n     *       pmp->fsizeold=size of frame (which is now the last frame)\n     *\n     */\n    if (pmp->header_parsed || pmp->fsizeold > 0 || pmp->framesize > 0) {\n        mp3data->header_parsed = 1;\n        mp3data->stereo = pmp->fr.stereo;\n        mp3data->samplerate = freqs[pmp->fr.sampling_frequency];\n        mp3data->mode = pmp->fr.mode;\n        mp3data->mode_ext = pmp->fr.mode_ext;\n        mp3data->framesize = smpls[pmp->fr.lsf][pmp->fr.lay];\n\n        /* free format, we need the entire frame before we can determine\n         * the bitrate.  If we haven't gotten the entire frame, bitrate=0 */\n        if (pmp->fsizeold > 0) /* works for free format and fixed, no overrun, temporal results are < 400.e6 */\n            mp3data->bitrate = 8 * (4 + pmp->fsizeold) * mp3data->samplerate /\n                (1.e3 * mp3data->framesize) + 0.5;\n        else if (pmp->framesize > 0)\n            mp3data->bitrate = 8 * (4 + pmp->framesize) * mp3data->samplerate /\n                (1.e3 * mp3data->framesize) + 0.5;\n        else\n            mp3data->bitrate = tabsel_123[pmp->fr.lsf][pmp->fr.lay - 1][pmp->fr.bitrate_index];\n\n\n\n        if (pmp->num_frames > 0) {\n            /* Xing VBR header found and num_frames was set */\n            mp3data->totalframes = pmp->num_frames;\n            mp3data->nsamp = mp3data->framesize * pmp->num_frames;\n            *enc_delay = pmp->enc_delay;\n            *enc_padding = pmp->enc_padding;\n        }\n    }\n\n    switch (ret) {\n    case MP3_OK:\n        switch (pmp->fr.stereo) {\n        case 1:\n            processed_samples = processed_bytes / decoded_sample_size;\n            if (decoded_sample_size == sizeof(short)) {\n                COPY_MONO(short, short)\n            }\n            else {\n                COPY_MONO(sample_t, FLOAT)\n            }\n            break;\n        case 2:\n            processed_samples = (processed_bytes / decoded_sample_size) >> 1;\n            if (decoded_sample_size == sizeof(short)) {\n                COPY_STEREO(short, short)\n            }\n            else {\n                COPY_STEREO(sample_t, FLOAT)\n            }\n            break;\n        default:\n            processed_samples = -1;\n            assert(0);\n            break;\n        }\n        break;\n\n    case MP3_NEED_MORE:\n        processed_samples = 0;\n        break;\n\n    case MP3_ERR:\n        processed_samples = -1;\n        break;\n\n    default:\n        processed_samples = -1;\n        assert(0);\n        break;\n    }\n\n    /*fprintf(stderr,\"ok, more, err:  %i %i %i\\n\", MP3_OK, MP3_NEED_MORE, MP3_ERR ); */\n    /*fprintf(stderr,\"ret = %i out=%i\\n\", ret, processed_samples ); */\n    return processed_samples;\n}\n\n\n#define OUTSIZE_CLIPPED   (4096*sizeof(short))\n\nint\nlame_decode1_headersB(unsigned char *buffer,\n                      int len,\n                      short pcm_l[], short pcm_r[], mp3data_struct * mp3data,\n                      int *enc_delay, int *enc_padding)\n{\n    static char out[OUTSIZE_CLIPPED];\n\n    return decode1_headersB_clipchoice(&mp, buffer, len, (char *) pcm_l, (char *) pcm_r, mp3data,\n                                       enc_delay, enc_padding, out, OUTSIZE_CLIPPED,\n                                       sizeof(short), decodeMP3);\n}\n\n\n\n\n\n/*\n * For lame_decode:  return code\n *  -1     error\n *   0     ok, but need more data before outputing any samples\n *   n     number of samples output.  Will be at most one frame of\n *         MPEG data.  \n */\n\nint\nlame_decode1_headers(unsigned char *buffer,\n                     int len, short pcm_l[], short pcm_r[], mp3data_struct * mp3data)\n{\n    int     enc_delay, enc_padding;\n    return lame_decode1_headersB(buffer, len, pcm_l, pcm_r, mp3data, &enc_delay, &enc_padding);\n}\n\n\nint\nlame_decode1(unsigned char *buffer, int len, short pcm_l[], short pcm_r[])\n{\n    mp3data_struct mp3data;\n\n    return lame_decode1_headers(buffer, len, pcm_l, pcm_r, &mp3data);\n}\n\n\n/*\n * For lame_decode:  return code\n *  -1     error\n *   0     ok, but need more data before outputing any samples\n *   n     number of samples output.  a multiple of 576 or 1152 depending on MP3 file.\n */\n\nint\nlame_decode_headers(unsigned char *buffer,\n                    int len, short pcm_l[], short pcm_r[], mp3data_struct * mp3data)\n{\n    int     ret;\n    int     totsize = 0;     /* number of decoded samples per channel */\n\n    for (;;) {\n        switch (ret = lame_decode1_headers(buffer, len, pcm_l + totsize, pcm_r + totsize, mp3data)) {\n        case -1:\n            return ret;\n        case 0:\n            return totsize;\n        default:\n            totsize += ret;\n            len = 0;    /* future calls to decodeMP3 are just to flush buffers */\n            break;\n        }\n    }\n}\n\n\nint\nlame_decode(unsigned char *buffer, int len, short pcm_l[], short pcm_r[])\n{\n    mp3data_struct mp3data;\n\n    return lame_decode_headers(buffer, len, pcm_l, pcm_r, &mp3data);\n}\n\n\n\n\nhip_t hip_decode_init(void)\n{\n    hip_t hip = calloc(1, sizeof(hip_global_flags));\n    InitMP3(hip);\n    return hip;\n}\n\n\nint hip_decode_exit(hip_t hip)\n{\n    if (hip) {\n        ExitMP3(hip);\n        free(hip);\n    }\n    return 0;\n}\n\n\n/* we forbid input with more than 1152 samples per channel for output in the unclipped mode */\n#define OUTSIZE_UNCLIPPED (1152*2*sizeof(FLOAT))\n\nint\nhip_decode1_unclipped(hip_t hip, unsigned char *buffer, size_t len, sample_t pcm_l[], sample_t pcm_r[])\n{\n    static char out[OUTSIZE_UNCLIPPED];\n    mp3data_struct mp3data;\n    int     enc_delay, enc_padding;\n\n    if (hip) {\n        return decode1_headersB_clipchoice(hip, buffer, len, (char *) pcm_l, (char *) pcm_r, &mp3data,\n                                           &enc_delay, &enc_padding, out, OUTSIZE_UNCLIPPED,\n                                           sizeof(FLOAT), decodeMP3_unclipped);\n    }\n    return 0;\n}\n\n/*\n * For hip_decode:  return code\n *  -1     error\n *   0     ok, but need more data before outputing any samples\n *   n     number of samples output.  Will be at most one frame of\n *         MPEG data.  \n */\n\nint\nhip_decode1_headers(hip_t hip, unsigned char *buffer,\n                     size_t len, short pcm_l[], short pcm_r[], mp3data_struct * mp3data)\n{\n    int     enc_delay, enc_padding;\n    return hip_decode1_headersB(hip, buffer, len, pcm_l, pcm_r, mp3data, &enc_delay, &enc_padding);\n}\n\n\nint\nhip_decode1(hip_t hip, unsigned char *buffer, size_t len, short pcm_l[], short pcm_r[])\n{\n    mp3data_struct mp3data;\n    return hip_decode1_headers(hip, buffer, len, pcm_l, pcm_r, &mp3data);\n}\n\n\n/*\n * For hip_decode:  return code\n *  -1     error\n *   0     ok, but need more data before outputing any samples\n *   n     number of samples output.  a multiple of 576 or 1152 depending on MP3 file.\n */\n\nint\nhip_decode_headers(hip_t hip, unsigned char *buffer,\n                    size_t len, short pcm_l[], short pcm_r[], mp3data_struct * mp3data)\n{\n    int     ret;\n    int     totsize = 0;     /* number of decoded samples per channel */\n\n    for (;;) {\n        switch (ret = hip_decode1_headers(hip, buffer, len, pcm_l + totsize, pcm_r + totsize, mp3data)) {\n        case -1:\n            return ret;\n        case 0:\n            return totsize;\n        default:\n            totsize += ret;\n            len = 0;    /* future calls to decodeMP3 are just to flush buffers */\n            break;\n        }\n    }\n}\n\n\nint\nhip_decode(hip_t hip, unsigned char *buffer, size_t len, short pcm_l[], short pcm_r[])\n{\n    mp3data_struct mp3data;\n    return hip_decode_headers(hip, buffer, len, pcm_l, pcm_r, &mp3data);\n}\n\n\nint\nhip_decode1_headersB(hip_t hip, unsigned char *buffer,\n                      size_t len,\n                      short pcm_l[], short pcm_r[], mp3data_struct * mp3data,\n                      int *enc_delay, int *enc_padding)\n{\n    static char out[OUTSIZE_CLIPPED];\n    if (hip) {\n        return decode1_headersB_clipchoice(hip, buffer, len, (char *) pcm_l, (char *) pcm_r, mp3data,\n                                           enc_delay, enc_padding, out, OUTSIZE_CLIPPED,\n                                           sizeof(short), decodeMP3);\n    }\n    return -1;\n}\n\n\nvoid hip_set_pinfo(hip_t hip, plotting_data* pinfo)\n{\n    if (hip) {\n        hip->pinfo = pinfo;\n    }\n}\n\n\n\nvoid hip_set_errorf(hip_t hip, lame_report_function func)\n{\n    if (hip) {\n        hip->report_err = func;\n    }\n}\n\nvoid hip_set_debugf(hip_t hip, lame_report_function func)\n{\n    if (hip) {\n        hip->report_dbg = func;\n    }\n}\n\nvoid hip_set_msgf  (hip_t hip, lame_report_function func)\n{\n    if (hip) {\n        hip->report_msg = func;\n    }\n}\n\n#endif\n\n/* end of mpglib_interface.c */\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/newmdct.c",
    "content": "/*\n *      MP3 window subband -> subband filtering -> mdct routine\n *\n *      Copyright (c) 1999-2000 Takehiro Tominaga\n *\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n/*\n *         Special Thanks to Patrick De Smet for your advices.\n */\n\n/* $Id: newmdct.c,v 1.39 2011/05/07 16:05:17 rbrito Exp $ */\n\n#ifdef HAVE_CONFIG_H\n# include <config.h>\n#endif\n\n#include \"lame.h\"\n#include \"machine.h\"\n#include \"encoder.h\"\n#include \"util.h\"\n#include \"newmdct.h\"\n\n\n\n#ifndef USE_GOGO_SUBBAND\nstatic const FLOAT enwindow[] = {\n    -4.77e-07 * 0.740951125354959 / 2.384e-06, 1.03951e-04 * 0.740951125354959 / 2.384e-06,\n    9.53674e-04 * 0.740951125354959 / 2.384e-06, 2.841473e-03 * 0.740951125354959 / 2.384e-06,\n    3.5758972e-02 * 0.740951125354959 / 2.384e-06, 3.401756e-03 * 0.740951125354959 / 2.384e-06, 9.83715e-04 * 0.740951125354959 / 2.384e-06, 9.9182e-05 * 0.740951125354959 / 2.384e-06, /* 15 */\n    1.2398e-05 * 0.740951125354959 / 2.384e-06, 1.91212e-04 * 0.740951125354959 / 2.384e-06,\n    2.283096e-03 * 0.740951125354959 / 2.384e-06, 1.6994476e-02 * 0.740951125354959 / 2.384e-06,\n    -1.8756866e-02 * 0.740951125354959 / 2.384e-06, -2.630711e-03 * 0.740951125354959 / 2.384e-06,\n    -2.47478e-04 * 0.740951125354959 / 2.384e-06, -1.4782e-05 * 0.740951125354959 / 2.384e-06,\n    9.063471690191471e-01,\n    1.960342806591213e-01,\n\n\n    -4.77e-07 * 0.773010453362737 / 2.384e-06, 1.05858e-04 * 0.773010453362737 / 2.384e-06,\n    9.30786e-04 * 0.773010453362737 / 2.384e-06, 2.521515e-03 * 0.773010453362737 / 2.384e-06,\n    3.5694122e-02 * 0.773010453362737 / 2.384e-06, 3.643036e-03 * 0.773010453362737 / 2.384e-06, 9.91821e-04 * 0.773010453362737 / 2.384e-06, 9.6321e-05 * 0.773010453362737 / 2.384e-06, /* 14 */\n    1.1444e-05 * 0.773010453362737 / 2.384e-06, 1.65462e-04 * 0.773010453362737 / 2.384e-06,\n    2.110004e-03 * 0.773010453362737 / 2.384e-06, 1.6112804e-02 * 0.773010453362737 / 2.384e-06,\n    -1.9634247e-02 * 0.773010453362737 / 2.384e-06, -2.803326e-03 * 0.773010453362737 / 2.384e-06,\n    -2.77042e-04 * 0.773010453362737 / 2.384e-06, -1.6689e-05 * 0.773010453362737 / 2.384e-06,\n    8.206787908286602e-01,\n    3.901806440322567e-01,\n\n\n    -4.77e-07 * 0.803207531480645 / 2.384e-06, 1.07288e-04 * 0.803207531480645 / 2.384e-06,\n    9.02653e-04 * 0.803207531480645 / 2.384e-06, 2.174854e-03 * 0.803207531480645 / 2.384e-06,\n    3.5586357e-02 * 0.803207531480645 / 2.384e-06, 3.858566e-03 * 0.803207531480645 / 2.384e-06, 9.95159e-04 * 0.803207531480645 / 2.384e-06, 9.3460e-05 * 0.803207531480645 / 2.384e-06, /* 13 */\n    1.0014e-05 * 0.803207531480645 / 2.384e-06, 1.40190e-04 * 0.803207531480645 / 2.384e-06,\n    1.937389e-03 * 0.803207531480645 / 2.384e-06, 1.5233517e-02 * 0.803207531480645 / 2.384e-06,\n    -2.0506859e-02 * 0.803207531480645 / 2.384e-06, -2.974033e-03 * 0.803207531480645 / 2.384e-06,\n    -3.07560e-04 * 0.803207531480645 / 2.384e-06, -1.8120e-05 * 0.803207531480645 / 2.384e-06,\n    7.416505462720353e-01,\n    5.805693545089249e-01,\n\n\n    -4.77e-07 * 0.831469612302545 / 2.384e-06, 1.08242e-04 * 0.831469612302545 / 2.384e-06,\n    8.68797e-04 * 0.831469612302545 / 2.384e-06, 1.800537e-03 * 0.831469612302545 / 2.384e-06,\n    3.5435200e-02 * 0.831469612302545 / 2.384e-06, 4.049301e-03 * 0.831469612302545 / 2.384e-06, 9.94205e-04 * 0.831469612302545 / 2.384e-06, 9.0599e-05 * 0.831469612302545 / 2.384e-06, /* 12 */\n    9.060e-06 * 0.831469612302545 / 2.384e-06, 1.16348e-04 * 0.831469612302545 / 2.384e-06,\n    1.766682e-03 * 0.831469612302545 / 2.384e-06, 1.4358521e-02 * 0.831469612302545 / 2.384e-06,\n    -2.1372318e-02 * 0.831469612302545 / 2.384e-06, -3.14188e-03 * 0.831469612302545 / 2.384e-06,\n    -3.39031e-04 * 0.831469612302545 / 2.384e-06, -1.9550e-05 * 0.831469612302545 / 2.384e-06,\n    6.681786379192989e-01,\n    7.653668647301797e-01,\n\n\n    -4.77e-07 * 0.857728610000272 / 2.384e-06, 1.08719e-04 * 0.857728610000272 / 2.384e-06,\n    8.29220e-04 * 0.857728610000272 / 2.384e-06, 1.399517e-03 * 0.857728610000272 / 2.384e-06,\n    3.5242081e-02 * 0.857728610000272 / 2.384e-06, 4.215240e-03 * 0.857728610000272 / 2.384e-06, 9.89437e-04 * 0.857728610000272 / 2.384e-06, 8.7261e-05 * 0.857728610000272 / 2.384e-06, /* 11 */\n    8.106e-06 * 0.857728610000272 / 2.384e-06, 9.3937e-05 * 0.857728610000272 / 2.384e-06,\n    1.597881e-03 * 0.857728610000272 / 2.384e-06, 1.3489246e-02 * 0.857728610000272 / 2.384e-06,\n    -2.2228718e-02 * 0.857728610000272 / 2.384e-06, -3.306866e-03 * 0.857728610000272 / 2.384e-06,\n    -3.71456e-04 * 0.857728610000272 / 2.384e-06, -2.1458e-05 * 0.857728610000272 / 2.384e-06,\n    5.993769336819237e-01,\n    9.427934736519954e-01,\n\n\n    -4.77e-07 * 0.881921264348355 / 2.384e-06, 1.08719e-04 * 0.881921264348355 / 2.384e-06,\n    7.8392e-04 * 0.881921264348355 / 2.384e-06, 9.71317e-04 * 0.881921264348355 / 2.384e-06,\n    3.5007000e-02 * 0.881921264348355 / 2.384e-06, 4.357815e-03 * 0.881921264348355 / 2.384e-06, 9.80854e-04 * 0.881921264348355 / 2.384e-06, 8.3923e-05 * 0.881921264348355 / 2.384e-06, /* 10 */\n    7.629e-06 * 0.881921264348355 / 2.384e-06, 7.2956e-05 * 0.881921264348355 / 2.384e-06,\n    1.432419e-03 * 0.881921264348355 / 2.384e-06, 1.2627602e-02 * 0.881921264348355 / 2.384e-06,\n    -2.3074150e-02 * 0.881921264348355 / 2.384e-06, -3.467083e-03 * 0.881921264348355 / 2.384e-06,\n    -4.04358e-04 * 0.881921264348355 / 2.384e-06, -2.3365e-05 * 0.881921264348355 / 2.384e-06,\n    5.345111359507916e-01,\n    1.111140466039205e+00,\n\n\n    -9.54e-07 * 0.903989293123443 / 2.384e-06, 1.08242e-04 * 0.903989293123443 / 2.384e-06,\n    7.31945e-04 * 0.903989293123443 / 2.384e-06, 5.15938e-04 * 0.903989293123443 / 2.384e-06,\n    3.4730434e-02 * 0.903989293123443 / 2.384e-06, 4.477024e-03 * 0.903989293123443 / 2.384e-06, 9.68933e-04 * 0.903989293123443 / 2.384e-06, 8.0585e-05 * 0.903989293123443 / 2.384e-06, /* 9 */\n    6.676e-06 * 0.903989293123443 / 2.384e-06, 5.2929e-05 * 0.903989293123443 / 2.384e-06,\n    1.269817e-03 * 0.903989293123443 / 2.384e-06, 1.1775017e-02 * 0.903989293123443 / 2.384e-06,\n    -2.3907185e-02 * 0.903989293123443 / 2.384e-06, -3.622532e-03 * 0.903989293123443 / 2.384e-06,\n    -4.38213e-04 * 0.903989293123443 / 2.384e-06, -2.5272e-05 * 0.903989293123443 / 2.384e-06,\n    4.729647758913199e-01,\n    1.268786568327291e+00,\n\n\n    -9.54e-07 * 0.92387953251128675613 / 2.384e-06,\n    1.06812e-04 * 0.92387953251128675613 / 2.384e-06,\n    6.74248e-04 * 0.92387953251128675613 / 2.384e-06,\n    3.3379e-05 * 0.92387953251128675613 / 2.384e-06,\n    3.4412861e-02 * 0.92387953251128675613 / 2.384e-06,\n    4.573822e-03 * 0.92387953251128675613 / 2.384e-06,\n    9.54151e-04 * 0.92387953251128675613 / 2.384e-06,\n    7.6771e-05 * 0.92387953251128675613 / 2.384e-06,\n    6.199e-06 * 0.92387953251128675613 / 2.384e-06, 3.4332e-05 * 0.92387953251128675613 / 2.384e-06,\n    1.111031e-03 * 0.92387953251128675613 / 2.384e-06,\n    1.0933399e-02 * 0.92387953251128675613 / 2.384e-06,\n    -2.4725437e-02 * 0.92387953251128675613 / 2.384e-06,\n    -3.771782e-03 * 0.92387953251128675613 / 2.384e-06,\n    -4.72546e-04 * 0.92387953251128675613 / 2.384e-06,\n    -2.7657e-05 * 0.92387953251128675613 / 2.384e-06,\n    4.1421356237309504879e-01, /* tan(PI/8) */\n    1.414213562373095e+00,\n\n\n    -9.54e-07 * 0.941544065183021 / 2.384e-06, 1.05381e-04 * 0.941544065183021 / 2.384e-06,\n    6.10352e-04 * 0.941544065183021 / 2.384e-06, -4.75883e-04 * 0.941544065183021 / 2.384e-06,\n    3.4055710e-02 * 0.941544065183021 / 2.384e-06, 4.649162e-03 * 0.941544065183021 / 2.384e-06, 9.35555e-04 * 0.941544065183021 / 2.384e-06, 7.3433e-05 * 0.941544065183021 / 2.384e-06, /* 7 */\n    5.245e-06 * 0.941544065183021 / 2.384e-06, 1.7166e-05 * 0.941544065183021 / 2.384e-06,\n    9.56535e-04 * 0.941544065183021 / 2.384e-06, 1.0103703e-02 * 0.941544065183021 / 2.384e-06,\n    -2.5527000e-02 * 0.941544065183021 / 2.384e-06, -3.914356e-03 * 0.941544065183021 / 2.384e-06,\n    -5.07355e-04 * 0.941544065183021 / 2.384e-06, -3.0041e-05 * 0.941544065183021 / 2.384e-06,\n    3.578057213145241e-01,\n    1.546020906725474e+00,\n\n\n    -9.54e-07 * 0.956940335732209 / 2.384e-06, 1.02520e-04 * 0.956940335732209 / 2.384e-06,\n    5.39303e-04 * 0.956940335732209 / 2.384e-06, -1.011848e-03 * 0.956940335732209 / 2.384e-06,\n    3.3659935e-02 * 0.956940335732209 / 2.384e-06, 4.703045e-03 * 0.956940335732209 / 2.384e-06, 9.15051e-04 * 0.956940335732209 / 2.384e-06, 7.0095e-05 * 0.956940335732209 / 2.384e-06, /* 6 */\n    4.768e-06 * 0.956940335732209 / 2.384e-06, 9.54e-07 * 0.956940335732209 / 2.384e-06,\n    8.06808e-04 * 0.956940335732209 / 2.384e-06, 9.287834e-03 * 0.956940335732209 / 2.384e-06,\n    -2.6310921e-02 * 0.956940335732209 / 2.384e-06, -4.048824e-03 * 0.956940335732209 / 2.384e-06,\n    -5.42164e-04 * 0.956940335732209 / 2.384e-06, -3.2425e-05 * 0.956940335732209 / 2.384e-06,\n    3.033466836073424e-01,\n    1.662939224605090e+00,\n\n\n    -1.431e-06 * 0.970031253194544 / 2.384e-06, 9.9182e-05 * 0.970031253194544 / 2.384e-06,\n    4.62532e-04 * 0.970031253194544 / 2.384e-06, -1.573563e-03 * 0.970031253194544 / 2.384e-06,\n    3.3225536e-02 * 0.970031253194544 / 2.384e-06, 4.737377e-03 * 0.970031253194544 / 2.384e-06, 8.91685e-04 * 0.970031253194544 / 2.384e-06, 6.6280e-05 * 0.970031253194544 / 2.384e-06, /* 5 */\n    4.292e-06 * 0.970031253194544 / 2.384e-06, -1.3828e-05 * 0.970031253194544 / 2.384e-06,\n    6.61850e-04 * 0.970031253194544 / 2.384e-06, 8.487225e-03 * 0.970031253194544 / 2.384e-06,\n    -2.7073860e-02 * 0.970031253194544 / 2.384e-06, -4.174709e-03 * 0.970031253194544 / 2.384e-06,\n    -5.76973e-04 * 0.970031253194544 / 2.384e-06, -3.4809e-05 * 0.970031253194544 / 2.384e-06,\n    2.504869601913055e-01,\n    1.763842528696710e+00,\n\n\n    -1.431e-06 * 0.98078528040323 / 2.384e-06, 9.5367e-05 * 0.98078528040323 / 2.384e-06,\n    3.78609e-04 * 0.98078528040323 / 2.384e-06, -2.161503e-03 * 0.98078528040323 / 2.384e-06,\n    3.2754898e-02 * 0.98078528040323 / 2.384e-06, 4.752159e-03 * 0.98078528040323 / 2.384e-06, 8.66413e-04 * 0.98078528040323 / 2.384e-06, 6.2943e-05 * 0.98078528040323 / 2.384e-06, /* 4 */\n    3.815e-06 * 0.98078528040323 / 2.384e-06, -2.718e-05 * 0.98078528040323 / 2.384e-06,\n    5.22137e-04 * 0.98078528040323 / 2.384e-06, 7.703304e-03 * 0.98078528040323 / 2.384e-06,\n    -2.7815342e-02 * 0.98078528040323 / 2.384e-06, -4.290581e-03 * 0.98078528040323 / 2.384e-06,\n    -6.11782e-04 * 0.98078528040323 / 2.384e-06, -3.7670e-05 * 0.98078528040323 / 2.384e-06,\n    1.989123673796580e-01,\n    1.847759065022573e+00,\n\n\n    -1.907e-06 * 0.989176509964781 / 2.384e-06, 9.0122e-05 * 0.989176509964781 / 2.384e-06,\n    2.88486e-04 * 0.989176509964781 / 2.384e-06, -2.774239e-03 * 0.989176509964781 / 2.384e-06,\n    3.2248020e-02 * 0.989176509964781 / 2.384e-06, 4.748821e-03 * 0.989176509964781 / 2.384e-06, 8.38757e-04 * 0.989176509964781 / 2.384e-06, 5.9605e-05 * 0.989176509964781 / 2.384e-06, /* 3 */\n    3.338e-06 * 0.989176509964781 / 2.384e-06, -3.9577e-05 * 0.989176509964781 / 2.384e-06,\n    3.88145e-04 * 0.989176509964781 / 2.384e-06, 6.937027e-03 * 0.989176509964781 / 2.384e-06,\n    -2.8532982e-02 * 0.989176509964781 / 2.384e-06, -4.395962e-03 * 0.989176509964781 / 2.384e-06,\n    -6.46591e-04 * 0.989176509964781 / 2.384e-06, -4.0531e-05 * 0.989176509964781 / 2.384e-06,\n    1.483359875383474e-01,\n    1.913880671464418e+00,\n\n\n    -1.907e-06 * 0.995184726672197 / 2.384e-06, 8.4400e-05 * 0.995184726672197 / 2.384e-06,\n    1.91689e-04 * 0.995184726672197 / 2.384e-06, -3.411293e-03 * 0.995184726672197 / 2.384e-06,\n    3.1706810e-02 * 0.995184726672197 / 2.384e-06, 4.728317e-03 * 0.995184726672197 / 2.384e-06,\n    8.09669e-04 * 0.995184726672197 / 2.384e-06, 5.579e-05 * 0.995184726672197 / 2.384e-06,\n    3.338e-06 * 0.995184726672197 / 2.384e-06, -5.0545e-05 * 0.995184726672197 / 2.384e-06,\n    2.59876e-04 * 0.995184726672197 / 2.384e-06, 6.189346e-03 * 0.995184726672197 / 2.384e-06,\n    -2.9224873e-02 * 0.995184726672197 / 2.384e-06, -4.489899e-03 * 0.995184726672197 / 2.384e-06,\n    -6.80923e-04 * 0.995184726672197 / 2.384e-06, -4.3392e-05 * 0.995184726672197 / 2.384e-06,\n    9.849140335716425e-02,\n    1.961570560806461e+00,\n\n\n    -2.384e-06 * 0.998795456205172 / 2.384e-06, 7.7724e-05 * 0.998795456205172 / 2.384e-06,\n    8.8215e-05 * 0.998795456205172 / 2.384e-06, -4.072189e-03 * 0.998795456205172 / 2.384e-06,\n    3.1132698e-02 * 0.998795456205172 / 2.384e-06, 4.691124e-03 * 0.998795456205172 / 2.384e-06,\n    7.79152e-04 * 0.998795456205172 / 2.384e-06, 5.2929e-05 * 0.998795456205172 / 2.384e-06,\n    2.861e-06 * 0.998795456205172 / 2.384e-06, -6.0558e-05 * 0.998795456205172 / 2.384e-06,\n    1.37329e-04 * 0.998795456205172 / 2.384e-06, 5.462170e-03 * 0.998795456205172 / 2.384e-06,\n    -2.9890060e-02 * 0.998795456205172 / 2.384e-06, -4.570484e-03 * 0.998795456205172 / 2.384e-06,\n    -7.14302e-04 * 0.998795456205172 / 2.384e-06, -4.6253e-05 * 0.998795456205172 / 2.384e-06,\n    4.912684976946725e-02,\n    1.990369453344394e+00,\n\n\n    3.5780907e-02 * SQRT2 * 0.5 / 2.384e-06, 1.7876148e-02 * SQRT2 * 0.5 / 2.384e-06,\n    3.134727e-03 * SQRT2 * 0.5 / 2.384e-06, 2.457142e-03 * SQRT2 * 0.5 / 2.384e-06,\n    9.71317e-04 * SQRT2 * 0.5 / 2.384e-06, 2.18868e-04 * SQRT2 * 0.5 / 2.384e-06,\n    1.01566e-04 * SQRT2 * 0.5 / 2.384e-06, 1.3828e-05 * SQRT2 * 0.5 / 2.384e-06,\n\n    3.0526638e-02 / 2.384e-06, 4.638195e-03 / 2.384e-06, 7.47204e-04 / 2.384e-06,\n    4.9591e-05 / 2.384e-06,\n    4.756451e-03 / 2.384e-06, 2.1458e-05 / 2.384e-06, -6.9618e-05 / 2.384e-06, /*    2.384e-06/2.384e-06 */\n};\n#endif\n\n\n#define NS 12\n#define NL 36\n\nstatic const FLOAT win[4][NL] = {\n    {\n     2.382191739347913e-13,\n     6.423305872147834e-13,\n     9.400849094049688e-13,\n     1.122435026096556e-12,\n     1.183840321267481e-12,\n     1.122435026096556e-12,\n     9.400849094049690e-13,\n     6.423305872147839e-13,\n     2.382191739347918e-13,\n\n     5.456116108943412e-12,\n     4.878985199565852e-12,\n     4.240448995017367e-12,\n     3.559909094758252e-12,\n     2.858043359288075e-12,\n     2.156177623817898e-12,\n     1.475637723558783e-12,\n     8.371015190102974e-13,\n     2.599706096327376e-13,\n\n     -5.456116108943412e-12,\n     -4.878985199565852e-12,\n     -4.240448995017367e-12,\n     -3.559909094758252e-12,\n     -2.858043359288076e-12,\n     -2.156177623817898e-12,\n     -1.475637723558783e-12,\n     -8.371015190102975e-13,\n     -2.599706096327376e-13,\n\n     -2.382191739347923e-13,\n     -6.423305872147843e-13,\n     -9.400849094049696e-13,\n     -1.122435026096556e-12,\n     -1.183840321267481e-12,\n     -1.122435026096556e-12,\n     -9.400849094049694e-13,\n     -6.423305872147840e-13,\n     -2.382191739347918e-13,\n     },\n    {\n     2.382191739347913e-13,\n     6.423305872147834e-13,\n     9.400849094049688e-13,\n     1.122435026096556e-12,\n     1.183840321267481e-12,\n     1.122435026096556e-12,\n     9.400849094049688e-13,\n     6.423305872147841e-13,\n     2.382191739347918e-13,\n\n     5.456116108943413e-12,\n     4.878985199565852e-12,\n     4.240448995017367e-12,\n     3.559909094758253e-12,\n     2.858043359288075e-12,\n     2.156177623817898e-12,\n     1.475637723558782e-12,\n     8.371015190102975e-13,\n     2.599706096327376e-13,\n\n     -5.461314069809755e-12,\n     -4.921085770524055e-12,\n     -4.343405037091838e-12,\n     -3.732668368707687e-12,\n     -3.093523840190885e-12,\n     -2.430835727329465e-12,\n     -1.734679010007751e-12,\n     -9.748253656609281e-13,\n     -2.797435120168326e-13,\n\n     0.000000000000000e+00,\n     0.000000000000000e+00,\n     0.000000000000000e+00,\n     0.000000000000000e+00,\n     0.000000000000000e+00,\n     0.000000000000000e+00,\n     -2.283748241799531e-13,\n     -4.037858874020686e-13,\n     -2.146547464825323e-13,\n     },\n    {\n     1.316524975873958e-01, /* win[SHORT_TYPE] */\n     4.142135623730950e-01,\n     7.673269879789602e-01,\n\n     1.091308501069271e+00, /* tantab_l */\n     1.303225372841206e+00,\n     1.569685577117490e+00,\n     1.920982126971166e+00,\n     2.414213562373094e+00,\n     3.171594802363212e+00,\n     4.510708503662055e+00,\n     7.595754112725146e+00,\n     2.290376554843115e+01,\n\n     0.98480775301220802032, /* cx */\n     0.64278760968653936292,\n     0.34202014332566882393,\n     0.93969262078590842791,\n     -0.17364817766693030343,\n     -0.76604444311897790243,\n     0.86602540378443870761,\n     0.500000000000000e+00,\n\n     -5.144957554275265e-01, /* ca */\n     -4.717319685649723e-01,\n     -3.133774542039019e-01,\n     -1.819131996109812e-01,\n     -9.457419252642064e-02,\n     -4.096558288530405e-02,\n     -1.419856857247115e-02,\n     -3.699974673760037e-03,\n\n     8.574929257125442e-01, /* cs */\n     8.817419973177052e-01,\n     9.496286491027329e-01,\n     9.833145924917901e-01,\n     9.955178160675857e-01,\n     9.991605581781475e-01,\n     9.998991952444470e-01,\n     9.999931550702802e-01,\n     },\n    {\n     0.000000000000000e+00,\n     0.000000000000000e+00,\n     0.000000000000000e+00,\n     0.000000000000000e+00,\n     0.000000000000000e+00,\n     0.000000000000000e+00,\n     2.283748241799531e-13,\n     4.037858874020686e-13,\n     2.146547464825323e-13,\n\n     5.461314069809755e-12,\n     4.921085770524055e-12,\n     4.343405037091838e-12,\n     3.732668368707687e-12,\n     3.093523840190885e-12,\n     2.430835727329466e-12,\n     1.734679010007751e-12,\n     9.748253656609281e-13,\n     2.797435120168326e-13,\n\n     -5.456116108943413e-12,\n     -4.878985199565852e-12,\n     -4.240448995017367e-12,\n     -3.559909094758253e-12,\n     -2.858043359288075e-12,\n     -2.156177623817898e-12,\n     -1.475637723558782e-12,\n     -8.371015190102975e-13,\n     -2.599706096327376e-13,\n\n     -2.382191739347913e-13,\n     -6.423305872147834e-13,\n     -9.400849094049688e-13,\n     -1.122435026096556e-12,\n     -1.183840321267481e-12,\n     -1.122435026096556e-12,\n     -9.400849094049688e-13,\n     -6.423305872147841e-13,\n     -2.382191739347918e-13,\n     }\n};\n\n#define tantab_l (win[SHORT_TYPE]+3)\n#define cx (win[SHORT_TYPE]+12)\n#define ca (win[SHORT_TYPE]+20)\n#define cs (win[SHORT_TYPE]+28)\n\n/************************************************************************\n*\n* window_subband()\n*\n* PURPOSE:  Overlapping window on PCM samples\n*\n* SEMANTICS:\n* 32 16-bit pcm samples are scaled to fractional 2's complement and\n* concatenated to the end of the window buffer #x#. The updated window\n* buffer #x# is then windowed by the analysis window #c# to produce the\n* windowed sample #z#\n*\n************************************************************************/\n\n/*\n *      new IDCT routine written by Takehiro TOMINAGA\n */\nstatic const int order[] = {\n    0, 1, 16, 17, 8, 9, 24, 25, 4, 5, 20, 21, 12, 13, 28, 29,\n    2, 3, 18, 19, 10, 11, 26, 27, 6, 7, 22, 23, 14, 15, 30, 31\n};\n\n\n/* returns sum_j=0^31 a[j]*cos(PI*j*(k+1/2)/32), 0<=k<32 */\ninline static void\nwindow_subband(const sample_t * x1, FLOAT a[SBLIMIT])\n{\n    int     i;\n    FLOAT const *wp = enwindow + 10;\n\n    const sample_t *x2 = &x1[238 - 14 - 286];\n\n    for (i = -15; i < 0; i++) {\n        FLOAT   w, s, t;\n\n        w = wp[-10];\n        s = x2[-224] * w;\n        t = x1[224] * w;\n        w = wp[-9];\n        s += x2[-160] * w;\n        t += x1[160] * w;\n        w = wp[-8];\n        s += x2[-96] * w;\n        t += x1[96] * w;\n        w = wp[-7];\n        s += x2[-32] * w;\n        t += x1[32] * w;\n        w = wp[-6];\n        s += x2[32] * w;\n        t += x1[-32] * w;\n        w = wp[-5];\n        s += x2[96] * w;\n        t += x1[-96] * w;\n        w = wp[-4];\n        s += x2[160] * w;\n        t += x1[-160] * w;\n        w = wp[-3];\n        s += x2[224] * w;\n        t += x1[-224] * w;\n\n        w = wp[-2];\n        s += x1[-256] * w;\n        t -= x2[256] * w;\n        w = wp[-1];\n        s += x1[-192] * w;\n        t -= x2[192] * w;\n        w = wp[0];\n        s += x1[-128] * w;\n        t -= x2[128] * w;\n        w = wp[1];\n        s += x1[-64] * w;\n        t -= x2[64] * w;\n        w = wp[2];\n        s += x1[0] * w;\n        t -= x2[0] * w;\n        w = wp[3];\n        s += x1[64] * w;\n        t -= x2[-64] * w;\n        w = wp[4];\n        s += x1[128] * w;\n        t -= x2[-128] * w;\n        w = wp[5];\n        s += x1[192] * w;\n        t -= x2[-192] * w;\n\n        /*\n         * this multiplyer could be removed, but it needs more 256 FLOAT data.\n         * thinking about the data cache performance, I think we should not\n         * use such a huge table. tt 2000/Oct/25\n         */\n        s *= wp[6];\n        w = t - s;\n        a[30 + i * 2] = t + s;\n        a[31 + i * 2] = wp[7] * w;\n        wp += 18;\n        x1--;\n        x2++;\n    }\n    {\n        FLOAT   s, t, u, v;\n        t = x1[-16] * wp[-10];\n        s = x1[-32] * wp[-2];\n        t += (x1[-48] - x1[16]) * wp[-9];\n        s += x1[-96] * wp[-1];\n        t += (x1[-80] + x1[48]) * wp[-8];\n        s += x1[-160] * wp[0];\n        t += (x1[-112] - x1[80]) * wp[-7];\n        s += x1[-224] * wp[1];\n        t += (x1[-144] + x1[112]) * wp[-6];\n        s -= x1[32] * wp[2];\n        t += (x1[-176] - x1[144]) * wp[-5];\n        s -= x1[96] * wp[3];\n        t += (x1[-208] + x1[176]) * wp[-4];\n        s -= x1[160] * wp[4];\n        t += (x1[-240] - x1[208]) * wp[-3];\n        s -= x1[224];\n\n        u = s - t;\n        v = s + t;\n\n        t = a[14];\n        s = a[15] - t;\n\n        a[31] = v + t;  /* A0 */\n        a[30] = u + s;  /* A1 */\n        a[15] = u - s;  /* A2 */\n        a[14] = v - t;  /* A3 */\n    }\n    {\n        FLOAT   xr;\n        xr = a[28] - a[0];\n        a[0] += a[28];\n        a[28] = xr * wp[-2 * 18 + 7];\n        xr = a[29] - a[1];\n        a[1] += a[29];\n        a[29] = xr * wp[-2 * 18 + 7];\n\n        xr = a[26] - a[2];\n        a[2] += a[26];\n        a[26] = xr * wp[-4 * 18 + 7];\n        xr = a[27] - a[3];\n        a[3] += a[27];\n        a[27] = xr * wp[-4 * 18 + 7];\n\n        xr = a[24] - a[4];\n        a[4] += a[24];\n        a[24] = xr * wp[-6 * 18 + 7];\n        xr = a[25] - a[5];\n        a[5] += a[25];\n        a[25] = xr * wp[-6 * 18 + 7];\n\n        xr = a[22] - a[6];\n        a[6] += a[22];\n        a[22] = xr * SQRT2;\n        xr = a[23] - a[7];\n        a[7] += a[23];\n        a[23] = xr * SQRT2 - a[7];\n        a[7] -= a[6];\n        a[22] -= a[7];\n        a[23] -= a[22];\n\n        xr = a[6];\n        a[6] = a[31] - xr;\n        a[31] = a[31] + xr;\n        xr = a[7];\n        a[7] = a[30] - xr;\n        a[30] = a[30] + xr;\n        xr = a[22];\n        a[22] = a[15] - xr;\n        a[15] = a[15] + xr;\n        xr = a[23];\n        a[23] = a[14] - xr;\n        a[14] = a[14] + xr;\n\n        xr = a[20] - a[8];\n        a[8] += a[20];\n        a[20] = xr * wp[-10 * 18 + 7];\n        xr = a[21] - a[9];\n        a[9] += a[21];\n        a[21] = xr * wp[-10 * 18 + 7];\n\n        xr = a[18] - a[10];\n        a[10] += a[18];\n        a[18] = xr * wp[-12 * 18 + 7];\n        xr = a[19] - a[11];\n        a[11] += a[19];\n        a[19] = xr * wp[-12 * 18 + 7];\n\n        xr = a[16] - a[12];\n        a[12] += a[16];\n        a[16] = xr * wp[-14 * 18 + 7];\n        xr = a[17] - a[13];\n        a[13] += a[17];\n        a[17] = xr * wp[-14 * 18 + 7];\n\n        xr = -a[20] + a[24];\n        a[20] += a[24];\n        a[24] = xr * wp[-12 * 18 + 7];\n        xr = -a[21] + a[25];\n        a[21] += a[25];\n        a[25] = xr * wp[-12 * 18 + 7];\n\n        xr = a[4] - a[8];\n        a[4] += a[8];\n        a[8] = xr * wp[-12 * 18 + 7];\n        xr = a[5] - a[9];\n        a[5] += a[9];\n        a[9] = xr * wp[-12 * 18 + 7];\n\n        xr = a[0] - a[12];\n        a[0] += a[12];\n        a[12] = xr * wp[-4 * 18 + 7];\n        xr = a[1] - a[13];\n        a[1] += a[13];\n        a[13] = xr * wp[-4 * 18 + 7];\n        xr = a[16] - a[28];\n        a[16] += a[28];\n        a[28] = xr * wp[-4 * 18 + 7];\n        xr = -a[17] + a[29];\n        a[17] += a[29];\n        a[29] = xr * wp[-4 * 18 + 7];\n\n        xr = SQRT2 * (a[2] - a[10]);\n        a[2] += a[10];\n        a[10] = xr;\n        xr = SQRT2 * (a[3] - a[11]);\n        a[3] += a[11];\n        a[11] = xr;\n        xr = SQRT2 * (-a[18] + a[26]);\n        a[18] += a[26];\n        a[26] = xr - a[18];\n        xr = SQRT2 * (-a[19] + a[27]);\n        a[19] += a[27];\n        a[27] = xr - a[19];\n\n        xr = a[2];\n        a[19] -= a[3];\n        a[3] -= xr;\n        a[2] = a[31] - xr;\n        a[31] += xr;\n        xr = a[3];\n        a[11] -= a[19];\n        a[18] -= xr;\n        a[3] = a[30] - xr;\n        a[30] += xr;\n        xr = a[18];\n        a[27] -= a[11];\n        a[19] -= xr;\n        a[18] = a[15] - xr;\n        a[15] += xr;\n\n        xr = a[19];\n        a[10] -= xr;\n        a[19] = a[14] - xr;\n        a[14] += xr;\n        xr = a[10];\n        a[11] -= xr;\n        a[10] = a[23] - xr;\n        a[23] += xr;\n        xr = a[11];\n        a[26] -= xr;\n        a[11] = a[22] - xr;\n        a[22] += xr;\n        xr = a[26];\n        a[27] -= xr;\n        a[26] = a[7] - xr;\n        a[7] += xr;\n\n        xr = a[27];\n        a[27] = a[6] - xr;\n        a[6] += xr;\n\n        xr = SQRT2 * (a[0] - a[4]);\n        a[0] += a[4];\n        a[4] = xr;\n        xr = SQRT2 * (a[1] - a[5]);\n        a[1] += a[5];\n        a[5] = xr;\n        xr = SQRT2 * (a[16] - a[20]);\n        a[16] += a[20];\n        a[20] = xr;\n        xr = SQRT2 * (a[17] - a[21]);\n        a[17] += a[21];\n        a[21] = xr;\n\n        xr = -SQRT2 * (a[8] - a[12]);\n        a[8] += a[12];\n        a[12] = xr - a[8];\n        xr = -SQRT2 * (a[9] - a[13]);\n        a[9] += a[13];\n        a[13] = xr - a[9];\n        xr = -SQRT2 * (a[25] - a[29]);\n        a[25] += a[29];\n        a[29] = xr - a[25];\n        xr = -SQRT2 * (a[24] + a[28]);\n        a[24] -= a[28];\n        a[28] = xr - a[24];\n\n        xr = a[24] - a[16];\n        a[24] = xr;\n        xr = a[20] - xr;\n        a[20] = xr;\n        xr = a[28] - xr;\n        a[28] = xr;\n\n        xr = a[25] - a[17];\n        a[25] = xr;\n        xr = a[21] - xr;\n        a[21] = xr;\n        xr = a[29] - xr;\n        a[29] = xr;\n\n        xr = a[17] - a[1];\n        a[17] = xr;\n        xr = a[9] - xr;\n        a[9] = xr;\n        xr = a[25] - xr;\n        a[25] = xr;\n        xr = a[5] - xr;\n        a[5] = xr;\n        xr = a[21] - xr;\n        a[21] = xr;\n        xr = a[13] - xr;\n        a[13] = xr;\n        xr = a[29] - xr;\n        a[29] = xr;\n\n        xr = a[1] - a[0];\n        a[1] = xr;\n        xr = a[16] - xr;\n        a[16] = xr;\n        xr = a[17] - xr;\n        a[17] = xr;\n        xr = a[8] - xr;\n        a[8] = xr;\n        xr = a[9] - xr;\n        a[9] = xr;\n        xr = a[24] - xr;\n        a[24] = xr;\n        xr = a[25] - xr;\n        a[25] = xr;\n        xr = a[4] - xr;\n        a[4] = xr;\n        xr = a[5] - xr;\n        a[5] = xr;\n        xr = a[20] - xr;\n        a[20] = xr;\n        xr = a[21] - xr;\n        a[21] = xr;\n        xr = a[12] - xr;\n        a[12] = xr;\n        xr = a[13] - xr;\n        a[13] = xr;\n        xr = a[28] - xr;\n        a[28] = xr;\n        xr = a[29] - xr;\n        a[29] = xr;\n\n        xr = a[0];\n        a[0] += a[31];\n        a[31] -= xr;\n        xr = a[1];\n        a[1] += a[30];\n        a[30] -= xr;\n        xr = a[16];\n        a[16] += a[15];\n        a[15] -= xr;\n        xr = a[17];\n        a[17] += a[14];\n        a[14] -= xr;\n        xr = a[8];\n        a[8] += a[23];\n        a[23] -= xr;\n        xr = a[9];\n        a[9] += a[22];\n        a[22] -= xr;\n        xr = a[24];\n        a[24] += a[7];\n        a[7] -= xr;\n        xr = a[25];\n        a[25] += a[6];\n        a[6] -= xr;\n        xr = a[4];\n        a[4] += a[27];\n        a[27] -= xr;\n        xr = a[5];\n        a[5] += a[26];\n        a[26] -= xr;\n        xr = a[20];\n        a[20] += a[11];\n        a[11] -= xr;\n        xr = a[21];\n        a[21] += a[10];\n        a[10] -= xr;\n        xr = a[12];\n        a[12] += a[19];\n        a[19] -= xr;\n        xr = a[13];\n        a[13] += a[18];\n        a[18] -= xr;\n        xr = a[28];\n        a[28] += a[3];\n        a[3] -= xr;\n        xr = a[29];\n        a[29] += a[2];\n        a[2] -= xr;\n    }\n\n}\n\n\n/*-------------------------------------------------------------------*/\n/*                                                                   */\n/*   Function: Calculation of the MDCT                               */\n/*   In the case of long blocks (type 0,1,3) there are               */\n/*   36 coefficents in the time domain and 18 in the frequency       */\n/*   domain.                                                         */\n/*   In the case of short blocks (type 2) there are 3                */\n/*   transformations with short length. This leads to 12 coefficents */\n/*   in the time and 6 in the frequency domain. In this case the     */\n/*   results are stored side by side in the vector out[].            */\n/*                                                                   */\n/*   New layer3                                                      */\n/*                                                                   */\n/*-------------------------------------------------------------------*/\n\ninline static void\nmdct_short(FLOAT * inout)\n{\n    int     l;\n    for (l = 0; l < 3; l++) {\n        FLOAT   tc0, tc1, tc2, ts0, ts1, ts2;\n\n        ts0 = inout[2 * 3] * win[SHORT_TYPE][0] - inout[5 * 3];\n        tc0 = inout[0 * 3] * win[SHORT_TYPE][2] - inout[3 * 3];\n        tc1 = ts0 + tc0;\n        tc2 = ts0 - tc0;\n\n        ts0 = inout[5 * 3] * win[SHORT_TYPE][0] + inout[2 * 3];\n        tc0 = inout[3 * 3] * win[SHORT_TYPE][2] + inout[0 * 3];\n        ts1 = ts0 + tc0;\n        ts2 = -ts0 + tc0;\n\n        tc0 = (inout[1 * 3] * win[SHORT_TYPE][1] - inout[4 * 3]) * 2.069978111953089e-11; /* tritab_s[1] */\n        ts0 = (inout[4 * 3] * win[SHORT_TYPE][1] + inout[1 * 3]) * 2.069978111953089e-11; /* tritab_s[1] */\n\n        inout[3 * 0] = tc1 * 1.907525191737280e-11 /* tritab_s[2] */  + tc0;\n        inout[3 * 5] = -ts1 * 1.907525191737280e-11 /* tritab_s[0] */  + ts0;\n\n        tc2 = tc2 * 0.86602540378443870761 * 1.907525191737281e-11 /* tritab_s[2] */ ;\n        ts1 = ts1 * 0.5 * 1.907525191737281e-11 + ts0;\n        inout[3 * 1] = tc2 - ts1;\n        inout[3 * 2] = tc2 + ts1;\n\n        tc1 = tc1 * 0.5 * 1.907525191737281e-11 - tc0;\n        ts2 = ts2 * 0.86602540378443870761 * 1.907525191737281e-11 /* tritab_s[0] */ ;\n        inout[3 * 3] = tc1 + ts2;\n        inout[3 * 4] = tc1 - ts2;\n\n        inout++;\n    }\n}\n\ninline static void\nmdct_long(FLOAT * out, FLOAT const *in)\n{\n    FLOAT   ct, st;\n    {\n        FLOAT   tc1, tc2, tc3, tc4, ts5, ts6, ts7, ts8;\n        /* 1,2, 5,6, 9,10, 13,14, 17 */\n        tc1 = in[17] - in[9];\n        tc3 = in[15] - in[11];\n        tc4 = in[14] - in[12];\n        ts5 = in[0] + in[8];\n        ts6 = in[1] + in[7];\n        ts7 = in[2] + in[6];\n        ts8 = in[3] + in[5];\n\n        out[17] = (ts5 + ts7 - ts8) - (ts6 - in[4]);\n        st = (ts5 + ts7 - ts8) * cx[7] + (ts6 - in[4]);\n        ct = (tc1 - tc3 - tc4) * cx[6];\n        out[5] = ct + st;\n        out[6] = ct - st;\n\n        tc2 = (in[16] - in[10]) * cx[6];\n        ts6 = ts6 * cx[7] + in[4];\n        ct = tc1 * cx[0] + tc2 + tc3 * cx[1] + tc4 * cx[2];\n        st = -ts5 * cx[4] + ts6 - ts7 * cx[5] + ts8 * cx[3];\n        out[1] = ct + st;\n        out[2] = ct - st;\n\n        ct = tc1 * cx[1] - tc2 - tc3 * cx[2] + tc4 * cx[0];\n        st = -ts5 * cx[5] + ts6 - ts7 * cx[3] + ts8 * cx[4];\n        out[9] = ct + st;\n        out[10] = ct - st;\n\n        ct = tc1 * cx[2] - tc2 + tc3 * cx[0] - tc4 * cx[1];\n        st = ts5 * cx[3] - ts6 + ts7 * cx[4] - ts8 * cx[5];\n        out[13] = ct + st;\n        out[14] = ct - st;\n    }\n    {\n        FLOAT   ts1, ts2, ts3, ts4, tc5, tc6, tc7, tc8;\n\n        ts1 = in[8] - in[0];\n        ts3 = in[6] - in[2];\n        ts4 = in[5] - in[3];\n        tc5 = in[17] + in[9];\n        tc6 = in[16] + in[10];\n        tc7 = in[15] + in[11];\n        tc8 = in[14] + in[12];\n\n        out[0] = (tc5 + tc7 + tc8) + (tc6 + in[13]);\n        ct = (tc5 + tc7 + tc8) * cx[7] - (tc6 + in[13]);\n        st = (ts1 - ts3 + ts4) * cx[6];\n        out[11] = ct + st;\n        out[12] = ct - st;\n\n        ts2 = (in[7] - in[1]) * cx[6];\n        tc6 = in[13] - tc6 * cx[7];\n        ct = tc5 * cx[3] - tc6 + tc7 * cx[4] + tc8 * cx[5];\n        st = ts1 * cx[2] + ts2 + ts3 * cx[0] + ts4 * cx[1];\n        out[3] = ct + st;\n        out[4] = ct - st;\n\n        ct = -tc5 * cx[5] + tc6 - tc7 * cx[3] - tc8 * cx[4];\n        st = ts1 * cx[1] + ts2 - ts3 * cx[2] - ts4 * cx[0];\n        out[7] = ct + st;\n        out[8] = ct - st;\n\n        ct = -tc5 * cx[4] + tc6 - tc7 * cx[5] - tc8 * cx[3];\n        st = ts1 * cx[0] - ts2 + ts3 * cx[1] - ts4 * cx[2];\n        out[15] = ct + st;\n        out[16] = ct - st;\n    }\n}\n\n\nvoid\nmdct_sub48(lame_internal_flags * gfc, const sample_t * w0, const sample_t * w1)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    EncStateVar_t *const esv = &gfc->sv_enc;\n    int     gr, k, ch;\n    const sample_t *wk;\n\n    wk = w0 + 286;\n    /* thinking cache performance, ch->gr loop is better than gr->ch loop */\n    for (ch = 0; ch < cfg->channels_out; ch++) {\n        for (gr = 0; gr < cfg->mode_gr; gr++) {\n            int     band;\n            gr_info *const gi = &(gfc->l3_side.tt[gr][ch]);\n            FLOAT  *mdct_enc = gi->xr;\n            FLOAT  *samp = esv->sb_sample[ch][1 - gr][0];\n\n            for (k = 0; k < 18 / 2; k++) {\n                window_subband(wk, samp);\n                window_subband(wk + 32, samp + 32);\n                samp += 64;\n                wk += 64;\n                /*\n                 * Compensate for inversion in the analysis filter\n                 */\n                for (band = 1; band < 32; band += 2) {\n                    samp[band - 32] *= -1;\n                }\n            }\n\n            /*\n             * Perform imdct of 18 previous subband samples\n             * + 18 current subband samples\n             */\n            for (band = 0; band < 32; band++, mdct_enc += 18) {\n                int     type = gi->block_type;\n                FLOAT const *const band0 = esv->sb_sample[ch][gr][0] + order[band];\n                FLOAT  *const band1 = esv->sb_sample[ch][1 - gr][0] + order[band];\n                if (gi->mixed_block_flag && band < 2)\n                    type = 0;\n                if (esv->amp_filter[band] < 1e-12) {\n                    memset(mdct_enc, 0, 18 * sizeof(FLOAT));\n                }\n                else {\n                    if (esv->amp_filter[band] < 1.0) {\n                        for (k = 0; k < 18; k++)\n                            band1[k * 32] *= esv->amp_filter[band];\n                    }\n                    if (type == SHORT_TYPE) {\n                        for (k = -NS / 4; k < 0; k++) {\n                            FLOAT const w = win[SHORT_TYPE][k + 3];\n                            mdct_enc[k * 3 + 9] = band0[(9 + k) * 32] * w - band0[(8 - k) * 32];\n                            mdct_enc[k * 3 + 18] = band0[(14 - k) * 32] * w + band0[(15 + k) * 32];\n                            mdct_enc[k * 3 + 10] = band0[(15 + k) * 32] * w - band0[(14 - k) * 32];\n                            mdct_enc[k * 3 + 19] = band1[(2 - k) * 32] * w + band1[(3 + k) * 32];\n                            mdct_enc[k * 3 + 11] = band1[(3 + k) * 32] * w - band1[(2 - k) * 32];\n                            mdct_enc[k * 3 + 20] = band1[(8 - k) * 32] * w + band1[(9 + k) * 32];\n                        }\n                        mdct_short(mdct_enc);\n                    }\n                    else {\n                        FLOAT   work[18];\n                        for (k = -NL / 4; k < 0; k++) {\n                            FLOAT   a, b;\n                            a = win[type][k + 27] * band1[(k + 9) * 32]\n                                + win[type][k + 36] * band1[(8 - k) * 32];\n                            b = win[type][k + 9] * band0[(k + 9) * 32]\n                                - win[type][k + 18] * band0[(8 - k) * 32];\n                            work[k + 9] = a - b * tantab_l[k + 9];\n                            work[k + 18] = a * tantab_l[k + 9] + b;\n                        }\n\n                        mdct_long(mdct_enc, work);\n                    }\n                }\n                /*\n                 * Perform aliasing reduction butterfly\n                 */\n                if (type != SHORT_TYPE && band != 0) {\n                    for (k = 7; k >= 0; --k) {\n                        FLOAT   bu, bd;\n                        bu = mdct_enc[k] * ca[k] + mdct_enc[-1 - k] * cs[k];\n                        bd = mdct_enc[k] * cs[k] - mdct_enc[-1 - k] * ca[k];\n\n                        mdct_enc[-1 - k] = bu;\n                        mdct_enc[k] = bd;\n                    }\n                }\n            }\n        }\n        wk = w1 + 286;\n        if (cfg->mode_gr == 1) {\n            memcpy(esv->sb_sample[ch][0], esv->sb_sample[ch][1], 576 * sizeof(FLOAT));\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/newmdct.h",
    "content": "/*\n *\tNew Modified DCT include file\n *\n *\tCopyright (c) 1999 Takehiro TOMINAGA\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\t See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n#ifndef LAME_NEWMDCT_H\n#define LAME_NEWMDCT_H\n\nvoid    mdct_sub48(lame_internal_flags * gfc, const sample_t * w0, const sample_t * w1);\n\n#endif /* LAME_NEWMDCT_H */\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/presets.c",
    "content": "/*\n * presets.c -- Apply presets\n *\n *\tCopyright (c) 2002-2008 Gabriel Bouvigne\n *\tCopyright (c) 2007-2011 Robert Hegemann\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.\n */\n\n\n#ifdef HAVE_CONFIG_H\n# include <config.h>\n#endif\n\n#include \"lame.h\"\n#include \"machine.h\"\n#include \"set_get.h\"\n#include \"encoder.h\"\n#include \"util.h\"\n#include \"lame_global_flags.h\"\n\n#define SET_OPTION(opt, val, def) if (enforce) \\\n    (void) lame_set_##opt(gfp, val); \\\n    else if (!(fabs(lame_get_##opt(gfp) - def) > 0)) \\\n    (void) lame_set_##opt(gfp, val);\n\n#define SET__OPTION(opt, val, def) if (enforce) \\\n    lame_set_##opt(gfp, val); \\\n    else if (!(fabs(lame_get_##opt(gfp) - def) > 0)) \\\n    lame_set_##opt(gfp, val);\n\n#undef Min\n#undef Max\n\nstatic inline int\nmin_int(int a, int b)\n{\n    if (a < b) {\n        return a;\n    }\n    return b;\n}\n\nstatic inline int\nmax_int(int a, int b)\n{\n    if (a > b) {\n        return a;\n    }\n    return b;\n}\n\n\n\ntypedef struct {\n    int     vbr_q;\n    int     quant_comp;\n    int     quant_comp_s;\n    int     expY;\n    FLOAT   st_lrm;          /*short threshold */\n    FLOAT   st_s;\n    FLOAT   masking_adj;\n    FLOAT   masking_adj_short;\n    FLOAT   ath_lower;\n    FLOAT   ath_curve;\n    FLOAT   ath_sensitivity;\n    FLOAT   interch;\n    int     safejoint;\n    int     sfb21mod;\n    FLOAT   msfix;\n    FLOAT   minval;\n    FLOAT   ath_fixpoint;\n} vbr_presets_t;\n\n    /* *INDENT-OFF* */\n    \n    /* Switch mappings for VBR mode VBR_RH */\n    static const vbr_presets_t vbr_old_switch_map[] = {\n    /*vbr_q  qcomp_l  qcomp_s  expY  st_lrm   st_s  mask adj_l  adj_s  ath_lower  ath_curve  ath_sens  interChR  safejoint sfb21mod  msfix */\n        {0,       9,       9,    0,   5.20, 125.0,      -4.2,   -6.3,       4.8,       1,          0,   0,              2,      21,  0.97, 5, 100},\n        {1,       9,       9,    0,   5.30, 125.0,      -3.6,   -5.6,       4.5,       1.5,        0,   0,              2,      21,  1.35, 5, 100},\n        {2,       9,       9,    0,   5.60, 125.0,      -2.2,   -3.5,       2.8,       2,          0,   0,              2,      21,  1.49, 5, 100},\n        {3,       9,       9,    1,   5.80, 130.0,      -1.8,   -2.8,       2.6,       3,         -4,   0,              2,      20,  1.64, 5, 100},\n        {4,       9,       9,    1,   6.00, 135.0,      -0.7,   -1.1,       1.1,       3.5,       -8,   0,              2,       0,  1.79, 5, 100},\n        {5,       9,       9,    1,   6.40, 140.0,       0.5,    0.4,      -7.5,       4,        -12,   0.0002,         0,       0,  1.95, 5, 100},\n        {6,       9,       9,    1,   6.60, 145.0,       0.67,   0.65,    -14.7,       6.5,      -19,   0.0004,         0,       0,  2.30, 5, 100},\n        {7,       9,       9,    1,   6.60, 145.0,       0.8,    0.75,    -19.7,       8,        -22,   0.0006,         0,       0,  2.70, 5, 100},\n        {8,       9,       9,    1,   6.60, 145.0,       1.2,    1.15,    -27.5,      10,        -23,   0.0007,         0,       0,  0,    5, 100},\n        {9,       9,       9,    1,   6.60, 145.0,       1.6,    1.6,     -36,        11,        -25,   0.0008,         0,       0,  0,    5, 100},\n        {10,      9,       9,    1,   6.60, 145.0,       2.0,    2.0,     -36,        12,        -25,   0.0008,         0,       0,  0,    5, 100}\n    };\n    \n    static const vbr_presets_t vbr_mt_psy_switch_map[] = {\n    /*vbr_q  qcomp_l  qcomp_s  expY  st_lrm   st_s  mask adj_l  adj_s  ath_lower  ath_curve  ath_sens  ---  safejoint sfb21mod  msfix */\n        {0,       9,       9,    0,   4.20,  25.0,      -6.8,   -6.8,       7.1,       1,          0,   0,         2,      31,  1.000,  5, 100},\n        {1,       9,       9,    0,   4.20,  25.0,      -4.8,   -4.8,       5.4,       1.4,       -1,   0,         2,      27,  1.122,  5,  98},\n        {2,       9,       9,    0,   4.20,  25.0,      -2.6,   -2.6,       3.7,       2.0,       -3,   0,         2,      23,  1.288,  5,  97},\n        {3,       9,       9,    1,   4.20,  25.0,      -1.6,   -1.6,       2.0,       2.0,       -5,   0,         2,      18,  1.479,  5,  96},\n        {4,       9,       9,    1,   4.20,  25.0,      -0.0,   -0.0,       0.0,       2.0,       -8,   0,         2,      12,  1.698,  5,  95},\n        {5,       9,       9,    1,   4.20,  25.0,       1.3,    1.3,      -6,         3.5,      -11,   0,         2,       8,  1.950,  5,  94.2},\n#if 0\n        {6,       9,       9,    1,   4.50, 100.0,       1.5,    1.5,     -24.0,       6.0,      -14,   0,         2,       4,  2.239,  3,  93.9},\n        {7,       9,       9,    1,   4.80, 200.0,       1.7,    1.7,     -28.0,       9.0,      -20,   0,         2,       0,  2.570,  1,  93.6},\n#else\n        {6,       9,       9,    1,   4.50, 100.0,       2.2,    2.3,     -12.0,       6.0,      -14,   0,         2,       4,  2.239,  3,  93.9},\n        {7,       9,       9,    1,   4.80, 200.0,       2.7,    2.7,     -18.0,       9.0,      -17,   0,         2,       0,  2.570,  1,  93.6},\n#endif\n        {8,       9,       9,    1,   5.30, 300.0,       2.8,    2.8,     -21.0,      10.0,      -23,   0.0002,    0,       0,  2.951,  0,  93.3},\n        {9,       9,       9,    1,   6.60, 300.0,       2.8,    2.8,     -23.0,      11.0,      -25,   0.0006,    0,       0,  3.388,  0,  93.3},\n        {10,      9,       9,    1,  25.00, 300.0,       2.8,    2.8,     -25.0,      12.0,      -27,   0.0025,    0,       0,  3.500,  0,  93.3}\n    };\n\n    /* *INDENT-ON* */\n\nstatic vbr_presets_t const*\nget_vbr_preset(int v)\n{\n    switch (v) {\n    case vbr_mtrh:\n    case vbr_mt:\n        return &vbr_mt_psy_switch_map[0];\n    default:\n        return &vbr_old_switch_map[0];\n    }\n}\n\n#define NOOP(m) (void)p.m\n#define LERP(m) (p.m = p.m + x * (q.m - p.m))\n\nstatic void\napply_vbr_preset(lame_global_flags * gfp, int a, int enforce)\n{\n    vbr_presets_t const *vbr_preset = get_vbr_preset(lame_get_VBR(gfp));\n    float   x = gfp->VBR_q_frac;\n    vbr_presets_t p = vbr_preset[a];\n    vbr_presets_t q = vbr_preset[a + 1];\n    vbr_presets_t const *set = &p;\n\n    NOOP(vbr_q);\n    NOOP(quant_comp);\n    NOOP(quant_comp_s);\n    NOOP(expY);\n    LERP(st_lrm);\n    LERP(st_s);\n    LERP(masking_adj);\n    LERP(masking_adj_short);\n    LERP(ath_lower);\n    LERP(ath_curve);\n    LERP(ath_sensitivity);\n    LERP(interch);\n    NOOP(safejoint);\n    LERP(sfb21mod);\n    LERP(msfix);\n    LERP(minval);\n    LERP(ath_fixpoint);\n\n    (void) lame_set_VBR_q(gfp, set->vbr_q);\n    SET_OPTION(quant_comp, set->quant_comp, -1);\n    SET_OPTION(quant_comp_short, set->quant_comp_s, -1);\n    if (set->expY) {\n        (void) lame_set_experimentalY(gfp, set->expY);\n    }\n    SET_OPTION(short_threshold_lrm, set->st_lrm, -1);\n    SET_OPTION(short_threshold_s, set->st_s, -1);\n    SET_OPTION(maskingadjust, set->masking_adj, 0);\n    SET_OPTION(maskingadjust_short, set->masking_adj_short, 0);\n    if (lame_get_VBR(gfp) == vbr_mt || lame_get_VBR(gfp) == vbr_mtrh) {\n        lame_set_ATHtype(gfp, 5);\n    }\n    SET_OPTION(ATHlower, set->ath_lower, 0);\n    SET_OPTION(ATHcurve, set->ath_curve, -1);\n    SET_OPTION(athaa_sensitivity, set->ath_sensitivity, 0);\n    if (set->interch > 0) {\n        SET_OPTION(interChRatio, set->interch, -1);\n    }\n\n    /* parameters for which there is no proper set/get interface */\n    if (set->safejoint > 0) {\n        (void) lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 2);\n    }\n    if (set->sfb21mod > 0) {\n        int const nsp = lame_get_exp_nspsytune(gfp);\n        int const val = (nsp >> 20) & 63;\n        if (val == 0) {\n            int const sf21mod = (set->sfb21mod << 20) | nsp;\n            (void) lame_set_exp_nspsytune(gfp, sf21mod);\n        }\n    }\n    SET__OPTION(msfix, set->msfix, -1);\n\n    if (enforce == 0) {\n        gfp->VBR_q = a;\n        gfp->VBR_q_frac = x;\n    }\n    gfp->internal_flags->cfg.minval = set->minval;\n    gfp->internal_flags->cfg.ATHfixpoint = set->ath_fixpoint;\n}\n\nstatic int\napply_abr_preset(lame_global_flags * gfp, int preset, int enforce)\n{\n    typedef struct {\n        int     abr_kbps;\n        int     quant_comp;\n        int     quant_comp_s;\n        int     safejoint;\n        FLOAT   nsmsfix;\n        FLOAT   st_lrm;      /*short threshold */\n        FLOAT   st_s;\n        FLOAT   scale;\n        FLOAT   masking_adj;\n        FLOAT   ath_lower;\n        FLOAT   ath_curve;\n        FLOAT   interch;\n        int     sfscale;\n    } abr_presets_t;\n\n\n    /* *INDENT-OFF* */\n\n    /* \n     *  Switch mappings for ABR mode\n     */\n    const abr_presets_t abr_switch_map[] = {        \n    /* kbps  quant q_s safejoint nsmsfix st_lrm  st_s  scale   msk ath_lwr ath_curve  interch , sfscale */\n      {  8,     9,  9,        0,      0,  6.60,  145,  0.95,    0,  -30.0,     11,    0.0012,        1}, /*   8, impossible to use in stereo */\n      { 16,     9,  9,        0,      0,  6.60,  145,  0.95,    0,  -25.0,     11,    0.0010,        1}, /*  16 */\n      { 24,     9,  9,        0,      0,  6.60,  145,  0.95,    0,  -20.0,     11,    0.0010,        1}, /*  24 */\n      { 32,     9,  9,        0,      0,  6.60,  145,  0.95,    0,  -15.0,     11,    0.0010,        1}, /*  32 */\n      { 40,     9,  9,        0,      0,  6.60,  145,  0.95,    0,  -10.0,     11,    0.0009,        1}, /*  40 */\n      { 48,     9,  9,        0,      0,  6.60,  145,  0.95,    0,  -10.0,     11,    0.0009,        1}, /*  48 */\n      { 56,     9,  9,        0,      0,  6.60,  145,  0.95,    0,   -6.0,     11,    0.0008,        1}, /*  56 */\n      { 64,     9,  9,        0,      0,  6.60,  145,  0.95,    0,   -2.0,     11,    0.0008,        1}, /*  64 */\n      { 80,     9,  9,        0,      0,  6.60,  145,  0.95,    0,     .0,      8,    0.0007,        1}, /*  80 */\n      { 96,     9,  9,        0,   2.50,  6.60,  145,  0.95,    0,    1.0,      5.5,  0.0006,        1}, /*  96 */\n      {112,     9,  9,        0,   2.25,  6.60,  145,  0.95,    0,    2.0,      4.5,  0.0005,        1}, /* 112 */\n      {128,     9,  9,        0,   1.95,  6.40,  140,  0.95,    0,    3.0,      4,    0.0002,        1}, /* 128 */\n      {160,     9,  9,        1,   1.79,  6.00,  135,  0.95,   -2,    5.0,      3.5,  0,             1}, /* 160 */\n      {192,     9,  9,        1,   1.49,  5.60,  125,  0.97,   -4,    7.0,      3,    0,             0}, /* 192 */\n      {224,     9,  9,        1,   1.25,  5.20,  125,  0.98,   -6,    9.0,      2,    0,             0}, /* 224 */\n      {256,     9,  9,        1,   0.97,  5.20,  125,  1.00,   -8,   10.0,      1,    0,             0}, /* 256 */\n      {320,     9,  9,        1,   0.90,  5.20,  125,  1.00,  -10,   12.0,      0,    0,             0}  /* 320 */\n    };\n\n    /* *INDENT-ON* */\n\n    /* Variables for the ABR stuff */\n    int     r;\n    int     actual_bitrate = preset;\n\n    r = nearestBitrateFullIndex(preset);\n    \n    (void) lame_set_VBR(gfp, vbr_abr);\n    (void) lame_set_VBR_mean_bitrate_kbps(gfp, (actual_bitrate));\n    (void) lame_set_VBR_mean_bitrate_kbps(gfp, min_int(lame_get_VBR_mean_bitrate_kbps(gfp), 320));\n    (void) lame_set_VBR_mean_bitrate_kbps(gfp, max_int(lame_get_VBR_mean_bitrate_kbps(gfp), 8));\n    (void) lame_set_brate(gfp, lame_get_VBR_mean_bitrate_kbps(gfp));\n\n\n    /* parameters for which there is no proper set/get interface */\n    if (abr_switch_map[r].safejoint > 0)\n        (void) lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 2); /* safejoint */\n\n    if (abr_switch_map[r].sfscale > 0)\n        (void) lame_set_sfscale(gfp, 1);\n\n\n    SET_OPTION(quant_comp, abr_switch_map[r].quant_comp, -1);\n    SET_OPTION(quant_comp_short, abr_switch_map[r].quant_comp_s, -1);\n\n    SET__OPTION(msfix, abr_switch_map[r].nsmsfix, -1);\n\n    SET_OPTION(short_threshold_lrm, abr_switch_map[r].st_lrm, -1);\n    SET_OPTION(short_threshold_s, abr_switch_map[r].st_s, -1);\n\n    /* ABR seems to have big problems with clipping, especially at low bitrates */\n    /* so we compensate for that here by using a scale value depending on bitrate */\n    lame_set_scale(gfp, lame_get_scale(gfp) * abr_switch_map[r].scale);\n\n    SET_OPTION(maskingadjust, abr_switch_map[r].masking_adj, 0);\n    if (abr_switch_map[r].masking_adj > 0) {\n        SET_OPTION(maskingadjust_short, abr_switch_map[r].masking_adj * .9, 0);\n    }\n    else {\n        SET_OPTION(maskingadjust_short, abr_switch_map[r].masking_adj * 1.1, 0);\n    }\n\n\n    SET_OPTION(ATHlower, abr_switch_map[r].ath_lower, 0);\n    SET_OPTION(ATHcurve, abr_switch_map[r].ath_curve, -1);\n\n    SET_OPTION(interChRatio, abr_switch_map[r].interch, -1);\n\n    (void) abr_switch_map[r].abr_kbps;\n\n    gfp->internal_flags->cfg.minval = 5. * (abr_switch_map[r].abr_kbps / 320.);\n\n    return preset;\n}\n\n\n\nint\napply_preset(lame_global_flags * gfp, int preset, int enforce)\n{\n    /*translate legacy presets */\n    switch (preset) {\n    case R3MIX:\n        {\n            preset = V3;\n            (void) lame_set_VBR(gfp, vbr_mtrh);\n            break;\n        }\n    case MEDIUM:\n    case MEDIUM_FAST:\n        {\n            preset = V4;\n            (void) lame_set_VBR(gfp, vbr_mtrh);\n            break;\n        }\n    case STANDARD:\n    case STANDARD_FAST:\n        {\n            preset = V2;\n            (void) lame_set_VBR(gfp, vbr_mtrh);\n            break;\n        }\n    case EXTREME:\n    case EXTREME_FAST:\n        {\n            preset = V0;\n            (void) lame_set_VBR(gfp, vbr_mtrh);\n            break;\n        }\n    case INSANE:\n        {\n            preset = 320;\n            gfp->preset = preset;\n            (void) apply_abr_preset(gfp, preset, enforce);\n            lame_set_VBR(gfp, vbr_off);\n            return preset;\n        }\n    }\n\n    gfp->preset = preset;\n    {\n        switch (preset) {\n        case V9:\n            apply_vbr_preset(gfp, 9, enforce);\n            return preset;\n        case V8:\n            apply_vbr_preset(gfp, 8, enforce);\n            return preset;\n        case V7:\n            apply_vbr_preset(gfp, 7, enforce);\n            return preset;\n        case V6:\n            apply_vbr_preset(gfp, 6, enforce);\n            return preset;\n        case V5:\n            apply_vbr_preset(gfp, 5, enforce);\n            return preset;\n        case V4:\n            apply_vbr_preset(gfp, 4, enforce);\n            return preset;\n        case V3:\n            apply_vbr_preset(gfp, 3, enforce);\n            return preset;\n        case V2:\n            apply_vbr_preset(gfp, 2, enforce);\n            return preset;\n        case V1:\n            apply_vbr_preset(gfp, 1, enforce);\n            return preset;\n        case V0:\n            apply_vbr_preset(gfp, 0, enforce);\n            return preset;\n        default:\n            break;\n        }\n    }\n    if (8 <= preset && preset <= 320) {\n        return apply_abr_preset(gfp, preset, enforce);\n    }\n\n    gfp->preset = 0;    /*no corresponding preset found */\n    return preset;\n}\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/psymodel.c",
    "content": "/*\n *      psymodel.c\n *\n *      Copyright (c) 1999-2000 Mark Taylor\n *      Copyright (c) 2001-2002 Naoki Shibata\n *      Copyright (c) 2000-2003 Takehiro Tominaga\n *      Copyright (c) 2000-2011 Robert Hegemann\n *      Copyright (c) 2000-2005 Gabriel Bouvigne\n *      Copyright (c) 2000-2005 Alexander Leidinger\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n/* $Id: psymodel.c,v 1.209 2011/05/24 20:45:55 robert Exp $ */\n\n\n/*\nPSYCHO ACOUSTICS\n\n\nThis routine computes the psycho acoustics, delayed by one granule.  \n\nInput: buffer of PCM data (1024 samples).  \n\nThis window should be centered over the 576 sample granule window.\nThe routine will compute the psycho acoustics for\nthis granule, but return the psycho acoustics computed\nfor the *previous* granule.  This is because the block\ntype of the previous granule can only be determined\nafter we have computed the psycho acoustics for the following\ngranule.  \n\nOutput:  maskings and energies for each scalefactor band.\nblock type, PE, and some correlation measures.  \nThe PE is used by CBR modes to determine if extra bits\nfrom the bit reservoir should be used.  The correlation\nmeasures are used to determine mid/side or regular stereo.\n*/\n/*\nNotation:\n\nbarks:  a non-linear frequency scale.  Mapping from frequency to\n        barks is given by freq2bark()\n\nscalefactor bands: The spectrum (frequencies) are broken into \n                   SBMAX \"scalefactor bands\".  Thes bands\n                   are determined by the MPEG ISO spec.  In\n                   the noise shaping/quantization code, we allocate\n                   bits among the partition bands to achieve the\n                   best possible quality\n\npartition bands:   The spectrum is also broken into about\n                   64 \"partition bands\".  Each partition \n                   band is about .34 barks wide.  There are about 2-5\n                   partition bands for each scalefactor band.\n\nLAME computes all psycho acoustic information for each partition\nband.  Then at the end of the computations, this information\nis mapped to scalefactor bands.  The energy in each scalefactor\nband is taken as the sum of the energy in all partition bands\nwhich overlap the scalefactor band.  The maskings can be computed\nin the same way (and thus represent the average masking in that band)\nor by taking the minmum value multiplied by the number of\npartition bands used (which represents a minimum masking in that band).\n*/\n/*\nThe general outline is as follows:\n\n1. compute the energy in each partition band\n2. compute the tonality in each partition band\n3. compute the strength of each partion band \"masker\"\n4. compute the masking (via the spreading function applied to each masker)\n5. Modifications for mid/side masking.  \n\nEach partition band is considiered a \"masker\".  The strength\nof the i'th masker in band j is given by:\n\n    s3(bark(i)-bark(j))*strength(i)\n\nThe strength of the masker is a function of the energy and tonality.\nThe more tonal, the less masking.  LAME uses a simple linear formula\n(controlled by NMT and TMN) which says the strength is given by the\nenergy divided by a linear function of the tonality.\n*/\n/*\ns3() is the \"spreading function\".  It is given by a formula\ndetermined via listening tests.  \n\nThe total masking in the j'th partition band is the sum over\nall maskings i.  It is thus given by the convolution of\nthe strength with s3(), the \"spreading function.\"\n\nmasking(j) = sum_over_i  s3(i-j)*strength(i)  = s3 o strength\n\nwhere \"o\" = convolution operator.  s3 is given by a formula determined\nvia listening tests.  It is normalized so that s3 o 1 = 1.\n\nNote: instead of a simple convolution, LAME also has the\noption of using \"additive masking\"\n\nThe most critical part is step 2, computing the tonality of each\npartition band.  LAME has two tonality estimators.  The first\nis based on the ISO spec, and measures how predictiable the\nsignal is over time.  The more predictable, the more tonal.\nThe second measure is based on looking at the spectrum of\na single granule.  The more peaky the spectrum, the more\ntonal.  By most indications, the latter approach is better.\n\nFinally, in step 5, the maskings for the mid and side\nchannel are possibly increased.  Under certain circumstances,\nnoise in the mid & side channels is assumed to also\nbe masked by strong maskers in the L or R channels.\n\n\nOther data computed by the psy-model:\n\nms_ratio        side-channel / mid-channel masking ratio (for previous granule)\nms_ratio_next   side-channel / mid-channel masking ratio for this granule\n\npercep_entropy[2]     L and R values (prev granule) of PE - A measure of how \n                      much pre-echo is in the previous granule\npercep_entropy_MS[2]  mid and side channel values (prev granule) of percep_entropy\nenergy[4]             L,R,M,S energy in each channel, prev granule\nblocktype_d[2]        block type to use for previous granule\n*/\n\n\n\n\n#ifdef HAVE_CONFIG_H\n# include <config.h>\n#endif\n\n#include \"lame.h\"\n#include \"machine.h\"\n#include \"encoder.h\"\n#include \"util.h\"\n#include \"psymodel.h\"\n#include \"lame_global_flags.h\"\n#include \"fft.h\"\n#include \"lame-analysis.h\"\n\n\n#define NSFIRLEN 21\n\n#ifdef M_LN10\n#define  LN_TO_LOG10  (M_LN10/10)\n#else\n#define  LN_TO_LOG10  0.2302585093\n#endif\n\n\n/*\n   L3psycho_anal.  Compute psycho acoustics.\n\n   Data returned to the calling program must be delayed by one \n   granule. \n\n   This is done in two places.  \n   If we do not need to know the blocktype, the copying\n   can be done here at the top of the program: we copy the data for\n   the last granule (computed during the last call) before it is\n   overwritten with the new data.  It looks like this:\n  \n   0. static psymodel_data \n   1. calling_program_data = psymodel_data\n   2. compute psymodel_data\n    \n   For data which needs to know the blocktype, the copying must be\n   done at the end of this loop, and the old values must be saved:\n   \n   0. static psymodel_data_old \n   1. compute psymodel_data\n   2. compute possible block type of this granule\n   3. compute final block type of previous granule based on #2.\n   4. calling_program_data = psymodel_data_old\n   5. psymodel_data_old = psymodel_data\n*/\n\n\n\n\n\n/* psycho_loudness_approx\n   jd - 2001 mar 12\nin:  energy   - BLKSIZE/2 elements of frequency magnitudes ^ 2\n     gfp      - uses out_samplerate, ATHtype (also needed for ATHformula)\nreturns: loudness^2 approximation, a positive value roughly tuned for a value\n         of 1.0 for signals near clipping.\nnotes:   When calibrated, feeding this function binary white noise at sample\n         values +32767 or -32768 should return values that approach 3.\n         ATHformula is used to approximate an equal loudness curve.\nfuture:  Data indicates that the shape of the equal loudness curve varies\n         with intensity.  This function might be improved by using an equal\n         loudness curve shaped for typical playback levels (instead of the\n         ATH, that is shaped for the threshold).  A flexible realization might\n         simply bend the existing ATH curve to achieve the desired shape.\n         However, the potential gain may not be enough to justify an effort.\n*/\nstatic  FLOAT\npsycho_loudness_approx(FLOAT const *energy, FLOAT const *eql_w)\n{\n    int     i;\n    FLOAT   loudness_power;\n\n    loudness_power = 0.0;\n    /* apply weights to power in freq. bands */\n    for (i = 0; i < BLKSIZE / 2; ++i)\n        loudness_power += energy[i] * eql_w[i];\n    loudness_power *= VO_SCALE;\n\n    return loudness_power;\n}\n\n/* mask_add optimization */\n/* init the limit values used to avoid computing log in mask_add when it is not necessary */\n\n/* For example, with i = 10*log10(m2/m1)/10*16         (= log10(m2/m1)*16)\n *\n * abs(i)>8 is equivalent (as i is an integer) to\n * abs(i)>=9\n * i>=9 || i<=-9\n * equivalent to (as i is the biggest integer smaller than log10(m2/m1)*16 \n * or the smallest integer bigger than log10(m2/m1)*16 depending on the sign of log10(m2/m1)*16)\n * log10(m2/m1)>=9/16 || log10(m2/m1)<=-9/16\n * exp10 is strictly increasing thus this is equivalent to\n * m2/m1 >= 10^(9/16) || m2/m1<=10^(-9/16) which are comparisons to constants\n */\n\n\n#define I1LIMIT 8       /* as in if(i>8)  */\n#define I2LIMIT 23      /* as in if(i>24) -> changed 23 */\n#define MLIMIT  15      /* as in if(m<15) */\n\nstatic FLOAT ma_max_i1;\nstatic FLOAT ma_max_i2;\nstatic FLOAT ma_max_m;\n\n    /*This is the masking table:\n       According to tonality, values are going from 0dB (TMN)\n       to 9.3dB (NMT).\n       After additive masking computation, 8dB are added, so\n       final values are going from 8dB to 17.3dB\n     */\nstatic const FLOAT tab[] = {\n    1.0 /*pow(10, -0) */ ,\n    0.79433 /*pow(10, -0.1) */ ,\n    0.63096 /*pow(10, -0.2) */ ,\n    0.63096 /*pow(10, -0.2) */ ,\n    0.63096 /*pow(10, -0.2) */ ,\n    0.63096 /*pow(10, -0.2) */ ,\n    0.63096 /*pow(10, -0.2) */ ,\n    0.25119 /*pow(10, -0.6) */ ,\n    0.11749             /*pow(10, -0.93) */\n};\n\nstatic const int tab_mask_add_delta[] = { 2, 2, 2, 1, 1, 1, 0, 0, -1 };\n#define STATIC_ASSERT_EQUAL_DIMENSION(A,B) {extern char static_assert_##A[dimension_of(A) == dimension_of(B) ? 1 : -1];(void) static_assert_##A;}\n\ninline static int\nmask_add_delta(int i)\n{\n    STATIC_ASSERT_EQUAL_DIMENSION(tab_mask_add_delta,tab);\n    assert(i < (int)dimension_of(tab));\n    return tab_mask_add_delta[i];\n}\n\n\nstatic void\ninit_mask_add_max_values(void)\n{\n    ma_max_i1 = pow(10, (I1LIMIT + 1) / 16.0);\n    ma_max_i2 = pow(10, (I2LIMIT + 1) / 16.0);\n    ma_max_m = pow(10, (MLIMIT) / 10.0);\n}\n\n\n\n\n/* addition of simultaneous masking   Naoki Shibata 2000/7 */\ninline static FLOAT\nvbrpsy_mask_add(FLOAT m1, FLOAT m2, int b, int delta)\n{\n    static const FLOAT table2[] = {\n        1.33352 * 1.33352, 1.35879 * 1.35879, 1.38454 * 1.38454, 1.39497 * 1.39497,\n        1.40548 * 1.40548, 1.3537 * 1.3537, 1.30382 * 1.30382, 1.22321 * 1.22321,\n        1.14758 * 1.14758,\n        1\n    };\n\n    FLOAT   ratio;\n\n    if (m1 < 0) {\n        m1 = 0;\n    }\n    if (m2 < 0) {\n        m2 = 0;\n    }\n    if (m1 <= 0) {\n        return m2;\n    }\n    if (m2 <= 0) {\n        return m1;\n    }\n    if (m2 > m1) {\n        ratio = m2 / m1;\n    }\n    else {\n        ratio = m1 / m2;\n    }\n    if (abs(b) <= delta) {       /* approximately, 1 bark = 3 partitions */\n        /* originally 'if(i > 8)' */\n        if (ratio >= ma_max_i1) {\n            return m1 + m2;\n        }\n        else {\n            int     i = (int) (FAST_LOG10_X(ratio, 16.0f));\n            return (m1 + m2) * table2[i];\n        }\n    }\n    if (ratio < ma_max_i2) {\n        return m1 + m2;\n    }\n    if (m1 < m2) {\n        m1 = m2;\n    }\n    return m1;\n}\n\n\n/* short block threshold calculation (part 2)\n\n    partition band bo_s[sfb] is at the transition from scalefactor\n    band sfb to the next one sfb+1; enn and thmm have to be split\n    between them\n*/\nstatic void\nconvert_partition2scalefac(PsyConst_CB2SB_t const *const gd, FLOAT const *eb, FLOAT const *thr,\n                           FLOAT enn_out[], FLOAT thm_out[])\n{\n    FLOAT   enn, thmm;\n    int     sb, b, n = gd->n_sb;\n    enn = thmm = 0.0f;\n    for (sb = b = 0; sb < n; ++b, ++sb) {\n        int const bo_sb = gd->bo[sb];\n        int const npart = gd->npart;\n        int const b_lim = bo_sb < npart ? bo_sb : npart;\n        while (b < b_lim) {\n            assert(eb[b] >= 0); /* iff failed, it may indicate some index error elsewhere */\n            assert(thr[b] >= 0);\n            enn += eb[b];\n            thmm += thr[b];\n            b++;\n        }\n        if (b >= npart) {\n            enn_out[sb] = enn;\n            thm_out[sb] = thmm;\n            ++sb;\n            break;\n        }\n        assert(eb[b] >= 0); /* iff failed, it may indicate some index error elsewhere */\n        assert(thr[b] >= 0);\n        {\n            /* at transition sfb -> sfb+1 */\n            FLOAT const w_curr = gd->bo_weight[sb];\n            FLOAT const w_next = 1.0f - w_curr;\n            enn += w_curr * eb[b];\n            thmm += w_curr * thr[b];\n            enn_out[sb] = enn;\n            thm_out[sb] = thmm;\n            enn = w_next * eb[b];\n            thmm = w_next * thr[b];\n        }\n    }\n    /* zero initialize the rest */\n    for (; sb < n; ++sb) {\n        enn_out[sb] = 0;\n        thm_out[sb] = 0;\n    }\n}\n\nstatic void\nconvert_partition2scalefac_s(lame_internal_flags * gfc, FLOAT const *eb, FLOAT const *thr, int chn,\n                             int sblock)\n{\n    PsyStateVar_t *const psv = &gfc->sv_psy;\n    PsyConst_CB2SB_t const *const gds = &gfc->cd_psy->s;\n    FLOAT   enn[SBMAX_s], thm[SBMAX_s];\n    int     sb;\n    convert_partition2scalefac(gds, eb, thr, enn, thm);\n    for (sb = 0; sb < SBMAX_s; ++sb) {\n        psv->en[chn].s[sb][sblock] = enn[sb];\n        psv->thm[chn].s[sb][sblock] = thm[sb];\n    }\n}\n\n/* longblock threshold calculation (part 2) */\nstatic void\nconvert_partition2scalefac_l(lame_internal_flags * gfc, FLOAT const *eb, FLOAT const *thr, int chn)\n{\n    PsyStateVar_t *const psv = &gfc->sv_psy;\n    PsyConst_CB2SB_t const *const gdl = &gfc->cd_psy->l;\n    FLOAT  *enn = &psv->en[chn].l[0];\n    FLOAT  *thm = &psv->thm[chn].l[0];\n    convert_partition2scalefac(gdl, eb, thr, enn, thm);\n}\n\nstatic void\nconvert_partition2scalefac_l_to_s(lame_internal_flags * gfc, FLOAT const *eb, FLOAT const *thr,\n                                  int chn)\n{\n    PsyStateVar_t *const psv = &gfc->sv_psy;\n    PsyConst_CB2SB_t const *const gds = &gfc->cd_psy->l_to_s;\n    FLOAT   enn[SBMAX_s], thm[SBMAX_s];\n    int     sb, sblock;\n    convert_partition2scalefac(gds, eb, thr, enn, thm);\n    for (sb = 0; sb < SBMAX_s; ++sb) {\n        FLOAT const scale = 1. / 64.f;\n        FLOAT const tmp_enn = enn[sb];\n        FLOAT const tmp_thm = thm[sb] * scale;\n        for (sblock = 0; sblock < 3; ++sblock) {\n            psv->en[chn].s[sb][sblock] = tmp_enn;\n            psv->thm[chn].s[sb][sblock] = tmp_thm;\n        }\n    }\n}\n\n\n\nstatic inline FLOAT\nNS_INTERP(FLOAT x, FLOAT y, FLOAT r)\n{\n    /* was pow((x),(r))*pow((y),1-(r)) */\n    if (r >= 1.0f)\n        return x;       /* 99.7% of the time */\n    if (r <= 0.0f)\n        return y;\n    if (y > 0.0f)\n        return powf(x / y, r) * y; /* rest of the time */\n    return 0.0f;        /* never happens */\n}\n\n\n\nstatic  FLOAT\npecalc_s(III_psy_ratio const *mr, FLOAT masking_lower)\n{\n    FLOAT   pe_s;\n    static const FLOAT regcoef_s[] = {\n        11.8,           /* these values are tuned only for 44.1kHz... */\n        13.6,\n        17.2,\n        32,\n        46.5,\n        51.3,\n        57.5,\n        67.1,\n        71.5,\n        84.6,\n        97.6,\n        130,\n/*      255.8 */\n    };\n    unsigned int sb, sblock;\n\n    pe_s = 1236.28f / 4;\n    for (sb = 0; sb < SBMAX_s - 1; sb++) {\n        for (sblock = 0; sblock < 3; sblock++) {\n            FLOAT const thm = mr->thm.s[sb][sblock];\n            assert(sb < dimension_of(regcoef_s));\n            if (thm > 0.0f) {\n                FLOAT const x = thm * masking_lower;\n                FLOAT const en = mr->en.s[sb][sblock];\n                if (en > x) {\n                    if (en > x * 1e10f) {\n                        pe_s += regcoef_s[sb] * (10.0f * LOG10);\n                    }\n                    else {\n                        assert(x > 0);\n                        pe_s += regcoef_s[sb] * FAST_LOG10(en / x);\n                    }\n                }\n            }\n        }\n    }\n\n    return pe_s;\n}\n\nstatic  FLOAT\npecalc_l(III_psy_ratio const *mr, FLOAT masking_lower)\n{\n    FLOAT   pe_l;\n    static const FLOAT regcoef_l[] = {\n        6.8,            /* these values are tuned only for 44.1kHz... */\n        5.8,\n        5.8,\n        6.4,\n        6.5,\n        9.9,\n        12.1,\n        14.4,\n        15,\n        18.9,\n        21.6,\n        26.9,\n        34.2,\n        40.2,\n        46.8,\n        56.5,\n        60.7,\n        73.9,\n        85.7,\n        93.4,\n        126.1,\n/*      241.3 */\n    };\n    unsigned int sb;\n\n    pe_l = 1124.23f / 4;\n    for (sb = 0; sb < SBMAX_l - 1; sb++) {\n        FLOAT const thm = mr->thm.l[sb];\n        assert(sb < dimension_of(regcoef_l));\n        if (thm > 0.0f) {\n            FLOAT const x = thm * masking_lower;\n            FLOAT const en = mr->en.l[sb];\n            if (en > x) {\n                if (en > x * 1e10f) {\n                    pe_l += regcoef_l[sb] * (10.0f * LOG10);\n                }\n                else {\n                    assert(x > 0);\n                    pe_l += regcoef_l[sb] * FAST_LOG10(en / x);\n                }\n            }\n        }\n    }\n\n    return pe_l;\n}\n\n\nstatic void\ncalc_energy(PsyConst_CB2SB_t const *l, FLOAT const *fftenergy, FLOAT * eb, FLOAT * max, FLOAT * avg)\n{\n    int     b, j;\n\n    for (b = j = 0; b < l->npart; ++b) {\n        FLOAT   ebb = 0, m = 0;\n        int     i;\n        for (i = 0; i < l->numlines[b]; ++i, ++j) {\n            FLOAT const el = fftenergy[j];\n            assert(el >= 0);\n            ebb += el;\n            if (m < el)\n                m = el;\n        }\n        eb[b] = ebb;\n        max[b] = m;\n        avg[b] = ebb * l->rnumlines[b];\n        assert(l->rnumlines[b] >= 0);\n        assert(ebb >= 0);\n        assert(eb[b] >= 0);\n        assert(max[b] >= 0);\n        assert(avg[b] >= 0);\n    }\n}\n\n\nstatic void\ncalc_mask_index_l(lame_internal_flags const *gfc, FLOAT const *max,\n                  FLOAT const *avg, unsigned char *mask_idx)\n{\n    PsyConst_CB2SB_t const *const gdl = &gfc->cd_psy->l;\n    FLOAT   m, a;\n    int     b, k;\n    int const last_tab_entry = sizeof(tab) / sizeof(tab[0]) - 1;\n    b = 0;\n    a = avg[b] + avg[b + 1];\n    assert(a >= 0);\n    if (a > 0.0f) {\n        m = max[b];\n        if (m < max[b + 1])\n            m = max[b + 1];\n        assert((gdl->numlines[b] + gdl->numlines[b + 1] - 1) > 0);\n        a = 20.0f * (m * 2.0f - a)\n            / (a * (gdl->numlines[b] + gdl->numlines[b + 1] - 1));\n        k = (int) a;\n        if (k > last_tab_entry)\n            k = last_tab_entry;\n        mask_idx[b] = k;\n    }\n    else {\n        mask_idx[b] = 0;\n    }\n\n    for (b = 1; b < gdl->npart - 1; b++) {\n        a = avg[b - 1] + avg[b] + avg[b + 1];\n        assert(a >= 0);\n        if (a > 0.0f) {\n            m = max[b - 1];\n            if (m < max[b])\n                m = max[b];\n            if (m < max[b + 1])\n                m = max[b + 1];\n            assert((gdl->numlines[b - 1] + gdl->numlines[b] + gdl->numlines[b + 1] - 1) > 0);\n            a = 20.0f * (m * 3.0f - a)\n                / (a * (gdl->numlines[b - 1] + gdl->numlines[b] + gdl->numlines[b + 1] - 1));\n            k = (int) a;\n            if (k > last_tab_entry)\n                k = last_tab_entry;\n            mask_idx[b] = k;\n        }\n        else {\n            mask_idx[b] = 0;\n        }\n    }\n    assert(b > 0);\n    assert(b == gdl->npart - 1);\n\n    a = avg[b - 1] + avg[b];\n    assert(a >= 0);\n    if (a > 0.0f) {\n        m = max[b - 1];\n        if (m < max[b])\n            m = max[b];\n        assert((gdl->numlines[b - 1] + gdl->numlines[b] - 1) > 0);\n        a = 20.0f * (m * 2.0f - a)\n            / (a * (gdl->numlines[b - 1] + gdl->numlines[b] - 1));\n        k = (int) a;\n        if (k > last_tab_entry)\n            k = last_tab_entry;\n        mask_idx[b] = k;\n    }\n    else {\n        mask_idx[b] = 0;\n    }\n    assert(b == (gdl->npart - 1));\n}\n\n\nstatic void\nvbrpsy_compute_fft_l(lame_internal_flags * gfc, const sample_t * const buffer[2], int chn,\n                     int gr_out, FLOAT fftenergy[HBLKSIZE], FLOAT(*wsamp_l)[BLKSIZE])\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    PsyStateVar_t *psv = &gfc->sv_psy;\n    plotting_data *plt = cfg->analysis ? gfc->pinfo : 0;\n    int     j;\n\n    if (chn < 2) {\n        fft_long(gfc, *wsamp_l, chn, buffer);\n    }\n    else if (chn == 2) {\n        FLOAT const sqrt2_half = SQRT2 * 0.5f;\n        /* FFT data for mid and side channel is derived from L & R */\n        for (j = BLKSIZE - 1; j >= 0; --j) {\n            FLOAT const l = wsamp_l[0][j];\n            FLOAT const r = wsamp_l[1][j];\n            wsamp_l[0][j] = (l + r) * sqrt2_half;\n            wsamp_l[1][j] = (l - r) * sqrt2_half;\n        }\n    }\n\n    /*********************************************************************\n    *  compute energies\n    *********************************************************************/\n    fftenergy[0] = wsamp_l[0][0];\n    fftenergy[0] *= fftenergy[0];\n\n    for (j = BLKSIZE / 2 - 1; j >= 0; --j) {\n        FLOAT const re = (*wsamp_l)[BLKSIZE / 2 - j];\n        FLOAT const im = (*wsamp_l)[BLKSIZE / 2 + j];\n        fftenergy[BLKSIZE / 2 - j] = (re * re + im * im) * 0.5f;\n    }\n    /* total energy */\n    {\n        FLOAT   totalenergy = 0.0f;\n        for (j = 11; j < HBLKSIZE; j++)\n            totalenergy += fftenergy[j];\n\n        psv->tot_ener[chn] = totalenergy;\n    }\n\n    if (plt) {\n        for (j = 0; j < HBLKSIZE; j++) {\n            plt->energy[gr_out][chn][j] = plt->energy_save[chn][j];\n            plt->energy_save[chn][j] = fftenergy[j];\n        }\n    }\n}\n\n\nstatic void\nvbrpsy_compute_fft_s(lame_internal_flags const *gfc, const sample_t * const buffer[2], int chn,\n                     int sblock, FLOAT(*fftenergy_s)[HBLKSIZE_s], FLOAT(*wsamp_s)[3][BLKSIZE_s])\n{\n    int     j;\n\n    if (sblock == 0 && chn < 2) {\n        fft_short(gfc, *wsamp_s, chn, buffer);\n    }\n    if (chn == 2) {\n        FLOAT const sqrt2_half = SQRT2 * 0.5f;\n        /* FFT data for mid and side channel is derived from L & R */\n        for (j = BLKSIZE_s - 1; j >= 0; --j) {\n            FLOAT const l = wsamp_s[0][sblock][j];\n            FLOAT const r = wsamp_s[1][sblock][j];\n            wsamp_s[0][sblock][j] = (l + r) * sqrt2_half;\n            wsamp_s[1][sblock][j] = (l - r) * sqrt2_half;\n        }\n    }\n\n    /*********************************************************************\n    *  compute energies\n    *********************************************************************/\n    fftenergy_s[sblock][0] = (*wsamp_s)[sblock][0];\n    fftenergy_s[sblock][0] *= fftenergy_s[sblock][0];\n    for (j = BLKSIZE_s / 2 - 1; j >= 0; --j) {\n        FLOAT const re = (*wsamp_s)[sblock][BLKSIZE_s / 2 - j];\n        FLOAT const im = (*wsamp_s)[sblock][BLKSIZE_s / 2 + j];\n        fftenergy_s[sblock][BLKSIZE_s / 2 - j] = (re * re + im * im) * 0.5f;\n    }\n}\n\n\n    /*********************************************************************\n    * compute loudness approximation (used for ATH auto-level adjustment) \n    *********************************************************************/\nstatic void\nvbrpsy_compute_loudness_approximation_l(lame_internal_flags * gfc, int gr_out, int chn,\n                                        const FLOAT fftenergy[HBLKSIZE])\n{\n    PsyStateVar_t *psv = &gfc->sv_psy;\n    if (chn < 2) {      /*no loudness for mid/side ch */\n        gfc->ov_psy.loudness_sq[gr_out][chn] = psv->loudness_sq_save[chn];\n        psv->loudness_sq_save[chn] = psycho_loudness_approx(fftenergy, gfc->ATH->eql_w);\n    }\n}\n\n\n    /**********************************************************************\n    *  Apply HPF of fs/4 to the input signal.\n    *  This is used for attack detection / handling.\n    **********************************************************************/\nstatic void\nvbrpsy_attack_detection(lame_internal_flags * gfc, const sample_t * const buffer[2], int gr_out,\n                        III_psy_ratio masking_ratio[2][2], III_psy_ratio masking_MS_ratio[2][2],\n                        FLOAT energy[4], FLOAT sub_short_factor[4][3], int ns_attacks[4][4],\n                        int uselongblock[2])\n{\n    FLOAT   ns_hpfsmpl[2][576];\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    PsyStateVar_t *const psv = &gfc->sv_psy;\n    plotting_data *plt = cfg->analysis ? gfc->pinfo : 0;\n    int const n_chn_out = cfg->channels_out;\n    /* chn=2 and 3 = Mid and Side channels */\n    int const n_chn_psy = (cfg->mode == JOINT_STEREO) ? 4 : n_chn_out;\n    int     chn, i, j;\n\n    memset(&ns_hpfsmpl[0][0], 0, sizeof(ns_hpfsmpl));\n    /* Don't copy the input buffer into a temporary buffer */\n    /* unroll the loop 2 times */\n    for (chn = 0; chn < n_chn_out; chn++) {\n        static const FLOAT fircoef[] = {\n            -8.65163e-18 * 2, -0.00851586 * 2, -6.74764e-18 * 2, 0.0209036 * 2,\n            -3.36639e-17 * 2, -0.0438162 * 2, -1.54175e-17 * 2, 0.0931738 * 2,\n            -5.52212e-17 * 2, -0.313819 * 2\n        };\n        /* apply high pass filter of fs/4 */\n        const sample_t *const firbuf = &buffer[chn][576 - 350 - NSFIRLEN + 192];\n        assert(dimension_of(fircoef) == ((NSFIRLEN - 1) / 2));\n        for (i = 0; i < 576; i++) {\n            FLOAT   sum1, sum2;\n            sum1 = firbuf[i + 10];\n            sum2 = 0.0;\n            for (j = 0; j < ((NSFIRLEN - 1) / 2) - 1; j += 2) {\n                sum1 += fircoef[j] * (firbuf[i + j] + firbuf[i + NSFIRLEN - j]);\n                sum2 += fircoef[j + 1] * (firbuf[i + j + 1] + firbuf[i + NSFIRLEN - j - 1]);\n            }\n            ns_hpfsmpl[chn][i] = sum1 + sum2;\n        }\n        masking_ratio[gr_out][chn].en = psv->en[chn];\n        masking_ratio[gr_out][chn].thm = psv->thm[chn];\n        if (n_chn_psy > 2) {\n            /* MS maskings  */\n            /*percep_MS_entropy         [chn-2]     = gfc -> pe  [chn];  */\n            masking_MS_ratio[gr_out][chn].en = psv->en[chn + 2];\n            masking_MS_ratio[gr_out][chn].thm = psv->thm[chn + 2];\n        }\n    }\n    for (chn = 0; chn < n_chn_psy; chn++) {\n        FLOAT   attack_intensity[12];\n        FLOAT   en_subshort[12];\n        FLOAT   en_short[4] = { 0, 0, 0, 0 };\n        FLOAT const *pf = ns_hpfsmpl[chn & 1];\n        int     ns_uselongblock = 1;\n\n        if (chn == 2) {\n            for (i = 0, j = 576; j > 0; ++i, --j) {\n                FLOAT const l = ns_hpfsmpl[0][i];\n                FLOAT const r = ns_hpfsmpl[1][i];\n                ns_hpfsmpl[0][i] = l + r;\n                ns_hpfsmpl[1][i] = l - r;\n            }\n        }\n        /*************************************************************** \n        * determine the block type (window type)\n        ***************************************************************/\n        /* calculate energies of each sub-shortblocks */\n        for (i = 0; i < 3; i++) {\n            en_subshort[i] = psv->last_en_subshort[chn][i + 6];\n            assert(psv->last_en_subshort[chn][i + 4] > 0);\n            attack_intensity[i] = en_subshort[i] / psv->last_en_subshort[chn][i + 4];\n            en_short[0] += en_subshort[i];\n        }\n\n        for (i = 0; i < 9; i++) {\n            FLOAT const *const pfe = pf + 576 / 9;\n            FLOAT   p = 1.;\n            for (; pf < pfe; pf++)\n                if (p < fabs(*pf))\n                    p = fabs(*pf);\n            psv->last_en_subshort[chn][i] = en_subshort[i + 3] = p;\n            en_short[1 + i / 3] += p;\n            if (p > en_subshort[i + 3 - 2]) {\n                assert(en_subshort[i + 3 - 2] > 0);\n                p = p / en_subshort[i + 3 - 2];\n            }\n            else if (en_subshort[i + 3 - 2] > p * 10.0f) {\n                assert(p > 0);\n                p = en_subshort[i + 3 - 2] / (p * 10.0f);\n            }\n            else {\n                p = 0.0;\n            }\n            attack_intensity[i + 3] = p;\n        }\n\n        /* pulse like signal detection for fatboy.wav and so on */\n        for (i = 0; i < 3; ++i) {\n            FLOAT const enn =\n                en_subshort[i * 3 + 3] + en_subshort[i * 3 + 4] + en_subshort[i * 3 + 5];\n            FLOAT   factor = 1.f;\n            if (en_subshort[i * 3 + 5] * 6 < enn) {\n                factor *= 0.5f;\n                if (en_subshort[i * 3 + 4] * 6 < enn) {\n                    factor *= 0.5f;\n                }\n            }\n            sub_short_factor[chn][i] = factor;\n        }\n\n        if (plt) {\n            FLOAT   x = attack_intensity[0];\n            for (i = 1; i < 12; i++) {\n                if (x < attack_intensity[i]) {\n                    x = attack_intensity[i];\n                }\n            }\n            plt->ers[gr_out][chn] = plt->ers_save[chn];\n            plt->ers_save[chn] = x;\n        }\n\n        /* compare energies between sub-shortblocks */\n        {\n            FLOAT   x = gfc->cd_psy->attack_threshold[chn];\n            for (i = 0; i < 12; i++) {\n                if (ns_attacks[chn][i / 3] == 0) {\n                    if (attack_intensity[i] > x) {\n                        ns_attacks[chn][i / 3] = (i % 3) + 1;\n                    }\n                }\n            }\n        }\n        /* should have energy change between short blocks, in order to avoid periodic signals */\n        /* Good samples to show the effect are Trumpet test songs */\n        /* GB: tuned (1) to avoid too many short blocks for test sample TRUMPET */\n        /* RH: tuned (2) to let enough short blocks through for test sample FSOL and SNAPS */\n        for (i = 1; i < 4; i++) {\n            FLOAT const u = en_short[i - 1];\n            FLOAT const v = en_short[i];\n            FLOAT const m = Max(u, v);\n            if (m < 40000) { /* (2) */\n                if (u < 1.7f * v && v < 1.7f * u) { /* (1) */\n                    if (i == 1 && ns_attacks[chn][0] <= ns_attacks[chn][i]) {\n                        ns_attacks[chn][0] = 0;\n                    }\n                    ns_attacks[chn][i] = 0;\n                }\n            }\n        }\n\n        if (ns_attacks[chn][0] <= psv->last_attacks[chn]) {\n            ns_attacks[chn][0] = 0;\n        }\n\n        if (psv->last_attacks[chn] == 3 ||\n            ns_attacks[chn][0] + ns_attacks[chn][1] + ns_attacks[chn][2] + ns_attacks[chn][3]) {\n            ns_uselongblock = 0;\n\n            if (ns_attacks[chn][1] && ns_attacks[chn][0]) {\n                ns_attacks[chn][1] = 0;\n            }\n            if (ns_attacks[chn][2] && ns_attacks[chn][1]) {\n                ns_attacks[chn][2] = 0;\n            }\n            if (ns_attacks[chn][3] && ns_attacks[chn][2]) {\n                ns_attacks[chn][3] = 0;\n            }\n        }\n\n        if (chn < 2) {\n            uselongblock[chn] = ns_uselongblock;\n        }\n        else {\n            if (ns_uselongblock == 0) {\n                uselongblock[0] = uselongblock[1] = 0;\n            }\n        }\n\n        /* there is a one granule delay.  Copy maskings computed last call\n         * into masking_ratio to return to calling program.\n         */\n        energy[chn] = psv->tot_ener[chn];\n    }\n}\n\n\nstatic void\nvbrpsy_skip_masking_s(lame_internal_flags * gfc, int chn, int sblock)\n{\n    if (sblock == 0) {\n        FLOAT  *nbs2 = &gfc->sv_psy.nb_s2[chn][0];\n        FLOAT  *nbs1 = &gfc->sv_psy.nb_s1[chn][0];\n        int const n = gfc->cd_psy->s.npart;\n        int     b;\n        for (b = 0; b < n; b++) {\n            nbs2[b] = nbs1[b];\n        }\n    }\n}\n\n\nstatic void\nvbrpsy_calc_mask_index_s(lame_internal_flags const *gfc, FLOAT const *max,\n                         FLOAT const *avg, unsigned char *mask_idx)\n{\n    PsyConst_CB2SB_t const *const gds = &gfc->cd_psy->s;\n    FLOAT   m, a;\n    int     b, k;\n    int const last_tab_entry = dimension_of(tab) - 1;\n    b = 0;\n    a = avg[b] + avg[b + 1];\n    assert(a >= 0);\n    if (a > 0.0f) {\n        m = max[b];\n        if (m < max[b + 1])\n            m = max[b + 1];\n        assert((gds->numlines[b] + gds->numlines[b + 1] - 1) > 0);\n        a = 20.0f * (m * 2.0f - a)\n            / (a * (gds->numlines[b] + gds->numlines[b + 1] - 1));\n        k = (int) a;\n        if (k > last_tab_entry)\n            k = last_tab_entry;\n        mask_idx[b] = k;\n    }\n    else {\n        mask_idx[b] = 0;\n    }\n\n    for (b = 1; b < gds->npart - 1; b++) {\n        a = avg[b - 1] + avg[b] + avg[b + 1];\n        assert(b + 1 < gds->npart);\n        assert(a >= 0);\n        if (a > 0.0) {\n            m = max[b - 1];\n            if (m < max[b])\n                m = max[b];\n            if (m < max[b + 1])\n                m = max[b + 1];\n            assert((gds->numlines[b - 1] + gds->numlines[b] + gds->numlines[b + 1] - 1) > 0);\n            a = 20.0f * (m * 3.0f - a)\n                / (a * (gds->numlines[b - 1] + gds->numlines[b] + gds->numlines[b + 1] - 1));\n            k = (int) a;\n            if (k > last_tab_entry)\n                k = last_tab_entry;\n            mask_idx[b] = k;\n        }\n        else {\n            mask_idx[b] = 0;\n        }\n    }\n    assert(b > 0);\n    assert(b == gds->npart - 1);\n\n    a = avg[b - 1] + avg[b];\n    assert(a >= 0);\n    if (a > 0.0f) {\n        m = max[b - 1];\n        if (m < max[b])\n            m = max[b];\n        assert((gds->numlines[b - 1] + gds->numlines[b] - 1) > 0);\n        a = 20.0f * (m * 2.0f - a)\n            / (a * (gds->numlines[b - 1] + gds->numlines[b] - 1));\n        k = (int) a;\n        if (k > last_tab_entry)\n            k = last_tab_entry;\n        mask_idx[b] = k;\n    }\n    else {\n        mask_idx[b] = 0;\n    }\n    assert(b == (gds->npart - 1));\n}\n\n\nstatic void\nvbrpsy_compute_masking_s(lame_internal_flags * gfc, const FLOAT(*fftenergy_s)[HBLKSIZE_s],\n                         FLOAT * eb, FLOAT * thr, int chn, int sblock)\n{\n    PsyStateVar_t *const psv = &gfc->sv_psy;\n    PsyConst_CB2SB_t const *const gds = &gfc->cd_psy->s;\n    FLOAT   max[CBANDS], avg[CBANDS];\n    int     i, j, b;\n    unsigned char mask_idx_s[CBANDS];\n\n    memset(max, 0, sizeof(max));\n    memset(avg, 0, sizeof(avg));\n\n    for (b = j = 0; b < gds->npart; ++b) {\n        FLOAT   ebb = 0, m = 0;\n        int const n = gds->numlines[b];\n        for (i = 0; i < n; ++i, ++j) {\n            FLOAT const el = fftenergy_s[sblock][j];\n            ebb += el;\n            if (m < el)\n                m = el;\n        }\n        eb[b] = ebb;\n        assert(ebb >= 0);\n        max[b] = m;\n        assert(n > 0);\n        avg[b] = ebb * gds->rnumlines[b];\n        assert(avg[b] >= 0);\n    }\n    assert(b == gds->npart);\n    assert(j == 129);\n    vbrpsy_calc_mask_index_s(gfc, max, avg, mask_idx_s);\n    for (j = b = 0; b < gds->npart; b++) {\n        int     kk = gds->s3ind[b][0];\n        int const last = gds->s3ind[b][1];\n        int const delta = mask_add_delta(mask_idx_s[b]);\n        int     dd, dd_n;\n        FLOAT   x, ecb, avg_mask;\n        FLOAT const masking_lower = gds->masking_lower[b] * gfc->sv_qnt.masking_lower;\n\n        dd = mask_idx_s[kk];\n        dd_n = 1;\n        ecb = gds->s3[j] * eb[kk] * tab[mask_idx_s[kk]];\n        ++j, ++kk;\n        while (kk <= last) {\n            dd += mask_idx_s[kk];\n            dd_n += 1;\n            x = gds->s3[j] * eb[kk] * tab[mask_idx_s[kk]];\n            ecb = vbrpsy_mask_add(ecb, x, kk - b, delta);\n            ++j, ++kk;\n        }\n        dd = (1 + 2 * dd) / (2 * dd_n);\n        avg_mask = tab[dd] * 0.5f;\n        ecb *= avg_mask;\n#if 0                   /* we can do PRE ECHO control now here, or do it later */\n        if (psv->blocktype_old[chn & 0x01] == SHORT_TYPE) {\n            /* limit calculated threshold by even older granule */\n            FLOAT const t1 = rpelev_s * psv->nb_s1[chn][b];\n            FLOAT const t2 = rpelev2_s * psv->nb_s2[chn][b];\n            FLOAT const tm = (t2 > 0) ? Min(ecb, t2) : ecb;\n            thr[b] = (t1 > 0) ? NS_INTERP(Min(tm, t1), ecb, 0.6) : ecb;\n        }\n        else {\n            /* limit calculated threshold by older granule */\n            FLOAT const t1 = rpelev_s * psv->nb_s1[chn][b];\n            thr[b] = (t1 > 0) ? NS_INTERP(Min(ecb, t1), ecb, 0.6) : ecb;\n        }\n#else /* we do it later */\n        thr[b] = ecb;\n#endif\n        psv->nb_s2[chn][b] = psv->nb_s1[chn][b];\n        psv->nb_s1[chn][b] = ecb;\n        {\n            /*  if THR exceeds EB, the quantization routines will take the difference\n             *  from other bands. in case of strong tonal samples (tonaltest.wav)\n             *  this leads to heavy distortions. that's why we limit THR here.\n             */\n            x = max[b];\n            x *= gds->minval[b];\n            x *= avg_mask;\n            if (thr[b] > x) {\n                thr[b] = x;\n            }\n        }\n        if (masking_lower > 1) {\n            thr[b] *= masking_lower;\n        }\n        if (thr[b] > eb[b]) {\n            thr[b] = eb[b];\n        }\n        if (masking_lower < 1) {\n            thr[b] *= masking_lower;\n        }\n\n        assert(thr[b] >= 0);\n    }\n    for (; b < CBANDS; ++b) {\n        eb[b] = 0;\n        thr[b] = 0;\n    }\n}\n\n\nstatic void\nvbrpsy_compute_masking_l(lame_internal_flags * gfc, const FLOAT fftenergy[HBLKSIZE],\n                         FLOAT eb_l[CBANDS], FLOAT thr[CBANDS], int chn)\n{\n    PsyStateVar_t *const psv = &gfc->sv_psy;\n    PsyConst_CB2SB_t const *const gdl = &gfc->cd_psy->l;\n    FLOAT   max[CBANDS], avg[CBANDS];\n    unsigned char mask_idx_l[CBANDS + 2];\n    int     k, b;\n\n /*********************************************************************\n    *    Calculate the energy and the tonality of each partition.\n *********************************************************************/\n    calc_energy(gdl, fftenergy, eb_l, max, avg);\n    calc_mask_index_l(gfc, max, avg, mask_idx_l);\n\n /*********************************************************************\n    *      convolve the partitioned energy and unpredictability\n    *      with the spreading function, s3_l[b][k]\n ********************************************************************/\n    k = 0;\n    for (b = 0; b < gdl->npart; b++) {\n        FLOAT   x, ecb, avg_mask, t;\n        FLOAT const masking_lower = gdl->masking_lower[b] * gfc->sv_qnt.masking_lower;\n        /* convolve the partitioned energy with the spreading function */\n        int     kk = gdl->s3ind[b][0];\n        int const last = gdl->s3ind[b][1];\n        int const delta = mask_add_delta(mask_idx_l[b]);\n        int     dd = 0, dd_n = 0;\n\n        dd = mask_idx_l[kk];\n        dd_n += 1;\n        ecb = gdl->s3[k] * eb_l[kk] * tab[mask_idx_l[kk]];\n        ++k, ++kk;\n        while (kk <= last) {\n            dd += mask_idx_l[kk];\n            dd_n += 1;\n            x = gdl->s3[k] * eb_l[kk] * tab[mask_idx_l[kk]];\n            t = vbrpsy_mask_add(ecb, x, kk - b, delta);\n#if 0\n            ecb += eb_l[kk];\n            if (ecb > t) {\n                ecb = t;\n            }\n#else\n            ecb = t;\n#endif\n            ++k, ++kk;\n        }\n        dd = (1 + 2 * dd) / (2 * dd_n);\n        avg_mask = tab[dd] * 0.5f;\n        ecb *= avg_mask;\n\n        /****   long block pre-echo control   ****/\n        /* dont use long block pre-echo control if previous granule was \n         * a short block.  This is to avoid the situation:   \n         * frame0:  quiet (very low masking)  \n         * frame1:  surge  (triggers short blocks)\n         * frame2:  regular frame.  looks like pre-echo when compared to \n         *          frame0, but all pre-echo was in frame1.\n         */\n        /* chn=0,1   L and R channels\n           chn=2,3   S and M channels.\n         */\n        if (psv->blocktype_old[chn & 0x01] == SHORT_TYPE) {\n            FLOAT const ecb_limit = rpelev * psv->nb_l1[chn][b];\n            if (ecb_limit > 0) {\n                thr[b] = Min(ecb, ecb_limit);\n            }\n            else {\n                /* Robert 071209:\n                   Because we don't calculate long block psy when we know a granule\n                   should be of short blocks, we don't have any clue how the granule\n                   before would have looked like as a long block. So we have to guess\n                   a little bit for this END_TYPE block.\n                   Most of the time we get away with this sloppyness. (fingers crossed :)\n                   The speed increase is worth it.\n                 */\n                thr[b] = Min(ecb, eb_l[b] * NS_PREECHO_ATT2);\n            }\n        }\n        else {\n            FLOAT   ecb_limit_2 = rpelev2 * psv->nb_l2[chn][b];\n            FLOAT   ecb_limit_1 = rpelev * psv->nb_l1[chn][b];\n            FLOAT   ecb_limit;\n            if (ecb_limit_2 <= 0) {\n                ecb_limit_2 = ecb;\n            }\n            if (ecb_limit_1 <= 0) {\n                ecb_limit_1 = ecb;\n            }\n            if (psv->blocktype_old[chn & 0x01] == NORM_TYPE) {\n                ecb_limit = Min(ecb_limit_1, ecb_limit_2);\n            }\n            else {\n                ecb_limit = ecb_limit_1;\n            }\n            thr[b] = Min(ecb, ecb_limit);\n        }\n        psv->nb_l2[chn][b] = psv->nb_l1[chn][b];\n        psv->nb_l1[chn][b] = ecb;\n        {\n            /*  if THR exceeds EB, the quantization routines will take the difference\n             *  from other bands. in case of strong tonal samples (tonaltest.wav)\n             *  this leads to heavy distortions. that's why we limit THR here.\n             */\n            x = max[b];\n            x *= gdl->minval[b];\n            x *= avg_mask;\n            if (thr[b] > x) {\n                thr[b] = x;\n            }\n        }\n        if (masking_lower > 1) {\n            thr[b] *= masking_lower;\n        }\n        if (thr[b] > eb_l[b]) {\n            thr[b] = eb_l[b];\n        }\n        if (masking_lower < 1) {\n            thr[b] *= masking_lower;\n        }\n        assert(thr[b] >= 0);\n    }\n    for (; b < CBANDS; ++b) {\n        eb_l[b] = 0;\n        thr[b] = 0;\n    }\n}\n\n\nstatic void\nvbrpsy_compute_block_type(SessionConfig_t const *cfg, int *uselongblock)\n{\n    int     chn;\n\n    if (cfg->short_blocks == short_block_coupled\n        /* force both channels to use the same block type */\n        /* this is necessary if the frame is to be encoded in ms_stereo.  */\n        /* But even without ms_stereo, FhG  does this */\n        && !(uselongblock[0] && uselongblock[1]))\n        uselongblock[0] = uselongblock[1] = 0;\n\n    for (chn = 0; chn < cfg->channels_out; chn++) {\n        /* disable short blocks */\n        if (cfg->short_blocks == short_block_dispensed) {\n            uselongblock[chn] = 1;\n        }\n        if (cfg->short_blocks == short_block_forced) {\n            uselongblock[chn] = 0;\n        }\n    }\n}\n\n\nstatic void\nvbrpsy_apply_block_type(PsyStateVar_t * psv, int nch, int const *uselongblock, int *blocktype_d)\n{\n    int     chn;\n\n    /* update the blocktype of the previous granule, since it depends on what\n     * happend in this granule */\n    for (chn = 0; chn < nch; chn++) {\n        int     blocktype = NORM_TYPE;\n        /* disable short blocks */\n\n        if (uselongblock[chn]) {\n            /* no attack : use long blocks */\n            assert(psv->blocktype_old[chn] != START_TYPE);\n            if (psv->blocktype_old[chn] == SHORT_TYPE)\n                blocktype = STOP_TYPE;\n        }\n        else {\n            /* attack : use short blocks */\n            blocktype = SHORT_TYPE;\n            if (psv->blocktype_old[chn] == NORM_TYPE) {\n                psv->blocktype_old[chn] = START_TYPE;\n            }\n            if (psv->blocktype_old[chn] == STOP_TYPE)\n                psv->blocktype_old[chn] = SHORT_TYPE;\n        }\n\n        blocktype_d[chn] = psv->blocktype_old[chn]; /* value returned to calling program */\n        psv->blocktype_old[chn] = blocktype; /* save for next call to l3psy_anal */\n    }\n}\n\n\n/*************************************************************** \n * compute M/S thresholds from Johnston & Ferreira 1992 ICASSP paper\n ***************************************************************/\n\nstatic void\nvbrpsy_compute_MS_thresholds(const FLOAT eb[4][CBANDS], FLOAT thr[4][CBANDS],\n                             const FLOAT cb_mld[CBANDS], const FLOAT ath_cb[CBANDS], FLOAT athlower,\n                             FLOAT msfix, int n)\n{\n    FLOAT const msfix2 = msfix * 2.f;\n    FLOAT   rside, rmid;\n    int     b;\n    for (b = 0; b < n; ++b) {\n        FLOAT const ebM = eb[2][b];\n        FLOAT const ebS = eb[3][b];\n        FLOAT const thmL = thr[0][b];\n        FLOAT const thmR = thr[1][b];\n        FLOAT   thmM = thr[2][b];\n        FLOAT   thmS = thr[3][b];\n\n        /* use this fix if L & R masking differs by 2db or less */\n        /* if db = 10*log10(x2/x1) < 2 */\n        /* if (x2 < 1.58*x1) { */\n        if (thmL <= 1.58f * thmR && thmR <= 1.58f * thmL) {\n            FLOAT const mld_m = cb_mld[b] * ebS;\n            FLOAT const mld_s = cb_mld[b] * ebM;\n            FLOAT const tmp_m = Min(thmS, mld_m);\n            FLOAT const tmp_s = Min(thmM, mld_s);\n            rmid = Max(thmM, tmp_m);\n            rside = Max(thmS, tmp_s);\n        }\n        else {\n            rmid = thmM;\n            rside = thmS;\n        }\n        if (msfix > 0.f) {\n            /***************************************************************/\n            /* Adjust M/S maskings if user set \"msfix\"                     */\n            /***************************************************************/\n            /* Naoki Shibata 2000 */\n            FLOAT   thmLR, thmMS;\n            FLOAT const ath = ath_cb[b] * athlower;\n            FLOAT const tmp_l = Max(thmL, ath);\n            FLOAT const tmp_r = Max(thmR, ath);\n            thmLR = Min(tmp_l, tmp_r);\n            thmM = Max(rmid, ath);\n            thmS = Max(rside, ath);\n            thmMS = thmM + thmS;\n            if (thmMS > 0.f && (thmLR * msfix2) < thmMS) {\n                FLOAT const f = thmLR * msfix2 / thmMS;\n                thmM *= f;\n                thmS *= f;\n                assert(thmMS > 0.f);\n            }\n            rmid = Min(thmM, rmid);\n            rside = Min(thmS, rside);\n        }\n        if (rmid > ebM) {\n            rmid = ebM;\n        }\n        if (rside > ebS) {\n            rside = ebS;\n        }\n        thr[2][b] = rmid;\n        thr[3][b] = rside;\n    }\n}\n\n\n/*\n * NOTE: the bitrate reduction from the inter-channel masking effect is low\n * compared to the chance of getting annyoing artefacts. L3psycho_anal_vbr does\n * not use this feature. (Robert 071216)\n*/\n\nint\nL3psycho_anal_vbr(lame_internal_flags * gfc,\n                  const sample_t * const buffer[2], int gr_out,\n                  III_psy_ratio masking_ratio[2][2],\n                  III_psy_ratio masking_MS_ratio[2][2],\n                  FLOAT percep_entropy[2], FLOAT percep_MS_entropy[2],\n                  FLOAT energy[4], int blocktype_d[2])\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    PsyStateVar_t *const psv = &gfc->sv_psy;\n    PsyConst_CB2SB_t const *const gdl = &gfc->cd_psy->l;\n    PsyConst_CB2SB_t const *const gds = &gfc->cd_psy->s;\n    plotting_data *plt = cfg->analysis ? gfc->pinfo : 0;\n\n    III_psy_xmin last_thm[4];\n\n    /* fft and energy calculation   */\n    FLOAT(*wsamp_l)[BLKSIZE];\n    FLOAT(*wsamp_s)[3][BLKSIZE_s];\n    FLOAT   fftenergy[HBLKSIZE];\n    FLOAT   fftenergy_s[3][HBLKSIZE_s];\n    FLOAT   wsamp_L[2][BLKSIZE];\n    FLOAT   wsamp_S[2][3][BLKSIZE_s];\n    FLOAT   eb[4][CBANDS], thr[4][CBANDS];\n\n    FLOAT   sub_short_factor[4][3];\n    FLOAT   thmm;\n    FLOAT const pcfact = 0.6f;\n    FLOAT const ath_factor =\n        (cfg->msfix > 0.f) ? (cfg->ATH_offset_factor * gfc->ATH->adjust_factor) : 1.f;\n\n    const   FLOAT(*const_eb)[CBANDS] = (const FLOAT(*)[CBANDS]) eb;\n    const   FLOAT(*const_fftenergy_s)[HBLKSIZE_s] = (const FLOAT(*)[HBLKSIZE_s]) fftenergy_s;\n\n    /* block type  */\n    int     ns_attacks[4][4] = { {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0} };\n    int     uselongblock[2];\n\n    /* usual variables like loop indices, etc..    */\n    int     chn, sb, sblock;\n\n    /* chn=2 and 3 = Mid and Side channels */\n    int const n_chn_psy = (cfg->mode == JOINT_STEREO) ? 4 : cfg->channels_out;\n\n    memcpy(&last_thm[0], &psv->thm[0], sizeof(last_thm));\n\n    vbrpsy_attack_detection(gfc, buffer, gr_out, masking_ratio, masking_MS_ratio, energy,\n                            sub_short_factor, ns_attacks, uselongblock);\n\n    vbrpsy_compute_block_type(cfg, uselongblock);\n\n    /* LONG BLOCK CASE */\n    {\n        for (chn = 0; chn < n_chn_psy; chn++) {\n            int const ch01 = chn & 0x01;\n\n            wsamp_l = wsamp_L + ch01;\n            vbrpsy_compute_fft_l(gfc, buffer, chn, gr_out, fftenergy, wsamp_l);\n            vbrpsy_compute_loudness_approximation_l(gfc, gr_out, chn, fftenergy);\n            vbrpsy_compute_masking_l(gfc, fftenergy, eb[chn], thr[chn], chn);\n        }\n        if (cfg->mode == JOINT_STEREO) {\n            if ((uselongblock[0] + uselongblock[1]) == 2) {\n                vbrpsy_compute_MS_thresholds(const_eb, thr, gdl->mld_cb, gfc->ATH->cb_l,\n                                             ath_factor, cfg->msfix, gdl->npart);\n            }\n        }\n        /* TODO: apply adaptive ATH masking here ?? */\n        for (chn = 0; chn < n_chn_psy; chn++) {\n            convert_partition2scalefac_l(gfc, eb[chn], thr[chn], chn);\n            convert_partition2scalefac_l_to_s(gfc, eb[chn], thr[chn], chn);\n        }\n    }\n    /* SHORT BLOCKS CASE */\n    {\n        int const force_short_block_calc = gfc->cd_psy->force_short_block_calc;\n        for (sblock = 0; sblock < 3; sblock++) {\n            for (chn = 0; chn < n_chn_psy; ++chn) {\n                int const ch01 = chn & 0x01;\n                if (uselongblock[ch01] && !force_short_block_calc) {\n                    vbrpsy_skip_masking_s(gfc, chn, sblock);\n                }\n                else {\n                    /* compute masking thresholds for short blocks */\n                    wsamp_s = wsamp_S + ch01;\n                    vbrpsy_compute_fft_s(gfc, buffer, chn, sblock, fftenergy_s, wsamp_s);\n                    vbrpsy_compute_masking_s(gfc, const_fftenergy_s, eb[chn], thr[chn], chn,\n                                             sblock);\n                }\n            }\n            if (cfg->mode == JOINT_STEREO) {\n                if ((uselongblock[0] + uselongblock[1]) == 0) {\n                    vbrpsy_compute_MS_thresholds(const_eb, thr, gds->mld_cb, gfc->ATH->cb_s,\n                                                 ath_factor, cfg->msfix, gds->npart);\n                }\n            }\n            /* TODO: apply adaptive ATH masking here ?? */\n            for (chn = 0; chn < n_chn_psy; ++chn) {\n                int const ch01 = chn & 0x01;\n                if (!uselongblock[ch01] || force_short_block_calc) {\n                    convert_partition2scalefac_s(gfc, eb[chn], thr[chn], chn, sblock);\n                }\n            }\n        }\n\n        /****   short block pre-echo control   ****/\n        for (chn = 0; chn < n_chn_psy; chn++) {\n            for (sb = 0; sb < SBMAX_s; sb++) {\n                FLOAT   new_thmm[3], prev_thm, t1, t2;\n                for (sblock = 0; sblock < 3; sblock++) {\n                    thmm = psv->thm[chn].s[sb][sblock];\n                    thmm *= NS_PREECHO_ATT0;\n\n                    t1 = t2 = thmm;\n\n                    if (sblock > 0) {\n                        prev_thm = new_thmm[sblock - 1];\n                    }\n                    else {\n                        prev_thm = last_thm[chn].s[sb][2];\n                    }\n                    if (ns_attacks[chn][sblock] >= 2 || ns_attacks[chn][sblock + 1] == 1) {\n                        t1 = NS_INTERP(prev_thm, thmm, NS_PREECHO_ATT1 * pcfact);\n                    }\n                    thmm = Min(t1, thmm);\n                    if (ns_attacks[chn][sblock] == 1) {\n                        t2 = NS_INTERP(prev_thm, thmm, NS_PREECHO_ATT2 * pcfact);\n                    }\n                    else if ((sblock == 0 && psv->last_attacks[chn] == 3)\n                             || (sblock > 0 && ns_attacks[chn][sblock - 1] == 3)) { /* 2nd preceeding block */\n                        switch (sblock) {\n                        case 0:\n                            prev_thm = last_thm[chn].s[sb][1];\n                            break;\n                        case 1:\n                            prev_thm = last_thm[chn].s[sb][2];\n                            break;\n                        case 2:\n                            prev_thm = new_thmm[0];\n                            break;\n                        }\n                        t2 = NS_INTERP(prev_thm, thmm, NS_PREECHO_ATT2 * pcfact);\n                    }\n\n                    thmm = Min(t1, thmm);\n                    thmm = Min(t2, thmm);\n\n                    /* pulse like signal detection for fatboy.wav and so on */\n                    thmm *= sub_short_factor[chn][sblock];\n\n                    new_thmm[sblock] = thmm;\n                }\n                for (sblock = 0; sblock < 3; sblock++) {\n                    psv->thm[chn].s[sb][sblock] = new_thmm[sblock];\n                }\n            }\n        }\n    }\n    for (chn = 0; chn < n_chn_psy; chn++) {\n        psv->last_attacks[chn] = ns_attacks[chn][2];\n    }\n\n\n    /*************************************************************** \n    * determine final block type\n    ***************************************************************/\n    vbrpsy_apply_block_type(psv, cfg->channels_out, uselongblock, blocktype_d);\n\n    /*********************************************************************\n    * compute the value of PE to return ... no delay and advance\n    *********************************************************************/\n    for (chn = 0; chn < n_chn_psy; chn++) {\n        FLOAT  *ppe;\n        int     type;\n        III_psy_ratio const *mr;\n\n        if (chn > 1) {\n            ppe = percep_MS_entropy - 2;\n            type = NORM_TYPE;\n            if (blocktype_d[0] == SHORT_TYPE || blocktype_d[1] == SHORT_TYPE)\n                type = SHORT_TYPE;\n            mr = &masking_MS_ratio[gr_out][chn - 2];\n        }\n        else {\n            ppe = percep_entropy;\n            type = blocktype_d[chn];\n            mr = &masking_ratio[gr_out][chn];\n        }\n        if (type == SHORT_TYPE) {\n            ppe[chn] = pecalc_s(mr, gfc->sv_qnt.masking_lower);\n        }\n        else {\n            ppe[chn] = pecalc_l(mr, gfc->sv_qnt.masking_lower);\n        }\n\n        if (plt) {\n            plt->pe[gr_out][chn] = ppe[chn];\n        }\n    }\n    return 0;\n}\n\n\n\n\n/* \n *   The spreading function.  Values returned in units of energy\n */\nstatic  FLOAT\ns3_func(FLOAT bark)\n{\n    FLOAT   tempx, x, tempy, temp;\n    tempx = bark;\n    if (tempx >= 0)\n        tempx *= 3;\n    else\n        tempx *= 1.5;\n\n    if (tempx >= 0.5 && tempx <= 2.5) {\n        temp = tempx - 0.5;\n        x = 8.0 * (temp * temp - 2.0 * temp);\n    }\n    else\n        x = 0.0;\n    tempx += 0.474;\n    tempy = 15.811389 + 7.5 * tempx - 17.5 * sqrt(1.0 + tempx * tempx);\n\n    if (tempy <= -60.0)\n        return 0.0;\n\n    tempx = exp((x + tempy) * LN_TO_LOG10);\n\n    /* Normalization.  The spreading function should be normalized so that:\n       +inf\n       /\n       |  s3 [ bark ]  d(bark)   =  1\n       /\n       -inf\n     */\n    tempx /= .6609193;\n    return tempx;\n}\n\n#if 0\nstatic  FLOAT\nnorm_s3_func(void)\n{\n    double  lim_a = 0, lim_b = 0;\n    double  x = 0, l, h;\n    for (x = 0; s3_func(x) > 1e-20; x -= 1);\n    l = x;\n    h = 0;\n    while (fabs(h - l) > 1e-12) {\n        x = (h + l) / 2;\n        if (s3_func(x) > 0) {\n            h = x;\n        }\n        else {\n            l = x;\n        }\n    }\n    lim_a = l;\n    for (x = 0; s3_func(x) > 1e-20; x += 1);\n    l = 0;\n    h = x;\n    while (fabs(h - l) > 1e-12) {\n        x = (h + l) / 2;\n        if (s3_func(x) > 0) {\n            l = x;\n        }\n        else {\n            h = x;\n        }\n    }\n    lim_b = h;\n    {\n        double  sum = 0;\n        int const m = 1000;\n        int     i;\n        for (i = 0; i <= m; ++i) {\n            double  x = lim_a + i * (lim_b - lim_a) / m;\n            double  y = s3_func(x);\n            sum += y;\n        }\n        {\n            double  norm = (m + 1) / (sum * (lim_b - lim_a));\n            /*printf( \"norm = %lf\\n\",norm); */\n            return norm;\n        }\n    }\n}\n#endif\n\nstatic  FLOAT\nstereo_demask(double f)\n{\n    /* setup stereo demasking thresholds */\n    /* formula reverse enginerred from plot in paper */\n    double  arg = freq2bark(f);\n    arg = (Min(arg, 15.5) / 15.5);\n\n    return pow(10.0, 1.25 * (1 - cos(PI * arg)) - 2.5);\n}\n\nstatic void\ninit_numline(PsyConst_CB2SB_t * gd, FLOAT sfreq, int fft_size,\n             int mdct_size, int sbmax, int const *scalepos)\n{\n    FLOAT   b_frq[CBANDS + 1];\n    FLOAT const mdct_freq_frac = sfreq / (2.0f * mdct_size);\n    FLOAT const deltafreq = fft_size / (2.0f * mdct_size);\n    int     partition[HBLKSIZE] = { 0 };\n    int     i, j, ni;\n    int     sfb;\n    sfreq /= fft_size;\n    j = 0;\n    ni = 0;\n    /* compute numlines, the number of spectral lines in each partition band */\n    /* each partition band should be about DELBARK wide. */\n    for (i = 0; i < CBANDS; i++) {\n        FLOAT   bark1;\n        int     j2, nl;\n        bark1 = freq2bark(sfreq * j);\n\n        b_frq[i] = sfreq * j;\n\n        for (j2 = j; freq2bark(sfreq * j2) - bark1 < DELBARK && j2 <= fft_size / 2; j2++);\n\n        nl = j2 - j;\n        gd->numlines[i] = nl;\n        gd->rnumlines[i] = (nl > 0) ? (1.0f / nl) : 0;\n\n        ni = i + 1;\n\n        while (j < j2) {\n            assert(j < HBLKSIZE);\n            partition[j++] = i;\n        }\n        if (j > fft_size / 2) {\n            j = fft_size / 2;\n            ++i;\n            break;\n        }\n    }\n    assert(i < CBANDS);\n    b_frq[i] = sfreq * j;\n\n    gd->n_sb = sbmax;\n    gd->npart = ni;\n\n    {\n        j = 0;\n        for (i = 0; i < gd->npart; i++) {\n            int const nl = gd->numlines[i];\n            FLOAT const freq = sfreq * (j + nl / 2);\n            gd->mld_cb[i] = stereo_demask(freq);\n            j += nl;\n        }\n        for (; i < CBANDS; ++i) {\n            gd->mld_cb[i] = 1;\n        }\n    }\n    for (sfb = 0; sfb < sbmax; sfb++) {\n        int     i1, i2, bo;\n        int     start = scalepos[sfb];\n        int     end = scalepos[sfb + 1];\n\n        i1 = floor(.5 + deltafreq * (start - .5));\n        if (i1 < 0)\n            i1 = 0;\n        i2 = floor(.5 + deltafreq * (end - .5));\n\n        if (i2 > fft_size / 2)\n            i2 = fft_size / 2;\n\n        bo = partition[i2];\n        gd->bm[sfb] = (partition[i1] + partition[i2]) / 2;\n        gd->bo[sfb] = bo;\n\n        /* calculate how much of this band belongs to current scalefactor band */\n        {\n            FLOAT const f_tmp = mdct_freq_frac * end;\n            FLOAT   bo_w = (f_tmp - b_frq[bo]) / (b_frq[bo + 1] - b_frq[bo]);\n            if (bo_w < 0) {\n                bo_w = 0;\n            }\n            else {\n                if (bo_w > 1) {\n                    bo_w = 1;\n                }\n            }\n            gd->bo_weight[sfb] = bo_w;\n        }\n        gd->mld[sfb] = stereo_demask(mdct_freq_frac * start);\n    }\n}\n\nstatic void\ncompute_bark_values(PsyConst_CB2SB_t const *gd, FLOAT sfreq, int fft_size,\n                    FLOAT * bval, FLOAT * bval_width)\n{\n    /* compute bark values of each critical band */\n    int     k, j = 0, ni = gd->npart;\n    sfreq /= fft_size;\n    for (k = 0; k < ni; k++) {\n        int const w = gd->numlines[k];\n        FLOAT   bark1, bark2;\n\n        bark1 = freq2bark(sfreq * (j));\n        bark2 = freq2bark(sfreq * (j + w - 1));\n        bval[k] = .5 * (bark1 + bark2);\n\n        bark1 = freq2bark(sfreq * (j - .5));\n        bark2 = freq2bark(sfreq * (j + w - .5));\n        bval_width[k] = bark2 - bark1;\n        j += w;\n    }\n}\n\nstatic int\ninit_s3_values(FLOAT ** p, int (*s3ind)[2], int npart,\n               FLOAT const *bval, FLOAT const *bval_width, FLOAT const *norm)\n{\n    FLOAT   s3[CBANDS][CBANDS];\n    /* The s3 array is not linear in the bark scale.\n     * bval[x] should be used to get the bark value.\n     */\n    int     i, j, k;\n    int     numberOfNoneZero = 0;\n\n    memset(&s3[0][0], 0, sizeof(s3));\n\n    /* s[i][j], the value of the spreading function,\n     * centered at band j (masker), for band i (maskee)\n     *\n     * i.e.: sum over j to spread into signal barkval=i\n     * NOTE: i and j are used opposite as in the ISO docs\n     */\n    for (i = 0; i < npart; i++) {\n        for (j = 0; j < npart; j++) {\n            FLOAT   v = s3_func(bval[i] - bval[j]) * bval_width[j];\n            s3[i][j] = v * norm[i];\n        }\n    }\n    for (i = 0; i < npart; i++) {\n        for (j = 0; j < npart; j++) {\n            if (s3[i][j] > 0.0f)\n                break;\n        }\n        s3ind[i][0] = j;\n\n        for (j = npart - 1; j > 0; j--) {\n            if (s3[i][j] > 0.0f)\n                break;\n        }\n        s3ind[i][1] = j;\n        numberOfNoneZero += (s3ind[i][1] - s3ind[i][0] + 1);\n    }\n    *p = malloc(sizeof(FLOAT) * numberOfNoneZero);\n    if (!*p)\n        return -1;\n\n    k = 0;\n    for (i = 0; i < npart; i++)\n        for (j = s3ind[i][0]; j <= s3ind[i][1]; j++)\n            (*p)[k++] = s3[i][j];\n\n    return 0;\n}\n\nint\npsymodel_init(lame_global_flags const *gfp)\n{\n    lame_internal_flags *const gfc = gfp->internal_flags;\n    SessionConfig_t *const cfg = &gfc->cfg;\n    PsyStateVar_t *const psv = &gfc->sv_psy;\n    PsyConst_t *gd;\n    int     i, j, b, sb, k;\n    FLOAT   bvl_a = 13, bvl_b = 24;\n    FLOAT   snr_l_a = 0, snr_l_b = 0;\n    FLOAT   snr_s_a = -8.25, snr_s_b = -4.5;\n\n    FLOAT   bval[CBANDS];\n    FLOAT   bval_width[CBANDS];\n    FLOAT   norm[CBANDS];\n    FLOAT const sfreq = cfg->samplerate_out;\n\n    FLOAT   xav = 10, xbv = 12;\n    FLOAT const minval_low = (0.f - cfg->minval);\n\n    if (gfc->cd_psy != 0) {\n        return 0;\n    }\n    memset(norm, 0, sizeof(norm));\n\n    gd = calloc(1, sizeof(PsyConst_t));\n    gfc->cd_psy = gd;\n\n    gd->force_short_block_calc = gfp->experimentalZ;\n\n    psv->blocktype_old[0] = psv->blocktype_old[1] = NORM_TYPE; /* the vbr header is long blocks */\n\n    for (i = 0; i < 4; ++i) {\n        for (j = 0; j < CBANDS; ++j) {\n            psv->nb_l1[i][j] = 1e20;\n            psv->nb_l2[i][j] = 1e20;\n            psv->nb_s1[i][j] = psv->nb_s2[i][j] = 1.0;\n        }\n        for (sb = 0; sb < SBMAX_l; sb++) {\n            psv->en[i].l[sb] = 1e20;\n            psv->thm[i].l[sb] = 1e20;\n        }\n        for (j = 0; j < 3; ++j) {\n            for (sb = 0; sb < SBMAX_s; sb++) {\n                psv->en[i].s[sb][j] = 1e20;\n                psv->thm[i].s[sb][j] = 1e20;\n            }\n            psv->last_attacks[i] = 0;\n        }\n        for (j = 0; j < 9; j++)\n            psv->last_en_subshort[i][j] = 10.;\n    }\n\n\n    /* init. for loudness approx. -jd 2001 mar 27 */\n    psv->loudness_sq_save[0] = psv->loudness_sq_save[1] = 0.0;\n\n\n\n    /*************************************************************************\n     * now compute the psychoacoustic model specific constants\n     ************************************************************************/\n    /* compute numlines, bo, bm, bval, bval_width, mld */\n    init_numline(&gd->l, sfreq, BLKSIZE, 576, SBMAX_l, gfc->scalefac_band.l);\n    assert(gd->l.npart < CBANDS);\n    compute_bark_values(&gd->l, sfreq, BLKSIZE, bval, bval_width);\n\n    /* compute the spreading function */\n    for (i = 0; i < gd->l.npart; i++) {\n        double  snr = snr_l_a;\n        if (bval[i] >= bvl_a) {\n            snr = snr_l_b * (bval[i] - bvl_a) / (bvl_b - bvl_a)\n                + snr_l_a * (bvl_b - bval[i]) / (bvl_b - bvl_a);\n        }\n        norm[i] = pow(10.0, snr / 10.0);\n    }\n    i = init_s3_values(&gd->l.s3, gd->l.s3ind, gd->l.npart, bval, bval_width, norm);\n    if (i)\n        return i;\n\n    /* compute long block specific values, ATH and MINVAL */\n    j = 0;\n    for (i = 0; i < gd->l.npart; i++) {\n        double  x;\n\n        /* ATH */\n        x = FLOAT_MAX;\n        for (k = 0; k < gd->l.numlines[i]; k++, j++) {\n            FLOAT const freq = sfreq * j / (1000.0 * BLKSIZE);\n            FLOAT   level;\n            /* freq = Min(.1,freq); *//* ATH below 100 Hz constant, not further climbing */\n            level = ATHformula(cfg, freq * 1000) - 20; /* scale to FFT units; returned value is in dB */\n            level = pow(10., 0.1 * level); /* convert from dB -> energy */\n            level *= gd->l.numlines[i];\n            if (x > level)\n                x = level;\n        }\n        gfc->ATH->cb_l[i] = x;\n\n        /* MINVAL.\n           For low freq, the strength of the masking is limited by minval\n           this is an ISO MPEG1 thing, dont know if it is really needed */\n        /* FIXME: it does work to reduce low-freq problems in S53-Wind-Sax\n           and lead-voice samples, but introduces some 3 kbps bit bloat too.\n           TODO: Further refinement of the shape of this hack.\n         */\n        x = 20.0 * (bval[i] / xav - 1.0);\n        if (x > 6) {\n            x = 30;\n        }\n        if (x < minval_low) {\n            x = minval_low;\n        }\n        if (cfg->samplerate_out < 44000) {\n            x = 30;\n        }\n        x -= 8.;\n        gd->l.minval[i] = pow(10.0, x / 10.) * gd->l.numlines[i];\n    }\n\n    /************************************************************************\n     * do the same things for short blocks\n     ************************************************************************/\n    init_numline(&gd->s, sfreq, BLKSIZE_s, 192, SBMAX_s, gfc->scalefac_band.s);\n    assert(gd->s.npart < CBANDS);\n    compute_bark_values(&gd->s, sfreq, BLKSIZE_s, bval, bval_width);\n\n    /* SNR formula. short block is normalized by SNR. is it still right ? */\n    j = 0;\n    for (i = 0; i < gd->s.npart; i++) {\n        double  x;\n        double  snr = snr_s_a;\n        if (bval[i] >= bvl_a) {\n            snr = snr_s_b * (bval[i] - bvl_a) / (bvl_b - bvl_a)\n                + snr_s_a * (bvl_b - bval[i]) / (bvl_b - bvl_a);\n        }\n        norm[i] = pow(10.0, snr / 10.0);\n\n        /* ATH */\n        x = FLOAT_MAX;\n        for (k = 0; k < gd->s.numlines[i]; k++, j++) {\n            FLOAT const freq = sfreq * j / (1000.0 * BLKSIZE_s);\n            FLOAT   level;\n            /* freq = Min(.1,freq); *//* ATH below 100 Hz constant, not further climbing */\n            level = ATHformula(cfg, freq * 1000) - 20; /* scale to FFT units; returned value is in dB */\n            level = pow(10., 0.1 * level); /* convert from dB -> energy */\n            level *= gd->s.numlines[i];\n            if (x > level)\n                x = level;\n        }\n        gfc->ATH->cb_s[i] = x;\n\n        /* MINVAL.\n           For low freq, the strength of the masking is limited by minval\n           this is an ISO MPEG1 thing, dont know if it is really needed */\n        x = 7.0 * (bval[i] / xbv - 1.0);\n        if (bval[i] > xbv) {\n            x *= 1 + log(1 + x) * 3.1;\n        }\n        if (bval[i] < xbv) {\n            x *= 1 + log(1 - x) * 2.3;\n        }\n        if (x > 6) {\n            x = 30;\n        }\n        if (x < minval_low) {\n            x = minval_low;\n        }\n        if (cfg->samplerate_out < 44000) {\n            x = 30;\n        }\n        x -= 8;\n        gd->s.minval[i] = pow(10.0, x / 10) * gd->s.numlines[i];\n    }\n\n    i = init_s3_values(&gd->s.s3, gd->s.s3ind, gd->s.npart, bval, bval_width, norm);\n    if (i)\n        return i;\n\n\n    init_mask_add_max_values();\n    init_fft(gfc);\n\n    /* setup temporal masking */\n    gd->decay = exp(-1.0 * LOG10 / (temporalmask_sustain_sec * sfreq / 192.0));\n\n    {\n        FLOAT   msfix;\n        msfix = NS_MSFIX;\n        if (cfg->use_safe_joint_stereo)\n            msfix = 1.0;\n        if (fabs(cfg->msfix) > 0.0)\n            msfix = cfg->msfix;\n        cfg->msfix = msfix;\n\n        /* spread only from npart_l bands.  Normally, we use the spreading\n         * function to convolve from npart_l down to npart_l bands \n         */\n        for (b = 0; b < gd->l.npart; b++)\n            if (gd->l.s3ind[b][1] > gd->l.npart - 1)\n                gd->l.s3ind[b][1] = gd->l.npart - 1;\n    }\n\n    /*  prepare for ATH auto adjustment:\n     *  we want to decrease the ATH by 12 dB per second\n     */\n#define  frame_duration (576. * cfg->mode_gr / sfreq)\n    gfc->ATH->decay = pow(10., -12. / 10. * frame_duration);\n    gfc->ATH->adjust_factor = 0.01; /* minimum, for leading low loudness */\n    gfc->ATH->adjust_limit = 1.0; /* on lead, allow adjust up to maximum */\n#undef  frame_duration\n\n    assert(gd->l.bo[SBMAX_l - 1] <= gd->l.npart);\n    assert(gd->s.bo[SBMAX_s - 1] <= gd->s.npart);\n\n    if (cfg->ATHtype != -1) {\n        /* compute equal loudness weights (eql_w) */\n        FLOAT   freq;\n        FLOAT const freq_inc = (FLOAT) cfg->samplerate_out / (FLOAT) (BLKSIZE);\n        FLOAT   eql_balance = 0.0;\n        freq = 0.0;\n        for (i = 0; i < BLKSIZE / 2; ++i) {\n            /* convert ATH dB to relative power (not dB) */\n            /*  to determine eql_w */\n            freq += freq_inc;\n            gfc->ATH->eql_w[i] = 1. / pow(10, ATHformula(cfg, freq) / 10);\n            eql_balance += gfc->ATH->eql_w[i];\n        }\n        eql_balance = 1.0 / eql_balance;\n        for (i = BLKSIZE / 2; --i >= 0;) { /* scale weights */\n            gfc->ATH->eql_w[i] *= eql_balance;\n        }\n    }\n    {\n        for (b = j = 0; b < gd->s.npart; ++b) {\n            for (i = 0; i < gd->s.numlines[b]; ++i) {\n                ++j;\n            }\n        }\n        assert(j == 129);\n        for (b = j = 0; b < gd->l.npart; ++b) {\n            for (i = 0; i < gd->l.numlines[b]; ++i) {\n                ++j;\n            }\n        }\n        assert(j == 513);\n    }\n    /* short block attack threshold */\n    {\n        float   x = gfp->attackthre;\n        float   y = gfp->attackthre_s;\n        if (x < 0) {\n            x = NSATTACKTHRE;\n        }\n        if (y < 0) {\n            y = NSATTACKTHRE_S;\n        }\n        gd->attack_threshold[0] = gd->attack_threshold[1] = gd->attack_threshold[2] = x;\n        gd->attack_threshold[3] = y;\n    }\n    {\n        float   sk_s = -10.f, sk_l = -4.7f;\n        static float const sk[] =\n            { -7.4, -7.4, -7.4, -9.5, -7.4, -6.1, -5.5, -4.7, -4.7, -4.7, -4.7 };\n        if (gfp->VBR_q < 4) {\n            sk_l = sk_s = sk[0];\n        }\n        else {\n            sk_l = sk_s = sk[gfp->VBR_q] + gfp->VBR_q_frac * (sk[gfp->VBR_q] - sk[gfp->VBR_q + 1]);\n        }\n        b = 0;\n        for (; b < gd->s.npart; b++) {\n            float   m = (float) (gd->s.npart - b) / gd->s.npart;\n            gd->s.masking_lower[b] = powf(10.f, sk_s * m * 0.1f);\n        }\n        for (; b < CBANDS; ++b) {\n            gd->s.masking_lower[b] = 1.f;\n        }\n        b = 0;\n        for (; b < gd->l.npart; b++) {\n            float   m = (float) (gd->l.npart - b) / gd->l.npart;\n            gd->l.masking_lower[b] = powf(10.f, sk_l * m * 0.1f);\n        }\n        for (; b < CBANDS; ++b) {\n            gd->l.masking_lower[b] = 1.f;\n        }\n    }\n    memcpy(&gd->l_to_s, &gd->l, sizeof(gd->l_to_s));\n    init_numline(&gd->l_to_s, sfreq, BLKSIZE, 192, SBMAX_s, gfc->scalefac_band.s);\n    return 0;\n}\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/psymodel.h",
    "content": "/*\n *\tpsymodel.h\n *\n *\tCopyright (c) 1999 Mark Taylor\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\t See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n#ifndef LAME_PSYMODEL_H\n#define LAME_PSYMODEL_H\n\n\nint     L3psycho_anal_ns(lame_internal_flags * gfc,\n                         const sample_t *const buffer[2], int gr,\n                         III_psy_ratio ratio[2][2],\n                         III_psy_ratio MS_ratio[2][2],\n                         FLOAT pe[2], FLOAT pe_MS[2], FLOAT ener[2], int blocktype_d[2]);\n\nint     L3psycho_anal_vbr(lame_internal_flags * gfc,\n                          const sample_t *const buffer[2], int gr,\n                          III_psy_ratio ratio[2][2],\n                          III_psy_ratio MS_ratio[2][2],\n                          FLOAT pe[2], FLOAT pe_MS[2], FLOAT ener[2], int blocktype_d[2]);\n\n\nint     psymodel_init(lame_global_flags const* gfp);\n\n\n#define rpelev 2\n#define rpelev2 16\n#define rpelev_s 2\n#define rpelev2_s 16\n\n/* size of each partition band, in barks: */\n#define DELBARK .34\n\n\n/* tuned for output level (sensitive to energy scale) */\n#define VO_SCALE (1./( 14752*14752 )/(BLKSIZE/2))\n\n#define temporalmask_sustain_sec 0.01\n\n#define NS_PREECHO_ATT0 0.8\n#define NS_PREECHO_ATT1 0.6\n#define NS_PREECHO_ATT2 0.3\n\n#define NS_MSFIX 3.5\n#define NSATTACKTHRE 4.4\n#define NSATTACKTHRE_S 25\n\n#endif /* LAME_PSYMODEL_H */\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/quantize.c",
    "content": "/*\n * MP3 quantization\n *\n *      Copyright (c) 1999-2000 Mark Taylor\n *      Copyright (c) 1999-2003 Takehiro Tominaga\n *      Copyright (c) 2000-2011 Robert Hegemann\n *      Copyright (c) 2001-2005 Gabriel Bouvigne\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.     See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n/* $Id: quantize.c,v 1.216.2.1 2012/01/08 23:49:58 robert Exp $ */\n\n#ifdef HAVE_CONFIG_H\n# include <config.h>\n#endif\n\n#include \"lame.h\"\n#include \"machine.h\"\n#include \"encoder.h\"\n#include \"util.h\"\n#include \"quantize_pvt.h\"\n#include \"reservoir.h\"\n#include \"bitstream.h\"\n#include \"vbrquantize.h\"\n#include \"quantize.h\"\n#ifdef HAVE_XMMINTRIN_H\n#include \"vector/lame_intrin.h\"\n#endif\n\n\n\n\n/* convert from L/R <-> Mid/Side */\nstatic void\nms_convert(III_side_info_t * l3_side, int gr)\n{\n    int     i;\n    for (i = 0; i < 576; ++i) {\n        FLOAT   l, r;\n        l = l3_side->tt[gr][0].xr[i];\n        r = l3_side->tt[gr][1].xr[i];\n        l3_side->tt[gr][0].xr[i] = (l + r) * (FLOAT) (SQRT2 * 0.5);\n        l3_side->tt[gr][1].xr[i] = (l - r) * (FLOAT) (SQRT2 * 0.5);\n    }\n}\n\n/************************************************************************\n *\n *      init_outer_loop()\n *  mt 6/99\n *\n *  initializes cod_info, scalefac and xrpow\n *\n *  returns 0 if all energies in xr are zero, else 1\n *\n ************************************************************************/\n\nstatic void\ninit_xrpow_core_c(gr_info * const cod_info, FLOAT xrpow[576], int upper, FLOAT * sum)\n{\n    int     i;\n    FLOAT   tmp;\n    *sum = 0;\n    for (i = 0; i <= upper; ++i) {\n        tmp = fabs(cod_info->xr[i]);\n        *sum += tmp;\n        xrpow[i] = sqrt(tmp * sqrt(tmp));\n\n        if (xrpow[i] > cod_info->xrpow_max)\n            cod_info->xrpow_max = xrpow[i];\n    }\n}\n\n\n\n\n\nvoid\ninit_xrpow_core_init(lame_internal_flags * const gfc)\n{\n    gfc->init_xrpow_core = init_xrpow_core_c;\n\n#if defined(HAVE_XMMINTRIN_H)\n    if (gfc->CPU_features.SSE)\n        gfc->init_xrpow_core = init_xrpow_core_sse;\n#endif\n#ifndef HAVE_NASM\n#ifdef MIN_ARCH_SSE\n    gfc->init_xrpow_core = init_xrpow_core_sse;\n#endif\n#endif\n}\n\n\n\nstatic int\ninit_xrpow(lame_internal_flags * gfc, gr_info * const cod_info, FLOAT xrpow[576])\n{\n    FLOAT   sum = 0;\n    int     i;\n    int const upper = cod_info->max_nonzero_coeff;\n\n    assert(xrpow != NULL);\n    cod_info->xrpow_max = 0;\n\n    /*  check if there is some energy we have to quantize\n     *  and calculate xrpow matching our fresh scalefactors\n     */\n    assert(0 <= upper && upper <= 575);\n    memset(&(xrpow[upper]), 0, (576 - upper) * sizeof(xrpow[0]));\n\n\n    gfc->init_xrpow_core(cod_info, xrpow, upper, &sum);\n\n    /*  return 1 if we have something to quantize, else 0\n     */\n    if (sum > (FLOAT) 1E-20) {\n        int     j = 0;\n        if (gfc->sv_qnt.substep_shaping & 2)\n            j = 1;\n\n        for (i = 0; i < cod_info->psymax; i++)\n            gfc->sv_qnt.pseudohalf[i] = j;\n\n        return 1;\n    }\n\n    memset(&cod_info->l3_enc[0], 0, sizeof(int) * 576);\n    return 0;\n}\n\n\n\n\n\n/*\nGabriel Bouvigne feb/apr 2003\nAnalog silence detection in partitionned sfb21\nor sfb12 for short blocks\n\nFrom top to bottom of sfb, changes to 0\ncoeffs which are below ath. It stops on the first\ncoeff higher than ath.\n*/\nstatic void\npsfb21_analogsilence(lame_internal_flags const *gfc, gr_info * const cod_info)\n{\n    ATH_t const *const ATH = gfc->ATH;\n    FLOAT  *const xr = cod_info->xr;\n\n    if (cod_info->block_type != SHORT_TYPE) { /* NORM, START or STOP type, but not SHORT blocks */\n        int     gsfb;\n        int     stop = 0;\n        for (gsfb = PSFB21 - 1; gsfb >= 0 && !stop; gsfb--) {\n            int const start = gfc->scalefac_band.psfb21[gsfb];\n            int const end = gfc->scalefac_band.psfb21[gsfb + 1];\n            int     j;\n            FLOAT   ath21;\n            ath21 = athAdjust(ATH->adjust_factor, ATH->psfb21[gsfb], ATH->floor, 0);\n\n            if (gfc->sv_qnt.longfact[21] > 1e-12f)\n                ath21 *= gfc->sv_qnt.longfact[21];\n\n            for (j = end - 1; j >= start; j--) {\n                if (fabs(xr[j]) < ath21)\n                    xr[j] = 0;\n                else {\n                    stop = 1;\n                    break;\n                }\n            }\n        }\n    }\n    else {\n        /*note: short blocks coeffs are reordered */\n        int     block;\n        for (block = 0; block < 3; block++) {\n\n            int     gsfb;\n            int     stop = 0;\n            for (gsfb = PSFB12 - 1; gsfb >= 0 && !stop; gsfb--) {\n                int const start = gfc->scalefac_band.s[12] * 3 +\n                    (gfc->scalefac_band.s[13] - gfc->scalefac_band.s[12]) * block +\n                    (gfc->scalefac_band.psfb12[gsfb] - gfc->scalefac_band.psfb12[0]);\n                int const end =\n                    start + (gfc->scalefac_band.psfb12[gsfb + 1] - gfc->scalefac_band.psfb12[gsfb]);\n                int     j;\n                FLOAT   ath12;\n                ath12 = athAdjust(ATH->adjust_factor, ATH->psfb12[gsfb], ATH->floor, 0);\n\n                if (gfc->sv_qnt.shortfact[12] > 1e-12f)\n                    ath12 *= gfc->sv_qnt.shortfact[12];\n\n                for (j = end - 1; j >= start; j--) {\n                    if (fabs(xr[j]) < ath12)\n                        xr[j] = 0;\n                    else {\n                        stop = 1;\n                        break;\n                    }\n                }\n            }\n        }\n    }\n\n}\n\n\n\n\n\nstatic void\ninit_outer_loop(lame_internal_flags const *gfc, gr_info * const cod_info)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    int     sfb, j;\n    /*  initialize fresh cod_info\n     */\n    cod_info->part2_3_length = 0;\n    cod_info->big_values = 0;\n    cod_info->count1 = 0;\n    cod_info->global_gain = 210;\n    cod_info->scalefac_compress = 0;\n    /* mixed_block_flag, block_type was set in psymodel.c */\n    cod_info->table_select[0] = 0;\n    cod_info->table_select[1] = 0;\n    cod_info->table_select[2] = 0;\n    cod_info->subblock_gain[0] = 0;\n    cod_info->subblock_gain[1] = 0;\n    cod_info->subblock_gain[2] = 0;\n    cod_info->subblock_gain[3] = 0; /* this one is always 0 */\n    cod_info->region0_count = 0;\n    cod_info->region1_count = 0;\n    cod_info->preflag = 0;\n    cod_info->scalefac_scale = 0;\n    cod_info->count1table_select = 0;\n    cod_info->part2_length = 0;\n    if (cfg->samplerate_out <= 8000) {\n      cod_info->sfb_lmax = 17;\n      cod_info->sfb_smin = 9;\n      cod_info->psy_lmax = 17;\n    }\n    else {\n      cod_info->sfb_lmax = SBPSY_l;\n      cod_info->sfb_smin = SBPSY_s;\n      cod_info->psy_lmax = gfc->sv_qnt.sfb21_extra ? SBMAX_l : SBPSY_l;\n    }\n    cod_info->psymax = cod_info->psy_lmax;\n    cod_info->sfbmax = cod_info->sfb_lmax;\n    cod_info->sfbdivide = 11;\n    for (sfb = 0; sfb < SBMAX_l; sfb++) {\n        cod_info->width[sfb]\n            = gfc->scalefac_band.l[sfb + 1] - gfc->scalefac_band.l[sfb];\n        cod_info->window[sfb] = 3; /* which is always 0. */\n    }\n    if (cod_info->block_type == SHORT_TYPE) {\n        FLOAT   ixwork[576];\n        FLOAT  *ix;\n\n        cod_info->sfb_smin = 0;\n        cod_info->sfb_lmax = 0;\n        if (cod_info->mixed_block_flag) {\n            /*\n             *  MPEG-1:      sfbs 0-7 long block, 3-12 short blocks\n             *  MPEG-2(.5):  sfbs 0-5 long block, 3-12 short blocks\n             */\n            cod_info->sfb_smin = 3;\n            cod_info->sfb_lmax = cfg->mode_gr * 2 + 4;\n        }\n        if (cfg->samplerate_out <= 8000) {\n            cod_info->psymax\n                = cod_info->sfb_lmax\n                + 3 * (9 - cod_info->sfb_smin);\n            cod_info->sfbmax = cod_info->sfb_lmax + 3 * (9 - cod_info->sfb_smin);\n        }\n        else {\n            cod_info->psymax\n                = cod_info->sfb_lmax\n                + 3 * ((gfc->sv_qnt.sfb21_extra ? SBMAX_s : SBPSY_s) - cod_info->sfb_smin);\n            cod_info->sfbmax = cod_info->sfb_lmax + 3 * (SBPSY_s - cod_info->sfb_smin);\n        }\n        cod_info->sfbdivide = cod_info->sfbmax - 18;\n        cod_info->psy_lmax = cod_info->sfb_lmax;\n        /* re-order the short blocks, for more efficient encoding below */\n        /* By Takehiro TOMINAGA */\n        /*\n           Within each scalefactor band, data is given for successive\n           time windows, beginning with window 0 and ending with window 2.\n           Within each window, the quantized values are then arranged in\n           order of increasing frequency...\n         */\n        ix = &cod_info->xr[gfc->scalefac_band.l[cod_info->sfb_lmax]];\n        memcpy(ixwork, cod_info->xr, 576 * sizeof(FLOAT));\n        for (sfb = cod_info->sfb_smin; sfb < SBMAX_s; sfb++) {\n            int const start = gfc->scalefac_band.s[sfb];\n            int const end = gfc->scalefac_band.s[sfb + 1];\n            int     window, l;\n            for (window = 0; window < 3; window++) {\n                for (l = start; l < end; l++) {\n                    *ix++ = ixwork[3 * l + window];\n                }\n            }\n        }\n\n        j = cod_info->sfb_lmax;\n        for (sfb = cod_info->sfb_smin; sfb < SBMAX_s; sfb++) {\n            cod_info->width[j] = cod_info->width[j + 1] = cod_info->width[j + 2]\n                = gfc->scalefac_band.s[sfb + 1] - gfc->scalefac_band.s[sfb];\n            cod_info->window[j] = 0;\n            cod_info->window[j + 1] = 1;\n            cod_info->window[j + 2] = 2;\n            j += 3;\n        }\n    }\n\n    cod_info->count1bits = 0;\n    cod_info->sfb_partition_table = nr_of_sfb_block[0][0];\n    cod_info->slen[0] = 0;\n    cod_info->slen[1] = 0;\n    cod_info->slen[2] = 0;\n    cod_info->slen[3] = 0;\n\n    cod_info->max_nonzero_coeff = 575;\n\n    /*  fresh scalefactors are all zero\n     */\n    memset(cod_info->scalefac, 0, sizeof(cod_info->scalefac));\n\n    if (cfg->vbr != vbr_mt && cfg->vbr != vbr_mtrh && cfg->vbr != vbr_abr && cfg->vbr != vbr_off) {\n        psfb21_analogsilence(gfc, cod_info);\n    }\n}\n\n\n\n/************************************************************************\n *\n *      bin_search_StepSize()\n *\n *  author/date??\n *\n *  binary step size search\n *  used by outer_loop to get a quantizer step size to start with\n *\n ************************************************************************/\n\ntypedef enum {\n    BINSEARCH_NONE,\n    BINSEARCH_UP,\n    BINSEARCH_DOWN\n} binsearchDirection_t;\n\nstatic int\nbin_search_StepSize(lame_internal_flags * const gfc, gr_info * const cod_info,\n                    int desired_rate, const int ch, const FLOAT xrpow[576])\n{\n    int     nBits;\n    int     CurrentStep = gfc->sv_qnt.CurrentStep[ch];\n    int     flag_GoneOver = 0;\n    int const start = gfc->sv_qnt.OldValue[ch];\n    binsearchDirection_t Direction = BINSEARCH_NONE;\n    cod_info->global_gain = start;\n    desired_rate -= cod_info->part2_length;\n\n    assert(CurrentStep);\n    for (;;) {\n        int     step;\n        nBits = count_bits(gfc, xrpow, cod_info, 0);\n\n        if (CurrentStep == 1 || nBits == desired_rate)\n            break;      /* nothing to adjust anymore */\n\n        if (nBits > desired_rate) {\n            /* increase Quantize_StepSize */\n            if (Direction == BINSEARCH_DOWN)\n                flag_GoneOver = 1;\n\n            if (flag_GoneOver)\n                CurrentStep /= 2;\n            Direction = BINSEARCH_UP;\n            step = CurrentStep;\n        }\n        else {\n            /* decrease Quantize_StepSize */\n            if (Direction == BINSEARCH_UP)\n                flag_GoneOver = 1;\n\n            if (flag_GoneOver)\n                CurrentStep /= 2;\n            Direction = BINSEARCH_DOWN;\n            step = -CurrentStep;\n        }\n        cod_info->global_gain += step;\n        if (cod_info->global_gain < 0) {\n            cod_info->global_gain = 0;\n            flag_GoneOver = 1;\n        }\n        if (cod_info->global_gain > 255) {\n            cod_info->global_gain = 255;\n            flag_GoneOver = 1;\n        }\n    }\n\n    assert(cod_info->global_gain >= 0);\n    assert(cod_info->global_gain < 256);\n\n    while (nBits > desired_rate && cod_info->global_gain < 255) {\n        cod_info->global_gain++;\n        nBits = count_bits(gfc, xrpow, cod_info, 0);\n    }\n    gfc->sv_qnt.CurrentStep[ch] = (start - cod_info->global_gain >= 4) ? 4 : 2;\n    gfc->sv_qnt.OldValue[ch] = cod_info->global_gain;\n    cod_info->part2_3_length = nBits;\n    return nBits;\n}\n\n\n\n\n/************************************************************************\n *\n *      trancate_smallspectrums()\n *\n *  Takehiro TOMINAGA 2002-07-21\n *\n *  trancate smaller nubmers into 0 as long as the noise threshold is allowed.\n *\n ************************************************************************/\nstatic int\nfloatcompare(const void *v1, const void *v2)\n{\n    const FLOAT *const a = v1, *const b = v2;\n    if (*a > *b)\n        return 1;\n    if (*a < *b)\n        return -1;\n    return 0;\n}\n\nstatic void\ntrancate_smallspectrums(lame_internal_flags const *gfc,\n                        gr_info * const gi, const FLOAT * const l3_xmin, FLOAT * const work)\n{\n    int     sfb, j, width;\n    FLOAT   distort[SFBMAX];\n    calc_noise_result dummy;\n\n    if ((!(gfc->sv_qnt.substep_shaping & 4) && gi->block_type == SHORT_TYPE)\n        || gfc->sv_qnt.substep_shaping & 0x80)\n        return;\n    (void) calc_noise(gi, l3_xmin, distort, &dummy, 0);\n    for (j = 0; j < 576; j++) {\n        FLOAT   xr = 0.0;\n        if (gi->l3_enc[j] != 0)\n            xr = fabs(gi->xr[j]);\n        work[j] = xr;\n    }\n\n    j = 0;\n    sfb = 8;\n    if (gi->block_type == SHORT_TYPE)\n        sfb = 6;\n    do {\n        FLOAT   allowedNoise, trancateThreshold;\n        int     nsame, start;\n\n        width = gi->width[sfb];\n        j += width;\n        if (distort[sfb] >= 1.0)\n            continue;\n\n        qsort(&work[j - width], width, sizeof(FLOAT), floatcompare);\n        if (EQ(work[j - 1], 0.0))\n            continue;   /* all zero sfb */\n\n        allowedNoise = (1.0 - distort[sfb]) * l3_xmin[sfb];\n        trancateThreshold = 0.0;\n        start = 0;\n        do {\n            FLOAT   noise;\n            for (nsame = 1; start + nsame < width; nsame++)\n                if (NEQ(work[start + j - width], work[start + j + nsame - width]))\n                    break;\n\n            noise = work[start + j - width] * work[start + j - width] * nsame;\n            if (allowedNoise < noise) {\n                if (start != 0)\n                    trancateThreshold = work[start + j - width - 1];\n                break;\n            }\n            allowedNoise -= noise;\n            start += nsame;\n        } while (start < width);\n        if (EQ(trancateThreshold, 0.0))\n            continue;\n\n/*      printf(\"%e %e %e\\n\", */\n/*             trancateThreshold/l3_xmin[sfb], */\n/*             trancateThreshold/(l3_xmin[sfb]*start), */\n/*             trancateThreshold/(l3_xmin[sfb]*(start+width)) */\n/*          ); */\n/*      if (trancateThreshold > 1000*l3_xmin[sfb]*start) */\n/*          trancateThreshold = 1000*l3_xmin[sfb]*start; */\n\n        do {\n            if (fabs(gi->xr[j - width]) <= trancateThreshold)\n                gi->l3_enc[j - width] = 0;\n        } while (--width > 0);\n    } while (++sfb < gi->psymax);\n\n    gi->part2_3_length = noquant_count_bits(gfc, gi, 0);\n}\n\n\n/*************************************************************************\n *\n *      loop_break()\n *\n *  author/date??\n *\n *  Function: Returns zero if there is a scalefac which has not been\n *            amplified. Otherwise it returns one.\n *\n *************************************************************************/\n\ninline static int\nloop_break(const gr_info * const cod_info)\n{\n    int     sfb;\n\n    for (sfb = 0; sfb < cod_info->sfbmax; sfb++)\n        if (cod_info->scalefac[sfb]\n            + cod_info->subblock_gain[cod_info->window[sfb]] == 0)\n            return 0;\n\n    return 1;\n}\n\n\n\n\n/*  mt 5/99:  Function: Improved calc_noise for a single channel   */\n\n/*************************************************************************\n *\n *      quant_compare()\n *\n *  author/date??\n *\n *  several different codes to decide which quantization is better\n *\n *************************************************************************/\n\nstatic double\npenalties(double noise)\n{\n    return FAST_LOG10(0.368 + 0.632 * noise * noise * noise);\n}\n\nstatic double\nget_klemm_noise(const FLOAT * distort, const gr_info * const gi)\n{\n    int     sfb;\n    double  klemm_noise = 1E-37;\n    for (sfb = 0; sfb < gi->psymax; sfb++)\n        klemm_noise += penalties(distort[sfb]);\n\n    return Max(1e-20, klemm_noise);\n}\n\ninline static int\nquant_compare(const int quant_comp,\n              const calc_noise_result * const best,\n              calc_noise_result * const calc, const gr_info * const gi, const FLOAT * distort)\n{\n    /*\n       noise is given in decibels (dB) relative to masking thesholds.\n\n       over_noise:  ??? (the previous comment is fully wrong)\n       tot_noise:   ??? (the previous comment is fully wrong)\n       max_noise:   max quantization noise\n\n     */\n    int     better;\n\n    switch (quant_comp) {\n    default:\n    case 9:{\n            if (best->over_count > 0) {\n                /* there are distorted sfb */\n                better = calc->over_SSD <= best->over_SSD;\n                if (calc->over_SSD == best->over_SSD)\n                    better = calc->bits < best->bits;\n            }\n            else {\n                /* no distorted sfb */\n                better = ((calc->max_noise < 0) &&\n                          ((calc->max_noise * 10 + calc->bits) <=\n                           (best->max_noise * 10 + best->bits)));\n            }\n            break;\n        }\n\n    case 0:\n        better = calc->over_count < best->over_count\n            || (calc->over_count == best->over_count && calc->over_noise < best->over_noise)\n            || (calc->over_count == best->over_count &&\n                EQ(calc->over_noise, best->over_noise) && calc->tot_noise < best->tot_noise);\n        break;\n\n    case 8:\n        calc->max_noise = get_klemm_noise(distort, gi);\n        /*lint --fallthrough */\n    case 1:\n        better = calc->max_noise < best->max_noise;\n        break;\n    case 2:\n        better = calc->tot_noise < best->tot_noise;\n        break;\n    case 3:\n        better = (calc->tot_noise < best->tot_noise)\n            && (calc->max_noise < best->max_noise);\n        break;\n    case 4:\n        better = (calc->max_noise <= 0.0 && best->max_noise > 0.2)\n            || (calc->max_noise <= 0.0 &&\n                best->max_noise < 0.0 &&\n                best->max_noise > calc->max_noise - 0.2 && calc->tot_noise < best->tot_noise)\n            || (calc->max_noise <= 0.0 &&\n                best->max_noise > 0.0 &&\n                best->max_noise > calc->max_noise - 0.2 &&\n                calc->tot_noise < best->tot_noise + best->over_noise)\n            || (calc->max_noise > 0.0 &&\n                best->max_noise > -0.05 &&\n                best->max_noise > calc->max_noise - 0.1 &&\n                calc->tot_noise + calc->over_noise < best->tot_noise + best->over_noise)\n            || (calc->max_noise > 0.0 &&\n                best->max_noise > -0.1 &&\n                best->max_noise > calc->max_noise - 0.15 &&\n                calc->tot_noise + calc->over_noise + calc->over_noise <\n                best->tot_noise + best->over_noise + best->over_noise);\n        break;\n    case 5:\n        better = calc->over_noise < best->over_noise\n            || (EQ(calc->over_noise, best->over_noise) && calc->tot_noise < best->tot_noise);\n        break;\n    case 6:\n        better = calc->over_noise < best->over_noise\n            || (EQ(calc->over_noise, best->over_noise) &&\n                (calc->max_noise < best->max_noise\n                 || (EQ(calc->max_noise, best->max_noise) && calc->tot_noise <= best->tot_noise)\n                ));\n        break;\n    case 7:\n        better = calc->over_count < best->over_count || calc->over_noise < best->over_noise;\n        break;\n    }\n\n\n    if (best->over_count == 0) {\n        /*\n           If no distorted bands, only use this quantization\n           if it is better, and if it uses less bits.\n           Unfortunately, part2_3_length is sometimes a poor\n           estimator of the final size at low bitrates.\n         */\n        better = better && calc->bits < best->bits;\n    }\n\n\n    return better;\n}\n\n\n\n/*************************************************************************\n *\n *          amp_scalefac_bands()\n *\n *  author/date??\n *\n *  Amplify the scalefactor bands that violate the masking threshold.\n *  See ISO 11172-3 Section C.1.5.4.3.5\n *\n *  distort[] = noise/masking\n *  distort[] > 1   ==> noise is not masked\n *  distort[] < 1   ==> noise is masked\n *  max_dist = maximum value of distort[]\n *\n *  Three algorithms:\n *  noise_shaping_amp\n *        0             Amplify all bands with distort[]>1.\n *\n *        1             Amplify all bands with distort[] >= max_dist^(.5);\n *                     ( 50% in the db scale)\n *\n *        2             Amplify first band with distort[] >= max_dist;\n *\n *\n *  For algorithms 0 and 1, if max_dist < 1, then amplify all bands\n *  with distort[] >= .95*max_dist.  This is to make sure we always\n *  amplify at least one band.\n *\n *\n *************************************************************************/\nstatic void\namp_scalefac_bands(lame_internal_flags * gfc,\n                   gr_info * const cod_info, FLOAT const *distort, FLOAT xrpow[576], int bRefine)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    int     j, sfb;\n    FLOAT   ifqstep34, trigger;\n    int     noise_shaping_amp;\n\n    if (cod_info->scalefac_scale == 0) {\n        ifqstep34 = 1.29683955465100964055; /* 2**(.75*.5) */\n    }\n    else {\n        ifqstep34 = 1.68179283050742922612; /* 2**(.75*1) */\n    }\n\n    /* compute maximum value of distort[]  */\n    trigger = 0;\n    for (sfb = 0; sfb < cod_info->sfbmax; sfb++) {\n        if (trigger < distort[sfb])\n            trigger = distort[sfb];\n    }\n\n    noise_shaping_amp = cfg->noise_shaping_amp;\n    if (noise_shaping_amp == 3) {\n        if (bRefine == 1)\n            noise_shaping_amp = 2;\n        else\n            noise_shaping_amp = 1;\n    }\n    switch (noise_shaping_amp) {\n    case 2:\n        /* amplify exactly 1 band */\n        break;\n\n    case 1:\n        /* amplify bands within 50% of max (on db scale) */\n        if (trigger > 1.0)\n            trigger = pow(trigger, .5);\n        else\n            trigger *= .95;\n        break;\n\n    case 0:\n    default:\n        /* ISO algorithm.  amplify all bands with distort>1 */\n        if (trigger > 1.0)\n            trigger = 1.0;\n        else\n            trigger *= .95;\n        break;\n    }\n\n    j = 0;\n    for (sfb = 0; sfb < cod_info->sfbmax; sfb++) {\n        int const width = cod_info->width[sfb];\n        int     l;\n        j += width;\n        if (distort[sfb] < trigger)\n            continue;\n\n        if (gfc->sv_qnt.substep_shaping & 2) {\n            gfc->sv_qnt.pseudohalf[sfb] = !gfc->sv_qnt.pseudohalf[sfb];\n            if (!gfc->sv_qnt.pseudohalf[sfb] && cfg->noise_shaping_amp == 2)\n                return;\n        }\n        cod_info->scalefac[sfb]++;\n        for (l = -width; l < 0; l++) {\n            xrpow[j + l] *= ifqstep34;\n            if (xrpow[j + l] > cod_info->xrpow_max)\n                cod_info->xrpow_max = xrpow[j + l];\n        }\n\n        if (cfg->noise_shaping_amp == 2)\n            return;\n    }\n}\n\n/*************************************************************************\n *\n *      inc_scalefac_scale()\n *\n *  Takehiro Tominaga 2000-xx-xx\n *\n *  turns on scalefac scale and adjusts scalefactors\n *\n *************************************************************************/\n\nstatic void\ninc_scalefac_scale(gr_info * const cod_info, FLOAT xrpow[576])\n{\n    int     l, j, sfb;\n    const FLOAT ifqstep34 = 1.29683955465100964055;\n\n    j = 0;\n    for (sfb = 0; sfb < cod_info->sfbmax; sfb++) {\n        int const width = cod_info->width[sfb];\n        int     s = cod_info->scalefac[sfb];\n        if (cod_info->preflag)\n            s += pretab[sfb];\n        j += width;\n        if (s & 1) {\n            s++;\n            for (l = -width; l < 0; l++) {\n                xrpow[j + l] *= ifqstep34;\n                if (xrpow[j + l] > cod_info->xrpow_max)\n                    cod_info->xrpow_max = xrpow[j + l];\n            }\n        }\n        cod_info->scalefac[sfb] = s >> 1;\n    }\n    cod_info->preflag = 0;\n    cod_info->scalefac_scale = 1;\n}\n\n\n\n/*************************************************************************\n *\n *      inc_subblock_gain()\n *\n *  Takehiro Tominaga 2000-xx-xx\n *\n *  increases the subblock gain and adjusts scalefactors\n *\n *************************************************************************/\n\nstatic int\ninc_subblock_gain(const lame_internal_flags * const gfc, gr_info * const cod_info, FLOAT xrpow[576])\n{\n    int     sfb, window;\n    int    *const scalefac = cod_info->scalefac;\n\n    /* subbloc_gain can't do anything in the long block region */\n    for (sfb = 0; sfb < cod_info->sfb_lmax; sfb++) {\n        if (scalefac[sfb] >= 16)\n            return 1;\n    }\n\n    for (window = 0; window < 3; window++) {\n        int     s1, s2, l, j;\n        s1 = s2 = 0;\n\n        for (sfb = cod_info->sfb_lmax + window; sfb < cod_info->sfbdivide; sfb += 3) {\n            if (s1 < scalefac[sfb])\n                s1 = scalefac[sfb];\n        }\n        for (; sfb < cod_info->sfbmax; sfb += 3) {\n            if (s2 < scalefac[sfb])\n                s2 = scalefac[sfb];\n        }\n\n        if (s1 < 16 && s2 < 8)\n            continue;\n\n        if (cod_info->subblock_gain[window] >= 7)\n            return 1;\n\n        /* even though there is no scalefactor for sfb12\n         * subblock gain affects upper frequencies too, that's why\n         * we have to go up to SBMAX_s\n         */\n        cod_info->subblock_gain[window]++;\n        j = gfc->scalefac_band.l[cod_info->sfb_lmax];\n        for (sfb = cod_info->sfb_lmax + window; sfb < cod_info->sfbmax; sfb += 3) {\n            FLOAT   amp;\n            int const width = cod_info->width[sfb];\n            int     s = scalefac[sfb];\n            assert(s >= 0);\n            s = s - (4 >> cod_info->scalefac_scale);\n            if (s >= 0) {\n                scalefac[sfb] = s;\n                j += width * 3;\n                continue;\n            }\n\n            scalefac[sfb] = 0;\n            {\n                int const gain = 210 + (s << (cod_info->scalefac_scale + 1));\n                amp = IPOW20(gain);\n            }\n            j += width * (window + 1);\n            for (l = -width; l < 0; l++) {\n                xrpow[j + l] *= amp;\n                if (xrpow[j + l] > cod_info->xrpow_max)\n                    cod_info->xrpow_max = xrpow[j + l];\n            }\n            j += width * (3 - window - 1);\n        }\n\n        {\n            FLOAT const amp = IPOW20(202);\n            j += cod_info->width[sfb] * (window + 1);\n            for (l = -cod_info->width[sfb]; l < 0; l++) {\n                xrpow[j + l] *= amp;\n                if (xrpow[j + l] > cod_info->xrpow_max)\n                    cod_info->xrpow_max = xrpow[j + l];\n            }\n        }\n    }\n    return 0;\n}\n\n\n\n/********************************************************************\n *\n *      balance_noise()\n *\n *  Takehiro Tominaga /date??\n *  Robert Hegemann 2000-09-06: made a function of it\n *\n *  amplifies scalefactor bands,\n *   - if all are already amplified returns 0\n *   - if some bands are amplified too much:\n *      * try to increase scalefac_scale\n *      * if already scalefac_scale was set\n *          try on short blocks to increase subblock gain\n *\n ********************************************************************/\ninline static int\nbalance_noise(lame_internal_flags * gfc,\n              gr_info * const cod_info, FLOAT const *distort, FLOAT xrpow[576], int bRefine)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    int     status;\n\n    amp_scalefac_bands(gfc, cod_info, distort, xrpow, bRefine);\n\n    /* check to make sure we have not amplified too much\n     * loop_break returns 0 if there is an unamplified scalefac\n     * scale_bitcount returns 0 if no scalefactors are too large\n     */\n\n    status = loop_break(cod_info);\n\n    if (status)\n        return 0;       /* all bands amplified */\n\n    /* not all scalefactors have been amplified.  so these\n     * scalefacs are possibly valid.  encode them:\n     */\n    status = scale_bitcount(gfc, cod_info);\n\n    if (!status)\n        return 1;       /* amplified some bands not exceeding limits */\n\n    /*  some scalefactors are too large.\n     *  lets try setting scalefac_scale=1\n     */\n    if (cfg->noise_shaping > 1) {\n        memset(&gfc->sv_qnt.pseudohalf[0], 0, sizeof(gfc->sv_qnt.pseudohalf));\n        if (!cod_info->scalefac_scale) {\n            inc_scalefac_scale(cod_info, xrpow);\n            status = 0;\n        }\n        else {\n            if (cod_info->block_type == SHORT_TYPE && cfg->subblock_gain > 0) {\n                status = inc_subblock_gain(gfc, cod_info, xrpow)\n                    || loop_break(cod_info);\n            }\n        }\n    }\n\n    if (!status) {\n        status = scale_bitcount(gfc, cod_info);\n    }\n    return !status;\n}\n\n\n\n/************************************************************************\n *\n *  outer_loop ()\n *\n *  Function: The outer iteration loop controls the masking conditions\n *  of all scalefactorbands. It computes the best scalefac and\n *  global gain. This module calls the inner iteration loop\n *\n *  mt 5/99 completely rewritten to allow for bit reservoir control,\n *  mid/side channels with L/R or mid/side masking thresholds,\n *  and chooses best quantization instead of last quantization when\n *  no distortion free quantization can be found.\n *\n *  added VBR support mt 5/99\n *\n *  some code shuffle rh 9/00\n ************************************************************************/\n\nstatic int\nouter_loop(lame_internal_flags * gfc, gr_info * const cod_info, const FLOAT * const l3_xmin, /* allowed distortion */\n           FLOAT xrpow[576], /* coloured magnitudes of spectral */\n           const int ch, const int targ_bits)\n{                       /* maximum allowed bits */\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    gr_info cod_info_w;\n    FLOAT   save_xrpow[576];\n    FLOAT   distort[SFBMAX];\n    calc_noise_result best_noise_info;\n    int     huff_bits;\n    int     better;\n    int     age;\n    calc_noise_data prev_noise;\n    int     best_part2_3_length = 9999999;\n    int     bEndOfSearch = 0;\n    int     bRefine = 0;\n    int     best_ggain_pass1 = 0;\n\n    (void) bin_search_StepSize(gfc, cod_info, targ_bits, ch, xrpow);\n\n    if (!cfg->noise_shaping)\n        /* fast mode, no noise shaping, we are ready */\n        return 100;     /* default noise_info.over_count */\n\n    memset(&prev_noise, 0, sizeof(calc_noise_data));\n\n\n    /* compute the distortion in this quantization */\n    /* coefficients and thresholds both l/r (or both mid/side) */\n    (void) calc_noise(cod_info, l3_xmin, distort, &best_noise_info, &prev_noise);\n    best_noise_info.bits = cod_info->part2_3_length;\n\n    cod_info_w = *cod_info;\n    age = 0;\n    /* if (cfg->vbr == vbr_rh || cfg->vbr == vbr_mtrh) */\n    memcpy(save_xrpow, xrpow, sizeof(FLOAT) * 576);\n\n    while (!bEndOfSearch) {\n        /* BEGIN MAIN LOOP */\n        do {\n            calc_noise_result noise_info;\n            int     search_limit;\n            int     maxggain = 255;\n\n            /* When quantization with no distorted bands is found,\n             * allow up to X new unsuccesful tries in serial. This\n             * gives us more possibilities for different quant_compare modes.\n             * Much more than 3 makes not a big difference, it is only slower.\n             */\n\n            if (gfc->sv_qnt.substep_shaping & 2) {\n                search_limit = 20;\n            }\n            else {\n                search_limit = 3;\n            }\n\n\n\n            /* Check if the last scalefactor band is distorted.\n             * in VBR mode we can't get rid of the distortion, so quit now\n             * and VBR mode will try again with more bits.\n             * (makes a 10% speed increase, the files I tested were\n             * binary identical, 2000/05/20 Robert Hegemann)\n             * distort[] > 1 means noise > allowed noise\n             */\n            if (gfc->sv_qnt.sfb21_extra) {\n                if (distort[cod_info_w.sfbmax] > 1.0)\n                    break;\n                if (cod_info_w.block_type == SHORT_TYPE\n                    && (distort[cod_info_w.sfbmax + 1] > 1.0\n                        || distort[cod_info_w.sfbmax + 2] > 1.0))\n                    break;\n            }\n\n            /* try a new scalefactor conbination on cod_info_w */\n            if (balance_noise(gfc, &cod_info_w, distort, xrpow, bRefine) == 0)\n                break;\n            if (cod_info_w.scalefac_scale)\n                maxggain = 254;\n\n            /* inner_loop starts with the initial quantization step computed above\n             * and slowly increases until the bits < huff_bits.\n             * Thus it is important not to start with too large of an inital\n             * quantization step.  Too small is ok, but inner_loop will take longer\n             */\n            huff_bits = targ_bits - cod_info_w.part2_length;\n            if (huff_bits <= 0)\n                break;\n\n            /*  increase quantizer stepsize until needed bits are below maximum\n             */\n            while ((cod_info_w.part2_3_length\n                    = count_bits(gfc, xrpow, &cod_info_w, &prev_noise)) > huff_bits\n                   && cod_info_w.global_gain <= maxggain)\n                cod_info_w.global_gain++;\n\n            if (cod_info_w.global_gain > maxggain)\n                break;\n\n            if (best_noise_info.over_count == 0) {\n\n                while ((cod_info_w.part2_3_length\n                        = count_bits(gfc, xrpow, &cod_info_w, &prev_noise)) > best_part2_3_length\n                       && cod_info_w.global_gain <= maxggain)\n                    cod_info_w.global_gain++;\n\n                if (cod_info_w.global_gain > maxggain)\n                    break;\n            }\n\n            /* compute the distortion in this quantization */\n            (void) calc_noise(&cod_info_w, l3_xmin, distort, &noise_info, &prev_noise);\n            noise_info.bits = cod_info_w.part2_3_length;\n\n            /* check if this quantization is better\n             * than our saved quantization */\n            if (cod_info->block_type != SHORT_TYPE) /* NORM, START or STOP type */\n                better = cfg->quant_comp;\n            else\n                better = cfg->quant_comp_short;\n\n\n            better = quant_compare(better, &best_noise_info, &noise_info, &cod_info_w, distort);\n\n\n            /* save data so we can restore this quantization later */\n            if (better) {\n                best_part2_3_length = cod_info->part2_3_length;\n                best_noise_info = noise_info;\n                *cod_info = cod_info_w;\n                age = 0;\n                /* save data so we can restore this quantization later */\n                /*if (cfg->vbr == vbr_rh || cfg->vbr == vbr_mtrh) */  {\n                    /* store for later reuse */\n                    memcpy(save_xrpow, xrpow, sizeof(FLOAT) * 576);\n                }\n            }\n            else {\n                /* early stop? */\n                if (cfg->full_outer_loop == 0) {\n                    if (++age > search_limit && best_noise_info.over_count == 0)\n                        break;\n                    if ((cfg->noise_shaping_amp == 3) && bRefine && age > 30)\n                        break;\n                    if ((cfg->noise_shaping_amp == 3) && bRefine &&\n                        (cod_info_w.global_gain - best_ggain_pass1) > 15)\n                        break;\n                }\n            }\n        }\n        while ((cod_info_w.global_gain + cod_info_w.scalefac_scale) < 255);\n\n        if (cfg->noise_shaping_amp == 3) {\n            if (!bRefine) {\n                /* refine search */\n                cod_info_w = *cod_info;\n                memcpy(xrpow, save_xrpow, sizeof(FLOAT) * 576);\n                age = 0;\n                best_ggain_pass1 = cod_info_w.global_gain;\n\n                bRefine = 1;\n            }\n            else {\n                /* search already refined, stop */\n                bEndOfSearch = 1;\n            }\n\n        }\n        else {\n            bEndOfSearch = 1;\n        }\n    }\n\n    assert((cod_info->global_gain + cod_info->scalefac_scale) <= 255);\n    /*  finish up\n     */\n    if (cfg->vbr == vbr_rh || cfg->vbr == vbr_mtrh || cfg->vbr == vbr_mt)\n        /* restore for reuse on next try */\n        memcpy(xrpow, save_xrpow, sizeof(FLOAT) * 576);\n    /*  do the 'substep shaping'\n     */\n    else if (gfc->sv_qnt.substep_shaping & 1)\n        trancate_smallspectrums(gfc, cod_info, l3_xmin, xrpow);\n\n    return best_noise_info.over_count;\n}\n\n\n\n\n\n/************************************************************************\n *\n *      iteration_finish_one()\n *\n *  Robert Hegemann 2000-09-06\n *\n *  update reservoir status after FINAL quantization/bitrate\n *\n ************************************************************************/\n\nstatic void\niteration_finish_one(lame_internal_flags * gfc, int gr, int ch)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    III_side_info_t *const l3_side = &gfc->l3_side;\n    gr_info *const cod_info = &l3_side->tt[gr][ch];\n\n    /*  try some better scalefac storage\n     */\n    best_scalefac_store(gfc, gr, ch, l3_side);\n\n    /*  best huffman_divide may save some bits too\n     */\n    if (cfg->use_best_huffman == 1)\n        best_huffman_divide(gfc, cod_info);\n\n    /*  update reservoir status after FINAL quantization/bitrate\n     */\n    ResvAdjust(gfc, cod_info);\n}\n\n\n\n/*********************************************************************\n *\n *      VBR_encode_granule()\n *\n *  2000-09-04 Robert Hegemann\n *\n *********************************************************************/\n\nstatic void\nVBR_encode_granule(lame_internal_flags * gfc, gr_info * const cod_info, const FLOAT * const l3_xmin, /* allowed distortion of the scalefactor */\n                   FLOAT xrpow[576], /* coloured magnitudes of spectral values */\n                   const int ch, int min_bits, int max_bits)\n{\n    gr_info bst_cod_info;\n    FLOAT   bst_xrpow[576];\n    int const Max_bits = max_bits;\n    int     real_bits = max_bits + 1;\n    int     this_bits = (max_bits + min_bits) / 2;\n    int     dbits, over, found = 0;\n    int const sfb21_extra = gfc->sv_qnt.sfb21_extra;\n\n    assert(Max_bits <= MAX_BITS_PER_CHANNEL);\n    memset(bst_cod_info.l3_enc, 0, sizeof(bst_cod_info.l3_enc));\n\n    /*  search within round about 40 bits of optimal\n     */\n    do {\n        assert(this_bits >= min_bits);\n        assert(this_bits <= max_bits);\n        assert(min_bits <= max_bits);\n\n        if (this_bits > Max_bits - 42)\n            gfc->sv_qnt.sfb21_extra = 0;\n        else\n            gfc->sv_qnt.sfb21_extra = sfb21_extra;\n\n        over = outer_loop(gfc, cod_info, l3_xmin, xrpow, ch, this_bits);\n\n        /*  is quantization as good as we are looking for ?\n         *  in this case: is no scalefactor band distorted?\n         */\n        if (over <= 0) {\n            found = 1;\n            /*  now we know it can be done with \"real_bits\"\n             *  and maybe we can skip some iterations\n             */\n            real_bits = cod_info->part2_3_length;\n\n            /*  store best quantization so far\n             */\n            bst_cod_info = *cod_info;\n            memcpy(bst_xrpow, xrpow, sizeof(FLOAT) * 576);\n\n            /*  try with fewer bits\n             */\n            max_bits = real_bits - 32;\n            dbits = max_bits - min_bits;\n            this_bits = (max_bits + min_bits) / 2;\n        }\n        else {\n            /*  try with more bits\n             */\n            min_bits = this_bits + 32;\n            dbits = max_bits - min_bits;\n            this_bits = (max_bits + min_bits) / 2;\n\n            if (found) {\n                found = 2;\n                /*  start again with best quantization so far\n                 */\n                *cod_info = bst_cod_info;\n                memcpy(xrpow, bst_xrpow, sizeof(FLOAT) * 576);\n            }\n        }\n    } while (dbits > 12);\n\n    gfc->sv_qnt.sfb21_extra = sfb21_extra;\n\n    /*  found=0 => nothing found, use last one\n     *  found=1 => we just found the best and left the loop\n     *  found=2 => we restored a good one and have now l3_enc to restore too\n     */\n    if (found == 2) {\n        memcpy(cod_info->l3_enc, bst_cod_info.l3_enc, sizeof(int) * 576);\n    }\n    assert(cod_info->part2_3_length <= Max_bits);\n\n}\n\n\n\n/************************************************************************\n *\n *      get_framebits()\n *\n *  Robert Hegemann 2000-09-05\n *\n *  calculates\n *  * how many bits are available for analog silent granules\n *  * how many bits to use for the lowest allowed bitrate\n *  * how many bits each bitrate would provide\n *\n ************************************************************************/\n\nstatic void\nget_framebits(lame_internal_flags * gfc, int frameBits[15])\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    EncResult_t *const eov = &gfc->ov_enc;\n    int     bitsPerFrame, i;\n\n    /*  always use at least this many bits per granule per channel\n     *  unless we detect analog silence, see below\n     */\n    eov->bitrate_index = cfg->vbr_min_bitrate_index;\n    bitsPerFrame = getframebits(gfc);\n\n    /*  bits for analog silence\n     */\n    eov->bitrate_index = 1;\n    bitsPerFrame = getframebits(gfc);\n\n    for (i = 1; i <= cfg->vbr_max_bitrate_index; i++) {\n        eov->bitrate_index = i;\n        frameBits[i] = ResvFrameBegin(gfc, &bitsPerFrame);\n    }\n}\n\n\n\n/*********************************************************************\n *\n *      VBR_prepare()\n *\n *  2000-09-04 Robert Hegemann\n *\n *  * converts LR to MS coding when necessary\n *  * calculates allowed/adjusted quantization noise amounts\n *  * detects analog silent frames\n *\n *  some remarks:\n *  - lower masking depending on Quality setting\n *  - quality control together with adjusted ATH MDCT scaling\n *    on lower quality setting allocate more noise from\n *    ATH masking, and on higher quality setting allocate\n *    less noise from ATH masking.\n *  - experiments show that going more than 2dB over GPSYCHO's\n *    limits ends up in very annoying artefacts\n *\n *********************************************************************/\n\n/* RH: this one needs to be overhauled sometime */\n\nstatic int\nVBR_old_prepare(lame_internal_flags * gfc,\n                const FLOAT pe[2][2], FLOAT const ms_ener_ratio[2],\n                const III_psy_ratio ratio[2][2],\n                FLOAT l3_xmin[2][2][SFBMAX],\n                int frameBits[16], int min_bits[2][2], int max_bits[2][2], int bands[2][2])\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    EncResult_t *const eov = &gfc->ov_enc;\n\n    FLOAT   masking_lower_db, adjust = 0.0;\n    int     gr, ch;\n    int     analog_silence = 1;\n    int     avg, mxb, bits = 0;\n\n    eov->bitrate_index = cfg->vbr_max_bitrate_index;\n    avg = ResvFrameBegin(gfc, &avg) / cfg->mode_gr;\n\n    get_framebits(gfc, frameBits);\n\n    for (gr = 0; gr < cfg->mode_gr; gr++) {\n        mxb = on_pe(gfc, pe, max_bits[gr], avg, gr, 0);\n        if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR) {\n            ms_convert(&gfc->l3_side, gr);\n            reduce_side(max_bits[gr], ms_ener_ratio[gr], avg, mxb);\n        }\n        for (ch = 0; ch < cfg->channels_out; ++ch) {\n            gr_info *const cod_info = &gfc->l3_side.tt[gr][ch];\n\n            if (cod_info->block_type != SHORT_TYPE) { /* NORM, START or STOP type */\n                adjust = 1.28 / (1 + exp(3.5 - pe[gr][ch] / 300.)) - 0.05;\n                masking_lower_db = gfc->sv_qnt.mask_adjust - adjust;\n            }\n            else {\n                adjust = 2.56 / (1 + exp(3.5 - pe[gr][ch] / 300.)) - 0.14;\n                masking_lower_db = gfc->sv_qnt.mask_adjust_short - adjust;\n            }\n            gfc->sv_qnt.masking_lower = pow(10.0, masking_lower_db * 0.1);\n\n            init_outer_loop(gfc, cod_info);\n            bands[gr][ch] = calc_xmin(gfc, &ratio[gr][ch], cod_info, l3_xmin[gr][ch]);\n            if (bands[gr][ch])\n                analog_silence = 0;\n\n            min_bits[gr][ch] = 126;\n\n            bits += max_bits[gr][ch];\n        }\n    }\n    for (gr = 0; gr < cfg->mode_gr; gr++) {\n        for (ch = 0; ch < cfg->channels_out; ch++) {\n            if (bits > frameBits[cfg->vbr_max_bitrate_index] && bits > 0) {\n                max_bits[gr][ch] *= frameBits[cfg->vbr_max_bitrate_index];\n                max_bits[gr][ch] /= bits;\n            }\n            if (min_bits[gr][ch] > max_bits[gr][ch])\n                min_bits[gr][ch] = max_bits[gr][ch];\n\n        }               /* for ch */\n    }                   /* for gr */\n\n    return analog_silence;\n}\n\nstatic void\nbitpressure_strategy(lame_internal_flags const *gfc,\n                     FLOAT l3_xmin[2][2][SFBMAX], const int min_bits[2][2], int max_bits[2][2])\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    int     gr, ch, sfb;\n    for (gr = 0; gr < cfg->mode_gr; gr++) {\n        for (ch = 0; ch < cfg->channels_out; ch++) {\n            gr_info const *const gi = &gfc->l3_side.tt[gr][ch];\n            FLOAT  *pxmin = l3_xmin[gr][ch];\n            for (sfb = 0; sfb < gi->psy_lmax; sfb++)\n                *pxmin++ *= 1. + .029 * sfb * sfb / SBMAX_l / SBMAX_l;\n\n            if (gi->block_type == SHORT_TYPE) {\n                for (sfb = gi->sfb_smin; sfb < SBMAX_s; sfb++) {\n                    *pxmin++ *= 1. + .029 * sfb * sfb / SBMAX_s / SBMAX_s;\n                    *pxmin++ *= 1. + .029 * sfb * sfb / SBMAX_s / SBMAX_s;\n                    *pxmin++ *= 1. + .029 * sfb * sfb / SBMAX_s / SBMAX_s;\n                }\n            }\n            max_bits[gr][ch] = Max(min_bits[gr][ch], 0.9 * max_bits[gr][ch]);\n        }\n    }\n}\n\n/************************************************************************\n *\n *      VBR_iteration_loop()\n *\n *  tries to find out how many bits are needed for each granule and channel\n *  to get an acceptable quantization. An appropriate bitrate will then be\n *  choosed for quantization.  rh 8/99\n *\n *  Robert Hegemann 2000-09-06 rewrite\n *\n ************************************************************************/\n\nvoid\nVBR_old_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2],\n                       const FLOAT ms_ener_ratio[2], const III_psy_ratio ratio[2][2])\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    EncResult_t *const eov = &gfc->ov_enc;\n    FLOAT   l3_xmin[2][2][SFBMAX];\n\n    FLOAT   xrpow[576];\n    int     bands[2][2];\n    int     frameBits[15];\n    int     used_bits;\n    int     bits;\n    int     min_bits[2][2], max_bits[2][2];\n    int     mean_bits;\n    int     ch, gr, analog_silence;\n    III_side_info_t *const l3_side = &gfc->l3_side;\n\n    analog_silence = VBR_old_prepare(gfc, pe, ms_ener_ratio, ratio,\n                                     l3_xmin, frameBits, min_bits, max_bits, bands);\n\n    /*---------------------------------*/\n    for (;;) {\n\n        /*  quantize granules with lowest possible number of bits\n         */\n\n        used_bits = 0;\n\n        for (gr = 0; gr < cfg->mode_gr; gr++) {\n            for (ch = 0; ch < cfg->channels_out; ch++) {\n                int     ret;\n                gr_info *const cod_info = &l3_side->tt[gr][ch];\n\n                /*  init_outer_loop sets up cod_info, scalefac and xrpow\n                 */\n                ret = init_xrpow(gfc, cod_info, xrpow);\n                if (ret == 0 || max_bits[gr][ch] == 0) {\n                    /*  xr contains no energy\n                     *  l3_enc, our encoding data, will be quantized to zero\n                     */\n                    continue; /* with next channel */\n                }\n\n                VBR_encode_granule(gfc, cod_info, l3_xmin[gr][ch], xrpow,\n                                   ch, min_bits[gr][ch], max_bits[gr][ch]);\n\n                /*  do the 'substep shaping'\n                 */\n                if (gfc->sv_qnt.substep_shaping & 1) {\n                    trancate_smallspectrums(gfc, &l3_side->tt[gr][ch], l3_xmin[gr][ch], xrpow);\n                }\n\n                ret = cod_info->part2_3_length + cod_info->part2_length;\n                used_bits += ret;\n            }           /* for ch */\n        }               /* for gr */\n\n        /*  find lowest bitrate able to hold used bits\n         */\n        if (analog_silence && !cfg->enforce_min_bitrate)\n            /*  we detected analog silence and the user did not specify\n             *  any hard framesize limit, so start with smallest possible frame\n             */\n            eov->bitrate_index = 1;\n        else\n            eov->bitrate_index = cfg->vbr_min_bitrate_index;\n\n        for (; eov->bitrate_index < cfg->vbr_max_bitrate_index; eov->bitrate_index++) {\n            if (used_bits <= frameBits[eov->bitrate_index])\n                break;\n        }\n        bits = ResvFrameBegin(gfc, &mean_bits);\n\n        if (used_bits <= bits)\n            break;\n\n        bitpressure_strategy(gfc, l3_xmin, (const int (*)[2])min_bits, max_bits);\n\n    }                   /* breaks adjusted */\n    /*--------------------------------------*/\n\n    for (gr = 0; gr < cfg->mode_gr; gr++) {\n        for (ch = 0; ch < cfg->channels_out; ch++) {\n            iteration_finish_one(gfc, gr, ch);\n        }               /* for ch */\n    }                   /* for gr */\n    ResvFrameEnd(gfc, mean_bits);\n}\n\n\n\nstatic int\nVBR_new_prepare(lame_internal_flags * gfc,\n                const FLOAT pe[2][2], const III_psy_ratio ratio[2][2],\n                FLOAT l3_xmin[2][2][SFBMAX], int frameBits[16], int max_bits[2][2],\n                int* max_resv)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    EncResult_t *const eov = &gfc->ov_enc;\n\n    int     gr, ch;\n    int     analog_silence = 1;\n    int     avg, bits = 0;\n    int     maximum_framebits;\n\n    if (!cfg->free_format) {\n        eov->bitrate_index = cfg->vbr_max_bitrate_index;\n        (void) ResvFrameBegin(gfc, &avg);\n        *max_resv = gfc->sv_enc.ResvMax;\n\n        get_framebits(gfc, frameBits);\n        maximum_framebits = frameBits[cfg->vbr_max_bitrate_index];\n    }\n    else {\n        eov->bitrate_index = 0;\n        maximum_framebits = ResvFrameBegin(gfc, &avg);\n        frameBits[0] = maximum_framebits;\n        *max_resv = gfc->sv_enc.ResvMax;\n    }\n\n    for (gr = 0; gr < cfg->mode_gr; gr++) {\n        (void) on_pe(gfc, pe, max_bits[gr], avg, gr, 0);\n        if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR) {\n            ms_convert(&gfc->l3_side, gr);\n        }\n        for (ch = 0; ch < cfg->channels_out; ++ch) {\n            gr_info *const cod_info = &gfc->l3_side.tt[gr][ch];\n\n            gfc->sv_qnt.masking_lower = pow(10.0, gfc->sv_qnt.mask_adjust * 0.1);\n\n            init_outer_loop(gfc, cod_info);\n            if (0 != calc_xmin(gfc, &ratio[gr][ch], cod_info, l3_xmin[gr][ch]))\n                analog_silence = 0;\n\n            bits += max_bits[gr][ch];\n        }\n    }\n    for (gr = 0; gr < cfg->mode_gr; gr++) {\n        for (ch = 0; ch < cfg->channels_out; ch++) {\n            if (bits > maximum_framebits && bits > 0) {\n                max_bits[gr][ch] *= maximum_framebits;\n                max_bits[gr][ch] /= bits;\n            }\n\n        }               /* for ch */\n    }                   /* for gr */\n    if (analog_silence) {\n        *max_resv = 0;\n    }\n    return analog_silence;\n}\n\n\n\nvoid\nVBR_new_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2],\n                       const FLOAT ms_ener_ratio[2], const III_psy_ratio ratio[2][2])\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    EncResult_t *const eov = &gfc->ov_enc;\n    FLOAT   l3_xmin[2][2][SFBMAX];\n\n    FLOAT   xrpow[2][2][576];\n    int     frameBits[15];\n    int     used_bits;\n    int     max_bits[2][2];\n    int     ch, gr, analog_silence, pad;\n    III_side_info_t *const l3_side = &gfc->l3_side;\n\n    const FLOAT (*const_l3_xmin)[2][SFBMAX] = (const FLOAT (*)[2][SFBMAX])l3_xmin;\n    const FLOAT (*const_xrpow)[2][576] = (const FLOAT (*)[2][576])xrpow;\n    const int (*const_max_bits)[2] = (const int (*)[2])max_bits;\n    \n    (void) ms_ener_ratio; /* not used */\n\n    memset(xrpow, 0, sizeof(xrpow));\n\n    analog_silence = VBR_new_prepare(gfc, pe, ratio, l3_xmin, frameBits, max_bits, &pad);\n\n    for (gr = 0; gr < cfg->mode_gr; gr++) {\n        for (ch = 0; ch < cfg->channels_out; ch++) {\n            gr_info *const cod_info = &l3_side->tt[gr][ch];\n\n            /*  init_outer_loop sets up cod_info, scalefac and xrpow\n             */\n            if (0 == init_xrpow(gfc, cod_info, xrpow[gr][ch])) {\n                max_bits[gr][ch] = 0; /* silent granule needs no bits */\n            }\n        }               /* for ch */\n    }                   /* for gr */\n\n    /*  quantize granules with lowest possible number of bits\n     */\n\n    used_bits = VBR_encode_frame(gfc, const_xrpow, const_l3_xmin, const_max_bits);\n\n    if (!cfg->free_format) {\n        int     i, j;\n\n        /*  find lowest bitrate able to hold used bits\n         */\n        if (analog_silence && !cfg->enforce_min_bitrate) {\n            /*  we detected analog silence and the user did not specify\n             *  any hard framesize limit, so start with smallest possible frame\n             */\n            i = 1;\n        }\n        else {\n            i = cfg->vbr_min_bitrate_index;\n        }\n\n        for (; i < cfg->vbr_max_bitrate_index; i++) {\n            if (used_bits <= frameBits[i]) \n                break;\n        }\n        if (i > cfg->vbr_max_bitrate_index) {\n            i = cfg->vbr_max_bitrate_index;\n        }\n        if (pad > 0) {\n            for (j = cfg->vbr_max_bitrate_index; j > i; --j) {\n                int const unused = frameBits[j] - used_bits;\n                if (unused <= pad) \n                    break;\n            }\n            eov->bitrate_index = j;\n        }\n        else {\n            eov->bitrate_index = i;\n        }\n    }\n    else {\n#if 0\n        static int mmm = 0;\n        int     fff = getFramesize_kbps(gfc, used_bits);\n        int     hhh = getFramesize_kbps(gfc, MAX_BITS_PER_GRANULE * cfg->mode_gr);\n        if (mmm < fff)\n            mmm = fff;\n        printf(\"demand=%3d kbps  max=%3d kbps   limit=%3d kbps\\n\", fff, mmm, hhh);\n#endif\n        eov->bitrate_index = 0;\n    }\n    if (used_bits <= frameBits[eov->bitrate_index]) {\n        /* update Reservoire status */\n        int     mean_bits, fullframebits;\n        fullframebits = ResvFrameBegin(gfc, &mean_bits);\n        assert(used_bits <= fullframebits);\n        for (gr = 0; gr < cfg->mode_gr; gr++) {\n            for (ch = 0; ch < cfg->channels_out; ch++) {\n                gr_info const *const cod_info = &l3_side->tt[gr][ch];\n                ResvAdjust(gfc, cod_info);\n            }\n        }\n        ResvFrameEnd(gfc, mean_bits);\n    }\n    else {\n        /* SHOULD NOT HAPPEN INTERNAL ERROR\n         */\n        ERRORF(gfc, \"INTERNAL ERROR IN VBR NEW CODE, please send bug report\\n\");\n        exit(-1);\n    }\n}\n\n\n\n\n\n/********************************************************************\n *\n *  calc_target_bits()\n *\n *  calculates target bits for ABR encoding\n *\n *  mt 2000/05/31\n *\n ********************************************************************/\n\nstatic void\ncalc_target_bits(lame_internal_flags * gfc,\n                 const FLOAT pe[2][2],\n                 FLOAT const ms_ener_ratio[2],\n                 int targ_bits[2][2], int *analog_silence_bits, int *max_frame_bits)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    EncResult_t *const eov = &gfc->ov_enc;\n    III_side_info_t const *const l3_side = &gfc->l3_side;\n    FLOAT   res_factor;\n    int     gr, ch, totbits, mean_bits;\n    int     framesize = 576 * cfg->mode_gr;\n\n    eov->bitrate_index = cfg->vbr_max_bitrate_index;\n    *max_frame_bits = ResvFrameBegin(gfc, &mean_bits);\n\n    eov->bitrate_index = 1;\n    mean_bits = getframebits(gfc) - cfg->sideinfo_len * 8;\n    *analog_silence_bits = mean_bits / (cfg->mode_gr * cfg->channels_out);\n\n    mean_bits = cfg->vbr_avg_bitrate_kbps * framesize * 1000;\n    if (gfc->sv_qnt.substep_shaping & 1)\n        mean_bits *= 1.09;\n    mean_bits /= cfg->samplerate_out;\n    mean_bits -= cfg->sideinfo_len * 8;\n    mean_bits /= (cfg->mode_gr * cfg->channels_out);\n\n    /*\n       res_factor is the percentage of the target bitrate that should\n       be used on average.  the remaining bits are added to the\n       bitreservoir and used for difficult to encode frames.\n\n       Since we are tracking the average bitrate, we should adjust\n       res_factor \"on the fly\", increasing it if the average bitrate\n       is greater than the requested bitrate, and decreasing it\n       otherwise.  Reasonable ranges are from .9 to 1.0\n\n       Until we get the above suggestion working, we use the following\n       tuning:\n       compression ratio    res_factor\n       5.5  (256kbps)         1.0      no need for bitreservoir\n       11   (128kbps)         .93      7% held for reservoir\n\n       with linear interpolation for other values.\n\n     */\n    res_factor = .93 + .07 * (11.0 - cfg->compression_ratio) / (11.0 - 5.5);\n    if (res_factor < .90)\n        res_factor = .90;\n    if (res_factor > 1.00)\n        res_factor = 1.00;\n\n    for (gr = 0; gr < cfg->mode_gr; gr++) {\n        int     sum = 0;\n        for (ch = 0; ch < cfg->channels_out; ch++) {\n            targ_bits[gr][ch] = res_factor * mean_bits;\n\n            if (pe[gr][ch] > 700) {\n                int     add_bits = (pe[gr][ch] - 700) / 1.4;\n\n                gr_info const *const cod_info = &l3_side->tt[gr][ch];\n                targ_bits[gr][ch] = res_factor * mean_bits;\n\n                /* short blocks use a little extra, no matter what the pe */\n                if (cod_info->block_type == SHORT_TYPE) {\n                    if (add_bits < mean_bits / 2)\n                        add_bits = mean_bits / 2;\n                }\n                /* at most increase bits by 1.5*average */\n                if (add_bits > mean_bits * 3 / 2)\n                    add_bits = mean_bits * 3 / 2;\n                else if (add_bits < 0)\n                    add_bits = 0;\n\n                targ_bits[gr][ch] += add_bits;\n            }\n            if (targ_bits[gr][ch] > MAX_BITS_PER_CHANNEL) {\n                targ_bits[gr][ch] = MAX_BITS_PER_CHANNEL;\n            }\n            sum += targ_bits[gr][ch];\n        }               /* for ch */\n        if (sum > MAX_BITS_PER_GRANULE) {\n            for (ch = 0; ch < cfg->channels_out; ++ch) {\n                targ_bits[gr][ch] *= MAX_BITS_PER_GRANULE;\n                targ_bits[gr][ch] /= sum;\n            }\n        }\n    }                   /* for gr */\n\n    if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR)\n        for (gr = 0; gr < cfg->mode_gr; gr++) {\n            reduce_side(targ_bits[gr], ms_ener_ratio[gr], mean_bits * cfg->channels_out,\n                        MAX_BITS_PER_GRANULE);\n        }\n\n    /*  sum target bits\n     */\n    totbits = 0;\n    for (gr = 0; gr < cfg->mode_gr; gr++) {\n        for (ch = 0; ch < cfg->channels_out; ch++) {\n            if (targ_bits[gr][ch] > MAX_BITS_PER_CHANNEL)\n                targ_bits[gr][ch] = MAX_BITS_PER_CHANNEL;\n            totbits += targ_bits[gr][ch];\n        }\n    }\n\n    /*  repartion target bits if needed\n     */\n    if (totbits > *max_frame_bits && totbits > 0) {\n        for (gr = 0; gr < cfg->mode_gr; gr++) {\n            for (ch = 0; ch < cfg->channels_out; ch++) {\n                targ_bits[gr][ch] *= *max_frame_bits;\n                targ_bits[gr][ch] /= totbits;\n            }\n        }\n    }\n}\n\n\n\n\n\n\n/********************************************************************\n *\n *  ABR_iteration_loop()\n *\n *  encode a frame with a disired average bitrate\n *\n *  mt 2000/05/31\n *\n ********************************************************************/\n\nvoid\nABR_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2],\n                   const FLOAT ms_ener_ratio[2], const III_psy_ratio ratio[2][2])\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    EncResult_t *const eov = &gfc->ov_enc;\n    FLOAT   l3_xmin[SFBMAX];\n    FLOAT   xrpow[576];\n    int     targ_bits[2][2];\n    int     mean_bits, max_frame_bits;\n    int     ch, gr, ath_over;\n    int     analog_silence_bits;\n    gr_info *cod_info;\n    III_side_info_t *const l3_side = &gfc->l3_side;\n\n    mean_bits = 0;\n\n    calc_target_bits(gfc, pe, ms_ener_ratio, targ_bits, &analog_silence_bits, &max_frame_bits);\n\n    /*  encode granules\n     */\n    for (gr = 0; gr < cfg->mode_gr; gr++) {\n\n        if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR) {\n            ms_convert(&gfc->l3_side, gr);\n        }\n        for (ch = 0; ch < cfg->channels_out; ch++) {\n            FLOAT   adjust, masking_lower_db;\n            cod_info = &l3_side->tt[gr][ch];\n\n            if (cod_info->block_type != SHORT_TYPE) { /* NORM, START or STOP type */\n                /* adjust = 1.28/(1+exp(3.5-pe[gr][ch]/300.))-0.05; */\n                adjust = 0;\n                masking_lower_db = gfc->sv_qnt.mask_adjust - adjust;\n            }\n            else {\n                /* adjust = 2.56/(1+exp(3.5-pe[gr][ch]/300.))-0.14; */\n                adjust = 0;\n                masking_lower_db = gfc->sv_qnt.mask_adjust_short - adjust;\n            }\n            gfc->sv_qnt.masking_lower = pow(10.0, masking_lower_db * 0.1);\n\n\n            /*  cod_info, scalefac and xrpow get initialized in init_outer_loop\n             */\n            init_outer_loop(gfc, cod_info);\n            if (init_xrpow(gfc, cod_info, xrpow)) {\n                /*  xr contains energy we will have to encode\n                 *  calculate the masking abilities\n                 *  find some good quantization in outer_loop\n                 */\n                ath_over = calc_xmin(gfc, &ratio[gr][ch], cod_info, l3_xmin);\n                if (0 == ath_over) /* analog silence */\n                    targ_bits[gr][ch] = analog_silence_bits;\n\n                (void) outer_loop(gfc, cod_info, l3_xmin, xrpow, ch, targ_bits[gr][ch]);\n            }\n            iteration_finish_one(gfc, gr, ch);\n        }               /* ch */\n    }                   /* gr */\n\n    /*  find a bitrate which can refill the resevoir to positive size.\n     */\n    for (eov->bitrate_index = cfg->vbr_min_bitrate_index;\n         eov->bitrate_index <= cfg->vbr_max_bitrate_index; eov->bitrate_index++) {\n        if (ResvFrameBegin(gfc, &mean_bits) >= 0)\n            break;\n    }\n    assert(eov->bitrate_index <= cfg->vbr_max_bitrate_index);\n\n    ResvFrameEnd(gfc, mean_bits);\n}\n\n\n\n\n\n\n/************************************************************************\n *\n *      CBR_iteration_loop()\n *\n *  author/date??\n *\n *  encodes one frame of MP3 data with constant bitrate\n *\n ************************************************************************/\n\nvoid\nCBR_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2],\n                   const FLOAT ms_ener_ratio[2], const III_psy_ratio ratio[2][2])\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    FLOAT   l3_xmin[SFBMAX];\n    FLOAT   xrpow[576];\n    int     targ_bits[2];\n    int     mean_bits, max_bits;\n    int     gr, ch;\n    III_side_info_t *const l3_side = &gfc->l3_side;\n    gr_info *cod_info;\n\n    (void) ResvFrameBegin(gfc, &mean_bits);\n\n    /* quantize! */\n    for (gr = 0; gr < cfg->mode_gr; gr++) {\n\n        /*  calculate needed bits\n         */\n        max_bits = on_pe(gfc, pe, targ_bits, mean_bits, gr, gr);\n\n        if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR) {\n            ms_convert(&gfc->l3_side, gr);\n            reduce_side(targ_bits, ms_ener_ratio[gr], mean_bits, max_bits);\n        }\n\n        for (ch = 0; ch < cfg->channels_out; ch++) {\n            FLOAT   adjust, masking_lower_db;\n            cod_info = &l3_side->tt[gr][ch];\n\n            if (cod_info->block_type != SHORT_TYPE) { /* NORM, START or STOP type */\n                /* adjust = 1.28/(1+exp(3.5-pe[gr][ch]/300.))-0.05; */\n                adjust = 0;\n                masking_lower_db = gfc->sv_qnt.mask_adjust - adjust;\n            }\n            else {\n                /* adjust = 2.56/(1+exp(3.5-pe[gr][ch]/300.))-0.14; */\n                adjust = 0;\n                masking_lower_db = gfc->sv_qnt.mask_adjust_short - adjust;\n            }\n            gfc->sv_qnt.masking_lower = pow(10.0, masking_lower_db * 0.1);\n\n            /*  init_outer_loop sets up cod_info, scalefac and xrpow\n             */\n            init_outer_loop(gfc, cod_info);\n            if (init_xrpow(gfc, cod_info, xrpow)) {\n                /*  xr contains energy we will have to encode\n                 *  calculate the masking abilities\n                 *  find some good quantization in outer_loop\n                 */\n                (void) calc_xmin(gfc, &ratio[gr][ch], cod_info, l3_xmin);\n                (void) outer_loop(gfc, cod_info, l3_xmin, xrpow, ch, targ_bits[ch]);\n            }\n\n            iteration_finish_one(gfc, gr, ch);\n            assert(cod_info->part2_3_length <= MAX_BITS_PER_CHANNEL);\n            assert(cod_info->part2_3_length <= targ_bits[ch]);\n        }               /* for ch */\n    }                   /* for gr */\n\n    ResvFrameEnd(gfc, mean_bits);\n}\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/quantize.h",
    "content": "/*\n * MP3 quantization\n *\n * Copyright (c) 1999 Mark Taylor\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n#ifndef LAME_QUANTIZE_H\n#define LAME_QUANTIZE_H\n\nvoid    CBR_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2],\n                           const FLOAT ms_ratio[2], const III_psy_ratio ratio[2][2]);\n\nvoid    VBR_old_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2],\n                               const FLOAT ms_ratio[2], const III_psy_ratio ratio[2][2]);\n\nvoid    VBR_new_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2],\n                               const FLOAT ms_ratio[2], const III_psy_ratio ratio[2][2]);\n\nvoid    ABR_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2],\n                           const FLOAT ms_ratio[2], const III_psy_ratio ratio[2][2]);\n\n\n#endif /* LAME_QUANTIZE_H */\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/quantize_pvt.c",
    "content": "/*\n *      quantize_pvt source file\n *\n *      Copyright (c) 1999-2002 Takehiro Tominaga\n *      Copyright (c) 2000-2012 Robert Hegemann\n *      Copyright (c) 2001 Naoki Shibata\n *      Copyright (c) 2002-2005 Gabriel Bouvigne\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n/* $Id: quantize_pvt.c,v 1.169.2.2 2012/02/07 13:40:37 robert Exp $ */\n#ifdef HAVE_CONFIG_H\n# include <config.h>\n#endif\n\n\n#include \"lame.h\"\n#include \"machine.h\"\n#include \"encoder.h\"\n#include \"util.h\"\n#include \"quantize_pvt.h\"\n#include \"reservoir.h\"\n#include \"lame-analysis.h\"\n#include <float.h>\n\n\n#define NSATHSCALE 100  /* Assuming dynamic range=96dB, this value should be 92 */\n\n/*\n  The following table is used to implement the scalefactor\n  partitioning for MPEG2 as described in section\n  2.4.3.2 of the IS. The indexing corresponds to the\n  way the tables are presented in the IS:\n\n  [table_number][row_in_table][column of nr_of_sfb]\n*/\nconst int nr_of_sfb_block[6][3][4] = {\n    {\n     {6, 5, 5, 5},\n     {9, 9, 9, 9},\n     {6, 9, 9, 9}\n     },\n    {\n     {6, 5, 7, 3},\n     {9, 9, 12, 6},\n     {6, 9, 12, 6}\n     },\n    {\n     {11, 10, 0, 0},\n     {18, 18, 0, 0},\n     {15, 18, 0, 0}\n     },\n    {\n     {7, 7, 7, 0},\n     {12, 12, 12, 0},\n     {6, 15, 12, 0}\n     },\n    {\n     {6, 6, 6, 3},\n     {12, 9, 9, 6},\n     {6, 12, 9, 6}\n     },\n    {\n     {8, 8, 5, 0},\n     {15, 12, 9, 0},\n     {6, 18, 9, 0}\n     }\n};\n\n\n/* Table B.6: layer3 preemphasis */\nconst int pretab[SBMAX_l] = {\n    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n    1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0\n};\n\n/*\n  Here are MPEG1 Table B.8 and MPEG2 Table B.1\n  -- Layer III scalefactor bands. \n  Index into this using a method such as:\n    idx  = fr_ps->header->sampling_frequency\n           + (fr_ps->header->version * 3)\n*/\n\n\nconst scalefac_struct sfBandIndex[9] = {\n    {                   /* Table B.2.b: 22.05 kHz */\n     {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464,\n      522, 576},\n     {0, 4, 8, 12, 18, 24, 32, 42, 56, 74, 100, 132, 174, 192}\n     , {0, 0, 0, 0, 0, 0, 0} /*  sfb21 pseudo sub bands */\n     , {0, 0, 0, 0, 0, 0, 0} /*  sfb12 pseudo sub bands */\n     },\n    {                   /* Table B.2.c: 24 kHz */ /* docs: 332. mpg123(broken): 330 */\n     {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 114, 136, 162, 194, 232, 278, 332, 394, 464,\n      540, 576},\n     {0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 136, 180, 192}\n     , {0, 0, 0, 0, 0, 0, 0} /*  sfb21 pseudo sub bands */\n     , {0, 0, 0, 0, 0, 0, 0} /*  sfb12 pseudo sub bands */\n     },\n    {                   /* Table B.2.a: 16 kHz */\n     {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464,\n      522, 576},\n     {0, 4, 8, 12, 18, 26, 36, 48, 62, 80, 104, 134, 174, 192}\n     , {0, 0, 0, 0, 0, 0, 0} /*  sfb21 pseudo sub bands */\n     , {0, 0, 0, 0, 0, 0, 0} /*  sfb12 pseudo sub bands */\n     },\n    {                   /* Table B.8.b: 44.1 kHz */\n     {0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 52, 62, 74, 90, 110, 134, 162, 196, 238, 288, 342, 418,\n      576},\n     {0, 4, 8, 12, 16, 22, 30, 40, 52, 66, 84, 106, 136, 192}\n     , {0, 0, 0, 0, 0, 0, 0} /*  sfb21 pseudo sub bands */\n     , {0, 0, 0, 0, 0, 0, 0} /*  sfb12 pseudo sub bands */\n     },\n    {                   /* Table B.8.c: 48 kHz */\n     {0, 4, 8, 12, 16, 20, 24, 30, 36, 42, 50, 60, 72, 88, 106, 128, 156, 190, 230, 276, 330, 384,\n      576},\n     {0, 4, 8, 12, 16, 22, 28, 38, 50, 64, 80, 100, 126, 192}\n     , {0, 0, 0, 0, 0, 0, 0} /*  sfb21 pseudo sub bands */\n     , {0, 0, 0, 0, 0, 0, 0} /*  sfb12 pseudo sub bands */\n     },\n    {                   /* Table B.8.a: 32 kHz */\n     {0, 4, 8, 12, 16, 20, 24, 30, 36, 44, 54, 66, 82, 102, 126, 156, 194, 240, 296, 364, 448, 550,\n      576},\n     {0, 4, 8, 12, 16, 22, 30, 42, 58, 78, 104, 138, 180, 192}\n     , {0, 0, 0, 0, 0, 0, 0} /*  sfb21 pseudo sub bands */\n     , {0, 0, 0, 0, 0, 0, 0} /*  sfb12 pseudo sub bands */\n     },\n    {                   /* MPEG-2.5 11.025 kHz */\n     {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464,\n      522, 576},\n     {0 / 3, 12 / 3, 24 / 3, 36 / 3, 54 / 3, 78 / 3, 108 / 3, 144 / 3, 186 / 3, 240 / 3, 312 / 3,\n      402 / 3, 522 / 3, 576 / 3}\n     , {0, 0, 0, 0, 0, 0, 0} /*  sfb21 pseudo sub bands */\n     , {0, 0, 0, 0, 0, 0, 0} /*  sfb12 pseudo sub bands */\n     },\n    {                   /* MPEG-2.5 12 kHz */\n     {0, 6, 12, 18, 24, 30, 36, 44, 54, 66, 80, 96, 116, 140, 168, 200, 238, 284, 336, 396, 464,\n      522, 576},\n     {0 / 3, 12 / 3, 24 / 3, 36 / 3, 54 / 3, 78 / 3, 108 / 3, 144 / 3, 186 / 3, 240 / 3, 312 / 3,\n      402 / 3, 522 / 3, 576 / 3}\n     , {0, 0, 0, 0, 0, 0, 0} /*  sfb21 pseudo sub bands */\n     , {0, 0, 0, 0, 0, 0, 0} /*  sfb12 pseudo sub bands */\n     },\n    {                   /* MPEG-2.5 8 kHz */\n     {0, 12, 24, 36, 48, 60, 72, 88, 108, 132, 160, 192, 232, 280, 336, 400, 476, 566, 568, 570,\n      572, 574, 576},\n     {0 / 3, 24 / 3, 48 / 3, 72 / 3, 108 / 3, 156 / 3, 216 / 3, 288 / 3, 372 / 3, 480 / 3, 486 / 3,\n      492 / 3, 498 / 3, 576 / 3}\n     , {0, 0, 0, 0, 0, 0, 0} /*  sfb21 pseudo sub bands */\n     , {0, 0, 0, 0, 0, 0, 0} /*  sfb12 pseudo sub bands */\n     }\n};\n\n\n\nFLOAT   pow20[Q_MAX + Q_MAX2 + 1];\nFLOAT   ipow20[Q_MAX];\nFLOAT   pow43[PRECALC_SIZE];\n/* initialized in first call to iteration_init */\n#ifdef TAKEHIRO_IEEE754_HACK\nFLOAT   adj43asm[PRECALC_SIZE];\n#else\nFLOAT   adj43[PRECALC_SIZE];\n#endif\n\n/* \ncompute the ATH for each scalefactor band \ncd range:  0..96db\n\nInput:  3.3kHz signal  32767 amplitude  (3.3kHz is where ATH is smallest = -5db)\nlongblocks:  sfb=12   en0/bw=-11db    max_en0 = 1.3db\nshortblocks: sfb=5           -9db              0db\n\nInput:  1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 (repeated)\nlongblocks:  amp=1      sfb=12   en0/bw=-103 db      max_en0 = -92db\n            amp=32767   sfb=12           -12 db                 -1.4db \n\nInput:  1 1 1 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 (repeated)\nshortblocks: amp=1      sfb=5   en0/bw= -99                    -86 \n            amp=32767   sfb=5           -9  db                  4db \n\n\nMAX energy of largest wave at 3.3kHz = 1db\nAVE energy of largest wave at 3.3kHz = -11db\nLet's take AVE:  -11db = maximum signal in sfb=12.  \nDynamic range of CD: 96db.  Therefor energy of smallest audible wave \nin sfb=12  = -11  - 96 = -107db = ATH at 3.3kHz.  \n\nATH formula for this wave: -5db.  To adjust to LAME scaling, we need\nATH = ATH_formula  - 103  (db)\nATH = ATH * 2.5e-10      (ener)\n\n*/\n\nstatic  FLOAT\nATHmdct(SessionConfig_t const *cfg, FLOAT f)\n{\n    FLOAT   ath;\n\n    ath = ATHformula(cfg, f);\n\n    if (cfg->ATHfixpoint > 0) {\n        ath -= cfg->ATHfixpoint;\n    }\n    else {\n        ath -= NSATHSCALE;\n    }\n    ath += cfg->ATH_offset_db;\n\n    /* modify the MDCT scaling for the ATH and convert to energy */\n    ath = powf(10.0f, ath * 0.1f);\n    return ath;\n}\n\nstatic void\ncompute_ath(lame_internal_flags const* gfc)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    FLOAT  *const ATH_l = gfc->ATH->l;\n    FLOAT  *const ATH_psfb21 = gfc->ATH->psfb21;\n    FLOAT  *const ATH_s = gfc->ATH->s;\n    FLOAT  *const ATH_psfb12 = gfc->ATH->psfb12;\n    int     sfb, i, start, end;\n    FLOAT   ATH_f;\n    FLOAT const samp_freq = cfg->samplerate_out;\n\n    for (sfb = 0; sfb < SBMAX_l; sfb++) {\n        start = gfc->scalefac_band.l[sfb];\n        end = gfc->scalefac_band.l[sfb + 1];\n        ATH_l[sfb] = FLOAT_MAX;\n        for (i = start; i < end; i++) {\n            FLOAT const freq = i * samp_freq / (2 * 576);\n            ATH_f = ATHmdct(cfg, freq); /* freq in kHz */\n            ATH_l[sfb] = Min(ATH_l[sfb], ATH_f);\n        }\n    }\n\n    for (sfb = 0; sfb < PSFB21; sfb++) {\n        start = gfc->scalefac_band.psfb21[sfb];\n        end = gfc->scalefac_band.psfb21[sfb + 1];\n        ATH_psfb21[sfb] = FLOAT_MAX;\n        for (i = start; i < end; i++) {\n            FLOAT const freq = i * samp_freq / (2 * 576);\n            ATH_f = ATHmdct(cfg, freq); /* freq in kHz */\n            ATH_psfb21[sfb] = Min(ATH_psfb21[sfb], ATH_f);\n        }\n    }\n\n    for (sfb = 0; sfb < SBMAX_s; sfb++) {\n        start = gfc->scalefac_band.s[sfb];\n        end = gfc->scalefac_band.s[sfb + 1];\n        ATH_s[sfb] = FLOAT_MAX;\n        for (i = start; i < end; i++) {\n            FLOAT const freq = i * samp_freq / (2 * 192);\n            ATH_f = ATHmdct(cfg, freq); /* freq in kHz */\n            ATH_s[sfb] = Min(ATH_s[sfb], ATH_f);\n        }\n        ATH_s[sfb] *= (gfc->scalefac_band.s[sfb + 1] - gfc->scalefac_band.s[sfb]);\n    }\n\n    for (sfb = 0; sfb < PSFB12; sfb++) {\n        start = gfc->scalefac_band.psfb12[sfb];\n        end = gfc->scalefac_band.psfb12[sfb + 1];\n        ATH_psfb12[sfb] = FLOAT_MAX;\n        for (i = start; i < end; i++) {\n            FLOAT const freq = i * samp_freq / (2 * 192);\n            ATH_f = ATHmdct(cfg, freq); /* freq in kHz */\n            ATH_psfb12[sfb] = Min(ATH_psfb12[sfb], ATH_f);\n        }\n        /*not sure about the following */\n        ATH_psfb12[sfb] *= (gfc->scalefac_band.s[13] - gfc->scalefac_band.s[12]);\n    }\n\n\n    /*  no-ATH mode:\n     *  reduce ATH to -200 dB\n     */\n\n    if (cfg->noATH) {\n        for (sfb = 0; sfb < SBMAX_l; sfb++) {\n            ATH_l[sfb] = 1E-20;\n        }\n        for (sfb = 0; sfb < PSFB21; sfb++) {\n            ATH_psfb21[sfb] = 1E-20;\n        }\n        for (sfb = 0; sfb < SBMAX_s; sfb++) {\n            ATH_s[sfb] = 1E-20;\n        }\n        for (sfb = 0; sfb < PSFB12; sfb++) {\n            ATH_psfb12[sfb] = 1E-20;\n        }\n    }\n\n    /*  work in progress, don't rely on it too much\n     */\n    gfc->ATH->floor = 10. * log10(ATHmdct(cfg, -1.));\n\n    /*\n       {   FLOAT g=10000, t=1e30, x;\n       for ( f = 100; f < 10000; f++ ) {\n       x = ATHmdct( cfg, f );\n       if ( t > x ) t = x, g = f;\n       }\n       printf(\"min=%g\\n\", g);\n       } */\n}\n\n\nstatic float const payload_long[2][4] = \n{ {-0.000f, -0.000f, -0.000f, +0.000f}\n, {-0.500f, -0.250f, -0.025f, +0.500f}\n};\nstatic float const payload_short[2][4] = \n{ {-0.000f, -0.000f, -0.000f, +0.000f}\n, {-2.000f, -1.000f, -0.050f, +0.500f}\n};\n\n/************************************************************************/\n/*  initialization for iteration_loop */\n/************************************************************************/\nvoid\niteration_init(lame_internal_flags * gfc)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    III_side_info_t *const l3_side = &gfc->l3_side;\n    FLOAT   adjust, db;\n    int     i, sel;\n\n    if (gfc->iteration_init_init == 0) {\n        gfc->iteration_init_init = 1;\n\n        l3_side->main_data_begin = 0;\n        compute_ath(gfc);\n\n        pow43[0] = 0.0;\n        for (i = 1; i < PRECALC_SIZE; i++)\n            pow43[i] = pow((FLOAT) i, 4.0 / 3.0);\n\n#ifdef TAKEHIRO_IEEE754_HACK\n        adj43asm[0] = 0.0;\n        for (i = 1; i < PRECALC_SIZE; i++)\n            adj43asm[i] = i - 0.5 - pow(0.5 * (pow43[i - 1] + pow43[i]), 0.75);\n#else\n        for (i = 0; i < PRECALC_SIZE - 1; i++)\n            adj43[i] = (i + 1) - pow(0.5 * (pow43[i] + pow43[i + 1]), 0.75);\n        adj43[i] = 0.5;\n#endif\n        for (i = 0; i < Q_MAX; i++)\n            ipow20[i] = pow(2.0, (double) (i - 210) * -0.1875);\n        for (i = 0; i <= Q_MAX + Q_MAX2; i++)\n            pow20[i] = pow(2.0, (double) (i - 210 - Q_MAX2) * 0.25);\n\n        huffman_init(gfc);\n        init_xrpow_core_init(gfc);\n\n        sel = 1;/* RH: all modes like vbr-new (cfg->vbr == vbr_mt || cfg->vbr == vbr_mtrh) ? 1 : 0;*/\n\n        /* long */\n        db = cfg->adjust_bass_db + payload_long[sel][0];\n        adjust = powf(10.f, db * 0.1f);\n        for (i = 0; i <= 6; ++i) {\n            gfc->sv_qnt.longfact[i] = adjust;\n        }\n        db = cfg->adjust_alto_db + payload_long[sel][1];\n        adjust = powf(10.f, db * 0.1f);\n        for (; i <= 13; ++i) {\n            gfc->sv_qnt.longfact[i] = adjust;\n        }\n        db = cfg->adjust_treble_db + payload_long[sel][2];\n        adjust = powf(10.f, db * 0.1f);\n        for (; i <= 20; ++i) {\n            gfc->sv_qnt.longfact[i] = adjust;\n        }\n        db = cfg->adjust_sfb21_db + payload_long[sel][3];\n        adjust = powf(10.f, db * 0.1f);\n        for (; i < SBMAX_l; ++i) {\n            gfc->sv_qnt.longfact[i] = adjust;\n        }\n\n        /* short */\n        db = cfg->adjust_bass_db + payload_short[sel][0];\n        adjust = powf(10.f, db * 0.1f);\n        for (i = 0; i <= 2; ++i) {\n            gfc->sv_qnt.shortfact[i] = adjust;\n        }\n        db = cfg->adjust_alto_db + payload_short[sel][1];\n        adjust = powf(10.f, db * 0.1f);\n        for (; i <= 6; ++i) {\n            gfc->sv_qnt.shortfact[i] = adjust;\n        }\n        db = cfg->adjust_treble_db + payload_short[sel][2];\n        adjust = powf(10.f, db * 0.1f);\n        for (; i <= 11; ++i) {\n            gfc->sv_qnt.shortfact[i] = adjust;\n        }\n        db = cfg->adjust_sfb21_db + payload_short[sel][3];\n        adjust = powf(10.f, db * 0.1f);\n        for (; i < SBMAX_s; ++i) {\n            gfc->sv_qnt.shortfact[i] = adjust;\n        }\n    }\n}\n\n\n\n\n\n/************************************************************************\n * allocate bits among 2 channels based on PE\n * mt 6/99\n * bugfixes rh 8/01: often allocated more than the allowed 4095 bits\n ************************************************************************/\nint\non_pe(lame_internal_flags * gfc, const FLOAT pe[][2], int targ_bits[2], int mean_bits, int gr, int cbr)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    int     extra_bits = 0, tbits, bits;\n    int     add_bits[2] = {0, 0};\n    int     max_bits;        /* maximum allowed bits for this granule */\n    int     ch;\n\n    /* allocate targ_bits for granule */\n    ResvMaxBits(gfc, mean_bits, &tbits, &extra_bits, cbr);\n    max_bits = tbits + extra_bits;\n    if (max_bits > MAX_BITS_PER_GRANULE) /* hard limit per granule */\n        max_bits = MAX_BITS_PER_GRANULE;\n\n    for (bits = 0, ch = 0; ch < cfg->channels_out; ++ch) {\n        /******************************************************************\n         * allocate bits for each channel \n         ******************************************************************/\n        targ_bits[ch] = Min(MAX_BITS_PER_CHANNEL, tbits / cfg->channels_out);\n\n        add_bits[ch] = targ_bits[ch] * pe[gr][ch] / 700.0 - targ_bits[ch];\n\n        /* at most increase bits by 1.5*average */\n        if (add_bits[ch] > mean_bits * 3 / 4)\n            add_bits[ch] = mean_bits * 3 / 4;\n        if (add_bits[ch] < 0)\n            add_bits[ch] = 0;\n\n        if (add_bits[ch] + targ_bits[ch] > MAX_BITS_PER_CHANNEL)\n            add_bits[ch] = Max(0, MAX_BITS_PER_CHANNEL - targ_bits[ch]);\n\n        bits += add_bits[ch];\n    }\n    if (bits > extra_bits && bits > 0) {\n        for (ch = 0; ch < cfg->channels_out; ++ch) {\n            add_bits[ch] = extra_bits * add_bits[ch] / bits;\n        }\n    }\n\n    for (ch = 0; ch < cfg->channels_out; ++ch) {\n        targ_bits[ch] += add_bits[ch];\n        extra_bits -= add_bits[ch];\n    }\n\n    for (bits = 0, ch = 0; ch < cfg->channels_out; ++ch) {\n        bits += targ_bits[ch];\n    }\n    if (bits > MAX_BITS_PER_GRANULE) {\n        int     sum = 0;\n        for (ch = 0; ch < cfg->channels_out; ++ch) {\n            targ_bits[ch] *= MAX_BITS_PER_GRANULE;\n            targ_bits[ch] /= bits;\n            sum += targ_bits[ch];\n        }\n        assert(sum <= MAX_BITS_PER_GRANULE);\n    }\n\n    return max_bits;\n}\n\n\n\n\nvoid\nreduce_side(int targ_bits[2], FLOAT ms_ener_ratio, int mean_bits, int max_bits)\n{\n    int     move_bits;\n    FLOAT   fac;\n\n    assert(max_bits <= MAX_BITS_PER_GRANULE);\n    assert(targ_bits[0] + targ_bits[1] <= MAX_BITS_PER_GRANULE);\n\n    /*  ms_ener_ratio = 0:  allocate 66/33  mid/side  fac=.33  \n     *  ms_ener_ratio =.5:  allocate 50/50 mid/side   fac= 0 */\n    /* 75/25 split is fac=.5 */\n    /* float fac = .50*(.5-ms_ener_ratio[gr])/.5; */\n    fac = .33 * (.5 - ms_ener_ratio) / .5;\n    if (fac < 0)\n        fac = 0;\n    if (fac > .5)\n        fac = .5;\n\n    /* number of bits to move from side channel to mid channel */\n    /*    move_bits = fac*targ_bits[1];  */\n    move_bits = fac * .5 * (targ_bits[0] + targ_bits[1]);\n\n    if (move_bits > MAX_BITS_PER_CHANNEL - targ_bits[0]) {\n        move_bits = MAX_BITS_PER_CHANNEL - targ_bits[0];\n    }\n    if (move_bits < 0)\n        move_bits = 0;\n\n    if (targ_bits[1] >= 125) {\n        /* dont reduce side channel below 125 bits */\n        if (targ_bits[1] - move_bits > 125) {\n\n            /* if mid channel already has 2x more than average, dont bother */\n            /* mean_bits = bits per granule (for both channels) */\n            if (targ_bits[0] < mean_bits)\n                targ_bits[0] += move_bits;\n            targ_bits[1] -= move_bits;\n        }\n        else {\n            targ_bits[0] += targ_bits[1] - 125;\n            targ_bits[1] = 125;\n        }\n    }\n\n    move_bits = targ_bits[0] + targ_bits[1];\n    if (move_bits > max_bits) {\n        targ_bits[0] = (max_bits * targ_bits[0]) / move_bits;\n        targ_bits[1] = (max_bits * targ_bits[1]) / move_bits;\n    }\n    assert(targ_bits[0] <= MAX_BITS_PER_CHANNEL);\n    assert(targ_bits[1] <= MAX_BITS_PER_CHANNEL);\n    assert(targ_bits[0] + targ_bits[1] <= MAX_BITS_PER_GRANULE);\n}\n\n\n/**\n *  Robert Hegemann 2001-04-27:\n *  this adjusts the ATH, keeping the original noise floor\n *  affects the higher frequencies more than the lower ones\n */\n\nFLOAT\nathAdjust(FLOAT a, FLOAT x, FLOAT athFloor, float ATHfixpoint)\n{\n    /*  work in progress\n     */\n    FLOAT const o = 90.30873362f;\n    FLOAT const p = (ATHfixpoint < 1.f) ? 94.82444863f : ATHfixpoint;\n    FLOAT   u = FAST_LOG10_X(x, 10.0f);\n    FLOAT const v = a * a;\n    FLOAT   w = 0.0f;\n    u -= athFloor;      /* undo scaling */\n    if (v > 1E-20f)\n        w = 1.f + FAST_LOG10_X(v, 10.0f / o);\n    if (w < 0)\n        w = 0.f;\n    u *= w;\n    u += athFloor + o - p; /* redo scaling */\n\n    return powf(10.f, 0.1f * u);\n}\n\n\n\n/*************************************************************************/\n/*            calc_xmin                                                  */\n/*************************************************************************/\n\n/*\n  Calculate the allowed distortion for each scalefactor band,\n  as determined by the psychoacoustic model.\n  xmin(sb) = ratio(sb) * en(sb) / bw(sb)\n\n  returns number of sfb's with energy > ATH\n*/\n\nint\ncalc_xmin(lame_internal_flags const *gfc,\n          III_psy_ratio const *const ratio, gr_info * const cod_info, FLOAT * pxmin)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    int     sfb, gsfb, j = 0, ath_over = 0, k;\n    ATH_t const *const ATH = gfc->ATH;\n    const FLOAT *const xr = cod_info->xr;\n    int     max_nonzero;\n\n    for (gsfb = 0; gsfb < cod_info->psy_lmax; gsfb++) {\n        FLOAT   en0, xmin;\n        FLOAT   rh1, rh2, rh3;\n        int     width, l;\n\n        xmin = athAdjust(ATH->adjust_factor, ATH->l[gsfb], ATH->floor, cfg->ATHfixpoint);\n        xmin *= gfc->sv_qnt.longfact[gsfb];\n\n        width = cod_info->width[gsfb];\n        rh1 = xmin / width;\n#ifdef DBL_EPSILON\n        rh2 = DBL_EPSILON;\n#else\n        rh2 = 2.2204460492503131e-016;\n#endif\n        en0 = 0.0;\n        for (l = 0; l < width; ++l) {\n            FLOAT const xa = xr[j++];\n            FLOAT const x2 = xa * xa;\n            en0 += x2;\n            rh2 += (x2 < rh1) ? x2 : rh1;\n        }\n        if (en0 > xmin)\n            ath_over++;\n\n        if (en0 < xmin) {\n            rh3 = en0;\n        }\n        else if (rh2 < xmin) {\n            rh3 = xmin;\n        }\n        else {\n            rh3 = rh2;\n        }\n        xmin = rh3;\n        {\n            FLOAT const e = ratio->en.l[gsfb];\n            if (e > 1e-12f) {\n                FLOAT   x;\n                x = en0 * ratio->thm.l[gsfb] / e;\n                x *= gfc->sv_qnt.longfact[gsfb];\n                if (xmin < x)\n                    xmin = x;\n            }\n        }\n        xmin = Max(xmin, DBL_EPSILON);\n        cod_info->energy_above_cutoff[gsfb] = (en0 > xmin+1e-14f) ? 1 : 0;\n        *pxmin++ = xmin;\n    }                   /* end of long block loop */\n\n\n\n\n    /*use this function to determine the highest non-zero coeff */\n    max_nonzero = 0;\n    for (k = 575; k > 0; --k) {\n        if (fabs(xr[k]) > 1e-12f) {\n            max_nonzero = k;\n            break;\n        }\n    }\n    if (cod_info->block_type != SHORT_TYPE) { /* NORM, START or STOP type, but not SHORT */\n        max_nonzero |= 1; /* only odd numbers */\n    }\n    else {\n        max_nonzero /= 6; /* 3 short blocks */\n        max_nonzero *= 6;\n        max_nonzero += 5;\n    }\n\n    if (gfc->sv_qnt.sfb21_extra == 0 && cfg->samplerate_out < 44000) {\n      int const sfb_l = (cfg->samplerate_out <= 8000) ? 17 : 21;\n      int const sfb_s = (cfg->samplerate_out <= 8000) ?  9 : 12;\n      int   limit = 575;\n      if (cod_info->block_type != SHORT_TYPE) { /* NORM, START or STOP type, but not SHORT */\n          limit = gfc->scalefac_band.l[sfb_l]-1;\n      }\n      else {\n          limit = 3*gfc->scalefac_band.s[sfb_s]-1;\n      }\n      if (max_nonzero > limit) {\n          max_nonzero = limit;\n      }\n    }\n    cod_info->max_nonzero_coeff = max_nonzero;\n\n\n\n    for (sfb = cod_info->sfb_smin; gsfb < cod_info->psymax; sfb++, gsfb += 3) {\n        int     width, b, l;\n        FLOAT   tmpATH;\n\n        tmpATH = athAdjust(ATH->adjust_factor, ATH->s[sfb], ATH->floor, cfg->ATHfixpoint);\n        tmpATH *= gfc->sv_qnt.shortfact[sfb];\n        \n        width = cod_info->width[gsfb];\n        for (b = 0; b < 3; b++) {\n            FLOAT   en0 = 0.0, xmin = tmpATH;\n            FLOAT   rh1, rh2, rh3;\n\n            rh1 = tmpATH / width;\n#ifdef DBL_EPSILON\n            rh2 = DBL_EPSILON;\n#else\n            rh2 = 2.2204460492503131e-016;\n#endif\n            for (l = 0; l < width; ++l) {\n                FLOAT const xa = xr[j++];\n                FLOAT const x2 = xa * xa;\n                en0 += x2;\n                rh2 += (x2 < rh1) ? x2 : rh1;\n            }\n            if (en0 > tmpATH)\n                ath_over++;\n            \n            if (en0 < tmpATH) {\n                rh3 = en0;\n            }\n            else if (rh2 < tmpATH) {\n                rh3 = tmpATH;\n            }\n            else {\n                rh3 = rh2;\n            }\n            xmin = rh3;\n            {\n                FLOAT const e = ratio->en.s[sfb][b];\n                if (e > 1e-12f) {\n                    FLOAT   x;\n                    x = en0 * ratio->thm.s[sfb][b] / e;\n                    x *= gfc->sv_qnt.shortfact[sfb];\n                    if (xmin < x)\n                        xmin = x;\n                }\n            }\n            xmin = Max(xmin, DBL_EPSILON);\n            cod_info->energy_above_cutoff[gsfb+b] = (en0 > xmin+1e-14f) ? 1 : 0;\n            *pxmin++ = xmin;\n        }               /* b */\n        if (cfg->use_temporal_masking_effect) {\n            if (pxmin[-3] > pxmin[-3 + 1])\n                pxmin[-3 + 1] += (pxmin[-3] - pxmin[-3 + 1]) * gfc->cd_psy->decay;\n            if (pxmin[-3 + 1] > pxmin[-3 + 2])\n                pxmin[-3 + 2] += (pxmin[-3 + 1] - pxmin[-3 + 2]) * gfc->cd_psy->decay;\n        }\n    }                   /* end of short block sfb loop */\n\n    return ath_over;\n}\n\n\nstatic  FLOAT\ncalc_noise_core_c(const gr_info * const cod_info, int *startline, int l, FLOAT step)\n{\n    FLOAT   noise = 0;\n    int     j = *startline;\n    const int *const ix = cod_info->l3_enc;\n\n    if (j > cod_info->count1) {\n        while (l--) {\n            FLOAT   temp;\n            temp = cod_info->xr[j];\n            j++;\n            noise += temp * temp;\n            temp = cod_info->xr[j];\n            j++;\n            noise += temp * temp;\n        }\n    }\n    else if (j > cod_info->big_values) {\n        FLOAT   ix01[2];\n        ix01[0] = 0;\n        ix01[1] = step;\n        while (l--) {\n            FLOAT   temp;\n            temp = fabs(cod_info->xr[j]) - ix01[ix[j]];\n            j++;\n            noise += temp * temp;\n            temp = fabs(cod_info->xr[j]) - ix01[ix[j]];\n            j++;\n            noise += temp * temp;\n        }\n    }\n    else {\n        while (l--) {\n            FLOAT   temp;\n            temp = fabs(cod_info->xr[j]) - pow43[ix[j]] * step;\n            j++;\n            noise += temp * temp;\n            temp = fabs(cod_info->xr[j]) - pow43[ix[j]] * step;\n            j++;\n            noise += temp * temp;\n        }\n    }\n\n    *startline = j;\n    return noise;\n}\n\n\n/*************************************************************************/\n/*            calc_noise                                                 */\n/*************************************************************************/\n\n/* -oo dB  =>  -1.00 */\n/* - 6 dB  =>  -0.97 */\n/* - 3 dB  =>  -0.80 */\n/* - 2 dB  =>  -0.64 */\n/* - 1 dB  =>  -0.38 */\n/*   0 dB  =>   0.00 */\n/* + 1 dB  =>  +0.49 */\n/* + 2 dB  =>  +1.06 */\n/* + 3 dB  =>  +1.68 */\n/* + 6 dB  =>  +3.69 */\n/* +10 dB  =>  +6.45 */\n\nint\ncalc_noise(gr_info const *const cod_info,\n           FLOAT const *l3_xmin,\n           FLOAT * distort, calc_noise_result * const res, calc_noise_data * prev_noise)\n{\n    int     sfb, l, over = 0;\n    FLOAT   over_noise_db = 0;\n    FLOAT   tot_noise_db = 0; /*    0 dB relative to masking */\n    FLOAT   max_noise = -20.0; /* -200 dB relative to masking */\n    int     j = 0;\n    const int *scalefac = cod_info->scalefac;\n\n    res->over_SSD = 0;\n\n\n    for (sfb = 0; sfb < cod_info->psymax; sfb++) {\n        int const s =\n            cod_info->global_gain - (((*scalefac++) + (cod_info->preflag ? pretab[sfb] : 0))\n                                     << (cod_info->scalefac_scale + 1))\n            - cod_info->subblock_gain[cod_info->window[sfb]] * 8;\n        FLOAT const r_l3_xmin = 1.f / *l3_xmin++;\n        FLOAT   distort_ = 0.0f;\n        FLOAT   noise = 0.0f;\n\n        if (prev_noise && (prev_noise->step[sfb] == s)) {\n\n            /* use previously computed values */\n            j += cod_info->width[sfb];\n            distort_ = r_l3_xmin * prev_noise->noise[sfb];\n\n            noise = prev_noise->noise_log[sfb];\n\n        }\n        else {\n            FLOAT const step = POW20(s);\n            l = cod_info->width[sfb] >> 1;\n\n            if ((j + cod_info->width[sfb]) > cod_info->max_nonzero_coeff) {\n                int     usefullsize;\n                usefullsize = cod_info->max_nonzero_coeff - j + 1;\n\n                if (usefullsize > 0)\n                    l = usefullsize >> 1;\n                else\n                    l = 0;\n            }\n\n            noise = calc_noise_core_c(cod_info, &j, l, step);\n\n\n            if (prev_noise) {\n                /* save noise values */\n                prev_noise->step[sfb] = s;\n                prev_noise->noise[sfb] = noise;\n            }\n\n            distort_ = r_l3_xmin * noise;\n\n            /* multiplying here is adding in dB, but can overflow */\n            noise = FAST_LOG10(Max(distort_, 1E-20f));\n\n            if (prev_noise) {\n                /* save noise values */\n                prev_noise->noise_log[sfb] = noise;\n            }\n        }\n        *distort++ = distort_;\n\n        if (prev_noise) {\n            /* save noise values */\n            prev_noise->global_gain = cod_info->global_gain;;\n        }\n\n\n        /*tot_noise *= Max(noise, 1E-20); */\n        tot_noise_db += noise;\n\n        if (noise > 0.0) {\n            int     tmp;\n\n            tmp = Max((int) (noise * 10 + .5), 1);\n            res->over_SSD += tmp * tmp;\n\n            over++;\n            /* multiplying here is adding in dB -but can overflow */\n            /*over_noise *= noise; */\n            over_noise_db += noise;\n        }\n        max_noise = Max(max_noise, noise);\n\n    }\n\n    res->over_count = over;\n    res->tot_noise = tot_noise_db;\n    res->over_noise = over_noise_db;\n    res->max_noise = max_noise;\n\n    return over;\n}\n\n\n\n\n\n\n\n\n/************************************************************************\n *\n *  set_pinfo()\n *\n *  updates plotting data    \n *\n *  Mark Taylor 2000-??-??                \n *\n *  Robert Hegemann: moved noise/distortion calc into it\n *\n ************************************************************************/\n\nstatic void\nset_pinfo(lame_internal_flags const *gfc,\n          gr_info * const cod_info, const III_psy_ratio * const ratio, const int gr, const int ch)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    int     sfb, sfb2;\n    int     j, i, l, start, end, bw;\n    FLOAT   en0, en1;\n    FLOAT const ifqstep = (cod_info->scalefac_scale == 0) ? .5 : 1.0;\n    int const *const scalefac = cod_info->scalefac;\n\n    FLOAT   l3_xmin[SFBMAX], xfsf[SFBMAX];\n    calc_noise_result noise;\n\n    (void) calc_xmin(gfc, ratio, cod_info, l3_xmin);\n    (void) calc_noise(cod_info, l3_xmin, xfsf, &noise, 0);\n\n    j = 0;\n    sfb2 = cod_info->sfb_lmax;\n    if (cod_info->block_type != SHORT_TYPE && !cod_info->mixed_block_flag)\n        sfb2 = 22;\n    for (sfb = 0; sfb < sfb2; sfb++) {\n        start = gfc->scalefac_band.l[sfb];\n        end = gfc->scalefac_band.l[sfb + 1];\n        bw = end - start;\n        for (en0 = 0.0; j < end; j++)\n            en0 += cod_info->xr[j] * cod_info->xr[j];\n        en0 /= bw;\n        /* convert to MDCT units */\n        en1 = 1e15;     /* scaling so it shows up on FFT plot */\n        gfc->pinfo->en[gr][ch][sfb] = en1 * en0;\n        gfc->pinfo->xfsf[gr][ch][sfb] = en1 * l3_xmin[sfb] * xfsf[sfb] / bw;\n\n        if (ratio->en.l[sfb] > 0 && !cfg->ATHonly)\n            en0 = en0 / ratio->en.l[sfb];\n        else\n            en0 = 0.0;\n\n        gfc->pinfo->thr[gr][ch][sfb] = en1 * Max(en0 * ratio->thm.l[sfb], gfc->ATH->l[sfb]);\n\n        /* there is no scalefactor bands >= SBPSY_l */\n        gfc->pinfo->LAMEsfb[gr][ch][sfb] = 0;\n        if (cod_info->preflag && sfb >= 11)\n            gfc->pinfo->LAMEsfb[gr][ch][sfb] = -ifqstep * pretab[sfb];\n\n        if (sfb < SBPSY_l) {\n            assert(scalefac[sfb] >= 0); /* scfsi should be decoded by caller side */\n            gfc->pinfo->LAMEsfb[gr][ch][sfb] -= ifqstep * scalefac[sfb];\n        }\n    }                   /* for sfb */\n\n    if (cod_info->block_type == SHORT_TYPE) {\n        sfb2 = sfb;\n        for (sfb = cod_info->sfb_smin; sfb < SBMAX_s; sfb++) {\n            start = gfc->scalefac_band.s[sfb];\n            end = gfc->scalefac_band.s[sfb + 1];\n            bw = end - start;\n            for (i = 0; i < 3; i++) {\n                for (en0 = 0.0, l = start; l < end; l++) {\n                    en0 += cod_info->xr[j] * cod_info->xr[j];\n                    j++;\n                }\n                en0 = Max(en0 / bw, 1e-20);\n                /* convert to MDCT units */\n                en1 = 1e15; /* scaling so it shows up on FFT plot */\n\n                gfc->pinfo->en_s[gr][ch][3 * sfb + i] = en1 * en0;\n                gfc->pinfo->xfsf_s[gr][ch][3 * sfb + i] = en1 * l3_xmin[sfb2] * xfsf[sfb2] / bw;\n                if (ratio->en.s[sfb][i] > 0)\n                    en0 = en0 / ratio->en.s[sfb][i];\n                else\n                    en0 = 0.0;\n                if (cfg->ATHonly || cfg->ATHshort)\n                    en0 = 0;\n\n                gfc->pinfo->thr_s[gr][ch][3 * sfb + i] =\n                    en1 * Max(en0 * ratio->thm.s[sfb][i], gfc->ATH->s[sfb]);\n\n                /* there is no scalefactor bands >= SBPSY_s */\n                gfc->pinfo->LAMEsfb_s[gr][ch][3 * sfb + i]\n                    = -2.0 * cod_info->subblock_gain[i];\n                if (sfb < SBPSY_s) {\n                    gfc->pinfo->LAMEsfb_s[gr][ch][3 * sfb + i] -= ifqstep * scalefac[sfb2];\n                }\n                sfb2++;\n            }\n        }\n    }                   /* block type short */\n    gfc->pinfo->LAMEqss[gr][ch] = cod_info->global_gain;\n    gfc->pinfo->LAMEmainbits[gr][ch] = cod_info->part2_3_length + cod_info->part2_length;\n    gfc->pinfo->LAMEsfbits[gr][ch] = cod_info->part2_length;\n\n    gfc->pinfo->over[gr][ch] = noise.over_count;\n    gfc->pinfo->max_noise[gr][ch] = noise.max_noise * 10.0;\n    gfc->pinfo->over_noise[gr][ch] = noise.over_noise * 10.0;\n    gfc->pinfo->tot_noise[gr][ch] = noise.tot_noise * 10.0;\n    gfc->pinfo->over_SSD[gr][ch] = noise.over_SSD;\n}\n\n\n/************************************************************************\n *\n *  set_frame_pinfo()\n *\n *  updates plotting data for a whole frame  \n *\n *  Robert Hegemann 2000-10-21                          \n *\n ************************************************************************/\n\nvoid\nset_frame_pinfo(lame_internal_flags * gfc, const III_psy_ratio ratio[2][2])\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    int     ch;\n    int     gr;\n\n    /* for every granule and channel patch l3_enc and set info\n     */\n    for (gr = 0; gr < cfg->mode_gr; gr++) {\n        for (ch = 0; ch < cfg->channels_out; ch++) {\n            gr_info *const cod_info = &gfc->l3_side.tt[gr][ch];\n            int     scalefac_sav[SFBMAX];\n            memcpy(scalefac_sav, cod_info->scalefac, sizeof(scalefac_sav));\n\n            /* reconstruct the scalefactors in case SCFSI was used \n             */\n            if (gr == 1) {\n                int     sfb;\n                for (sfb = 0; sfb < cod_info->sfb_lmax; sfb++) {\n                    if (cod_info->scalefac[sfb] < 0) /* scfsi */\n                        cod_info->scalefac[sfb] = gfc->l3_side.tt[0][ch].scalefac[sfb];\n                }\n            }\n\n            set_pinfo(gfc, cod_info, &ratio[gr][ch], gr, ch);\n            memcpy(cod_info->scalefac, scalefac_sav, sizeof(scalefac_sav));\n        }               /* for ch */\n    }                   /* for gr */\n}\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/quantize_pvt.h",
    "content": "/*\n *\tquantize_pvt include file\n *\n *\tCopyright (c) 1999 Takehiro TOMINAGA\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\t See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n#ifndef LAME_QUANTIZE_PVT_H\n#define LAME_QUANTIZE_PVT_H\n\n#define IXMAX_VAL 8206  /* ix always <= 8191+15.    see count_bits() */\n\n/* buggy Winamp decoder cannot handle values > 8191 */\n/* #define IXMAX_VAL 8191 */\n\n#define PRECALC_SIZE (IXMAX_VAL+2)\n\n\nextern const int nr_of_sfb_block[6][3][4];\nextern const int pretab[SBMAX_l];\nextern const int slen1_tab[16];\nextern const int slen2_tab[16];\n\nextern const scalefac_struct sfBandIndex[9];\n\nextern FLOAT pow43[PRECALC_SIZE];\n#ifdef TAKEHIRO_IEEE754_HACK\nextern FLOAT adj43asm[PRECALC_SIZE];\n#else\nextern FLOAT adj43[PRECALC_SIZE];\n#endif\n\n#define Q_MAX (256+1)\n#define Q_MAX2 116      /* minimum possible number of\n                           -cod_info->global_gain\n                           + ((scalefac[] + (cod_info->preflag ? pretab[sfb] : 0))\n                           << (cod_info->scalefac_scale + 1))\n                           + cod_info->subblock_gain[cod_info->window[sfb]] * 8;\n\n                           for long block, 0+((15+3)<<2) = 18*4 = 72\n                           for short block, 0+(15<<2)+7*8 = 15*4+56 = 116\n                         */\n\nextern FLOAT pow20[Q_MAX + Q_MAX2 + 1];\nextern FLOAT ipow20[Q_MAX];\n\ntypedef struct calc_noise_result_t {\n    FLOAT   over_noise;      /* sum of quantization noise > masking */\n    FLOAT   tot_noise;       /* sum of all quantization noise */\n    FLOAT   max_noise;       /* max quantization noise */\n    int     over_count;      /* number of quantization noise > masking */\n    int     over_SSD;        /* SSD-like cost of distorted bands */\n    int     bits;\n} calc_noise_result;\n\n\n/**\n* allows re-use of previously\n* computed noise values\n*/\ntypedef struct calc_noise_data_t {\n    int     global_gain;\n    int     sfb_count1;\n    int     step[39];\n    FLOAT   noise[39];\n    FLOAT   noise_log[39];\n} calc_noise_data;\n\n\nint     on_pe(lame_internal_flags * gfc, const FLOAT pe[2][2],\n              int targ_bits[2], int mean_bits, int gr, int cbr);\n\nvoid    reduce_side(int targ_bits[2], FLOAT ms_ener_ratio, int mean_bits, int max_bits);\n\n\nvoid    iteration_init(lame_internal_flags * gfc);\n\n\nint     calc_xmin(lame_internal_flags const *gfc,\n                  III_psy_ratio const *const ratio, gr_info * const cod_info, FLOAT * l3_xmin);\n\nint     calc_noise(const gr_info * const cod_info,\n                   const FLOAT * l3_xmin,\n                   FLOAT * distort, calc_noise_result * const res, calc_noise_data * prev_noise);\n\nvoid    set_frame_pinfo(lame_internal_flags * gfc, const III_psy_ratio ratio[2][2]);\n\n\n\n\n/* takehiro.c */\n\nint     count_bits(lame_internal_flags const *const gfc, const FLOAT * const xr,\n                   gr_info * const cod_info, calc_noise_data * prev_noise);\nint     noquant_count_bits(lame_internal_flags const *const gfc,\n                           gr_info * const cod_info, calc_noise_data * prev_noise);\n\n\nvoid    best_huffman_divide(const lame_internal_flags * const gfc, gr_info * const cod_info);\n\nvoid    best_scalefac_store(const lame_internal_flags * gfc, const int gr, const int ch,\n                            III_side_info_t * const l3_side);\n\nint     scale_bitcount(const lame_internal_flags * gfc, gr_info * cod_info);\n\nvoid    huffman_init(lame_internal_flags * const gfc);\n\nvoid    init_xrpow_core_init(lame_internal_flags * const gfc);\n\nFLOAT   athAdjust(FLOAT a, FLOAT x, FLOAT athFloor, float ATHfixpoint);\n\n#define LARGE_BITS 100000\n\n#endif /* LAME_QUANTIZE_PVT_H */\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/reservoir.c",
    "content": "/*\n *      bit reservoir source file\n *\n *      Copyright (c) 1999-2000 Mark Taylor\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n/* $Id: reservoir.c,v 1.45 2011/05/07 16:05:17 rbrito Exp $ */\n\n#ifdef HAVE_CONFIG_H\n# include <config.h>\n#endif\n\n\n#include \"lame.h\"\n#include \"machine.h\"\n#include \"encoder.h\"\n#include \"util.h\"\n#include \"reservoir.h\"\n\n#include \"bitstream.h\"\n#include \"lame-analysis.h\"\n#include \"lame_global_flags.h\"\n\n\n/*\n  ResvFrameBegin:\n  Called (repeatedly) at the beginning of a frame. Updates the maximum\n  size of the reservoir, and checks to make sure main_data_begin\n  was set properly by the formatter\n*/\n\n/*\n *  Background information:\n *\n *  This is the original text from the ISO standard. Because of\n *  sooo many bugs and irritations correcting comments are added\n *  in brackets []. A '^W' means you should remove the last word.\n *\n *  1) The following rule can be used to calculate the maximum\n *     number of bits used for one granule [^W frame]:\n *     At the highest possible bitrate of Layer III (320 kbps\n *     per stereo signal [^W^W^W], 48 kHz) the frames must be of\n *     [^W^W^W are designed to have] constant length, i.e.\n *     one buffer [^W^W the frame] length is:\n *\n *         320 kbps * 1152/48 kHz = 7680 bit = 960 byte\n *\n *     This value is used as the maximum buffer per channel [^W^W] at\n *     lower bitrates [than 320 kbps]. At 64 kbps mono or 128 kbps\n *     stereo the main granule length is 64 kbps * 576/48 kHz = 768 bit\n *     [per granule and channel] at 48 kHz sampling frequency.\n *     This means that there is a maximum deviation (short time buffer\n *     [= reservoir]) of 7680 - 2*2*768 = 4608 bits is allowed at 64 kbps.\n *     The actual deviation is equal to the number of bytes [with the\n *     meaning of octets] denoted by the main_data_end offset pointer.\n *     The actual maximum deviation is (2^9-1)*8 bit = 4088 bits\n *     [for MPEG-1 and (2^8-1)*8 bit for MPEG-2, both are hard limits].\n *     ... The xchange of buffer bits between the left and right channel\n *     is allowed without restrictions [exception: dual channel].\n *     Because of the [constructed] constraint on the buffer size\n *     main_data_end is always set to 0 in the case of bit_rate_index==14,\n *     i.e. data rate 320 kbps per stereo signal [^W^W^W]. In this case\n *     all data are allocated between adjacent header [^W sync] words\n *     [, i.e. there is no buffering at all].\n */\n\nint\nResvFrameBegin(lame_internal_flags * gfc, int *mean_bits)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    EncStateVar_t *const esv = &gfc->sv_enc;\n    int     fullFrameBits;\n    int     resvLimit;\n    int     maxmp3buf;\n    III_side_info_t *const l3_side = &gfc->l3_side;\n    int     frameLength;\n    int     meanBits;\n\n    frameLength = getframebits(gfc);\n    meanBits = (frameLength - cfg->sideinfo_len * 8) / cfg->mode_gr;\n\n/*\n *  Meaning of the variables:\n *      resvLimit: (0, 8, ..., 8*255 (MPEG-2), 8*511 (MPEG-1))\n *          Number of bits can be stored in previous frame(s) due to\n *          counter size constaints\n *      maxmp3buf: ( ??? ... 8*1951 (MPEG-1 and 2), 8*2047 (MPEG-2.5))\n *          Number of bits allowed to encode one frame (you can take 8*511 bit\n *          from the bit reservoir and at most 8*1440 bit from the current\n *          frame (320 kbps, 32 kHz), so 8*1951 bit is the largest possible\n *          value for MPEG-1 and -2)\n *\n *          maximum allowed granule/channel size times 4 = 8*2047 bits.,\n *          so this is the absolute maximum supported by the format.\n *\n *\n *      fullFrameBits:  maximum number of bits available for encoding\n *                      the current frame.\n *\n *      mean_bits:      target number of bits per granule.\n *\n *      frameLength:\n *\n *      gfc->ResvMax:   maximum allowed reservoir\n *\n *      gfc->ResvSize:  current reservoir size\n *\n *      l3_side->resvDrain_pre:\n *         ancillary data to be added to previous frame:\n *         (only usefull in VBR modes if it is possible to have\n *         maxmp3buf < fullFrameBits)).  Currently disabled,\n *         see #define NEW_DRAIN\n *         2010-02-13: RH now enabled, it seems to be needed for CBR too,\n *                     as there exists one example, where the FhG decoder\n *                     can't decode a -b320 CBR file anymore.\n *\n *      l3_side->resvDrain_post:\n *         ancillary data to be added to this frame:\n *\n */\n\n    /* main_data_begin has 9 bits in MPEG-1, 8 bits MPEG-2 */\n    resvLimit = (8 * 256) * cfg->mode_gr - 8;\n\n    /* maximum allowed frame size.  dont use more than this number of\n       bits, even if the frame has the space for them: */\n    maxmp3buf = cfg->buffer_constraint;\n    esv->ResvMax = maxmp3buf - frameLength;\n    if (esv->ResvMax > resvLimit)\n        esv->ResvMax = resvLimit;\n    if (esv->ResvMax < 0 || cfg->disable_reservoir)\n        esv->ResvMax = 0;\n    \n    fullFrameBits = meanBits * cfg->mode_gr + Min(esv->ResvSize, esv->ResvMax);\n\n    if (fullFrameBits > maxmp3buf)\n        fullFrameBits = maxmp3buf;\n\n    assert(0 == esv->ResvMax % 8);\n    assert(esv->ResvMax >= 0);\n\n    l3_side->resvDrain_pre = 0;\n\n    if (gfc->pinfo != NULL) {\n        gfc->pinfo->mean_bits = meanBits / 2; /* expected bits per channel per granule [is this also right for mono/stereo, MPEG-1/2 ?] */\n        gfc->pinfo->resvsize = esv->ResvSize;\n    }\n    *mean_bits = meanBits;\n    return fullFrameBits;\n}\n\n\n/*\n  ResvMaxBits\n  returns targ_bits:  target number of bits to use for 1 granule\n         extra_bits:  amount extra available from reservoir\n  Mark Taylor 4/99\n*/\nvoid\nResvMaxBits(lame_internal_flags * gfc, int mean_bits, int *targ_bits, int *extra_bits, int cbr)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    EncStateVar_t *const esv = &gfc->sv_enc;\n    int     add_bits, targBits, extraBits;\n    int     ResvSize = esv->ResvSize, ResvMax = esv->ResvMax;\n\n    /* conpensate the saved bits used in the 1st granule */\n    if (cbr)\n        ResvSize += mean_bits;\n\n    if (gfc->sv_qnt.substep_shaping & 1)\n        ResvMax *= 0.9;\n\n    targBits = mean_bits;\n\n    /* extra bits if the reservoir is almost full */\n    if (ResvSize * 10 > ResvMax * 9) {\n        add_bits = ResvSize - (ResvMax * 9) / 10;\n        targBits += add_bits;\n        gfc->sv_qnt.substep_shaping |= 0x80;\n    }\n    else {\n        add_bits = 0;\n        gfc->sv_qnt.substep_shaping &= 0x7f;\n        /* build up reservoir.  this builds the reservoir a little slower\n         * than FhG.  It could simple be mean_bits/15, but this was rigged\n         * to always produce 100 (the old value) at 128kbs */\n        /*    *targ_bits -= (int) (mean_bits/15.2); */\n        if (!cfg->disable_reservoir && !(gfc->sv_qnt.substep_shaping & 1))\n            targBits -= .1 * mean_bits;\n    }\n\n\n    /* amount from the reservoir we are allowed to use. ISO says 6/10 */\n    extraBits = (ResvSize < (esv->ResvMax * 6) / 10 ? ResvSize : (esv->ResvMax * 6) / 10);\n    extraBits -= add_bits;\n\n    if (extraBits < 0)\n        extraBits = 0;\n\n    *targ_bits = targBits;\n    *extra_bits = extraBits;\n}\n\n/*\n  ResvAdjust:\n  Called after a granule's bit allocation. Readjusts the size of\n  the reservoir to reflect the granule's usage.\n*/\nvoid\nResvAdjust(lame_internal_flags * gfc, gr_info const *gi)\n{\n    gfc->sv_enc.ResvSize -= gi->part2_3_length + gi->part2_length;\n}\n\n\n/*\n  ResvFrameEnd:\n  Called after all granules in a frame have been allocated. Makes sure\n  that the reservoir size is within limits, possibly by adding stuffing\n  bits.\n*/\nvoid\nResvFrameEnd(lame_internal_flags * gfc, int mean_bits)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    EncStateVar_t *const esv = &gfc->sv_enc;\n    III_side_info_t *const l3_side = &gfc->l3_side;\n    int     stuffingBits;\n    int     over_bits;\n\n    esv->ResvSize += mean_bits * cfg->mode_gr;\n    stuffingBits = 0;\n    l3_side->resvDrain_post = 0;\n    l3_side->resvDrain_pre = 0;\n\n    /* we must be byte aligned */\n    if ((over_bits = esv->ResvSize % 8) != 0)\n        stuffingBits += over_bits;\n\n\n    over_bits = (esv->ResvSize - stuffingBits) - esv->ResvMax;\n    if (over_bits > 0) {\n        assert(0 == over_bits % 8);\n        assert(over_bits >= 0);\n        stuffingBits += over_bits;\n    }\n\n\n    /* NOTE: enabling the NEW_DRAIN code fixes some problems with FhG decoder\n             shipped with MS Windows operating systems. Using this, it is even\n             possible to use Gabriel's lax buffer consideration again, which\n             assumes, any decoder should have a buffer large enough\n             for a 320 kbps frame at 32 kHz sample rate.\n\n       old drain code:\n             lame -b320 BlackBird.wav ---> does not play with GraphEdit.exe using FhG decoder V1.5 Build 50\n\n       new drain code:\n             lame -b320 BlackBird.wav ---> plays fine with GraphEdit.exe using FhG decoder V1.5 Build 50\n\n             Robert Hegemann, 2010-02-13.\n     */\n    /* drain as many bits as possible into previous frame ancillary data\n     * In particular, in VBR mode ResvMax may have changed, and we have\n     * to make sure main_data_begin does not create a reservoir bigger\n     * than ResvMax  mt 4/00*/\n    {\n        int     mdb_bytes = Min(l3_side->main_data_begin * 8, stuffingBits) / 8;\n        l3_side->resvDrain_pre += 8 * mdb_bytes;\n        stuffingBits -= 8 * mdb_bytes;\n        esv->ResvSize -= 8 * mdb_bytes;\n        l3_side->main_data_begin -= mdb_bytes;\n    }\n    /* drain the rest into this frames ancillary data */\n    l3_side->resvDrain_post += stuffingBits;\n    esv->ResvSize -= stuffingBits;\n}\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/reservoir.h",
    "content": "/*\n *\tbit reservoir include file\n *\n *\tCopyright (c) 1999 Mark Taylor\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\t See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n#ifndef LAME_RESERVOIR_H\n#define LAME_RESERVOIR_H\n\nint     ResvFrameBegin(lame_internal_flags * gfc, int *mean_bits);\nvoid    ResvMaxBits(lame_internal_flags * gfc, int mean_bits, int *targ_bits, int *max_bits,\n                    int cbr);\nvoid    ResvAdjust(lame_internal_flags * gfc, gr_info const *gi);\nvoid    ResvFrameEnd(lame_internal_flags * gfc, int mean_bits);\n\n#endif /* LAME_RESERVOIR_H */\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/set_get.c",
    "content": "/* -*- mode: C; mode: fold -*- */\n/*\n * set/get functions for lame_global_flags\n *\n * Copyright (c) 2001-2005 Alexander Leidinger\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n/* $Id: set_get.c,v 1.98 2011/05/07 16:05:17 rbrito Exp $ */\n\n#ifdef HAVE_CONFIG_H\n# include <config.h>\n#endif\n\n#include \"lame.h\"\n#include \"machine.h\"\n#include \"encoder.h\"\n#include \"util.h\"\n#include \"bitstream.h\"  /* because of compute_flushbits */\n\n#include \"set_get.h\"\n#include \"lame_global_flags.h\"\n\n/*\n * input stream description\n */\n\n\n/* number of samples */\n/* it's unlikely for this function to return an error */\nint\nlame_set_num_samples(lame_global_flags * gfp, unsigned long num_samples)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* default = 2^32-1 */\n        gfp->num_samples = num_samples;\n        return 0;\n    }\n    return -1;\n}\n\nunsigned long\nlame_get_num_samples(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->num_samples;\n    }\n    return 0;\n}\n\n\n/* input samplerate */\nint\nlame_set_in_samplerate(lame_global_flags * gfp, int in_samplerate)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* input sample rate in Hz,  default = 44100 Hz */\n        gfp->samplerate_in = in_samplerate;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_in_samplerate(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->samplerate_in;\n    }\n    return 0;\n}\n\n\n/* number of channels in input stream */\nint\nlame_set_num_channels(lame_global_flags * gfp, int num_channels)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* default = 2 */\n        if (2 < num_channels || 0 == num_channels) {\n            return -1;  /* we don't support more than 2 channels */\n        }\n        gfp->num_channels = num_channels;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_num_channels(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->num_channels;\n    }\n    return 0;\n}\n\n\n/* scale the input by this amount before encoding (not used for decoding) */\nint\nlame_set_scale(lame_global_flags * gfp, float scale)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* default = 1 */\n        gfp->scale = scale;\n        return 0;\n    }\n    return -1;\n}\n\nfloat\nlame_get_scale(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->scale;\n    }\n    return 0;\n}\n\n\n/* scale the channel 0 (left) input by this amount before \n   encoding (not used for decoding) */\nint\nlame_set_scale_left(lame_global_flags * gfp, float scale)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* default = 1 */\n        gfp->scale_left = scale;\n        return 0;\n    }\n    return -1;\n}\n\nfloat\nlame_get_scale_left(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->scale_left;\n    }\n    return 0;\n}\n\n\n/* scale the channel 1 (right) input by this amount before \n   encoding (not used for decoding) */\nint\nlame_set_scale_right(lame_global_flags * gfp, float scale)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* default = 1 */\n        gfp->scale_right = scale;\n        return 0;\n    }\n    return -1;\n}\n\nfloat\nlame_get_scale_right(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->scale_right;\n    }\n    return 0;\n}\n\n\n/* output sample rate in Hz */\nint\nlame_set_out_samplerate(lame_global_flags * gfp, int out_samplerate)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /*\n         * default = 0: LAME picks best value based on the amount\n         *              of compression\n         * MPEG only allows:\n         *  MPEG1    32, 44.1,   48khz\n         *  MPEG2    16, 22.05,  24\n         *  MPEG2.5   8, 11.025, 12\n         *\n         * (not used by decoding routines)\n         */\n        gfp->samplerate_out = out_samplerate;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_out_samplerate(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->samplerate_out;\n    }\n    return 0;\n}\n\n\n\n\n/*\n * general control parameters\n */\n\n/* collect data for an MP3 frame analzyer */\nint\nlame_set_analysis(lame_global_flags * gfp, int analysis)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* default = 0 */\n\n        /* enforce disable/enable meaning, if we need more than two values\n           we need to switch to an enum to have an apropriate representation\n           of the possible meanings of the value */\n        if (0 > analysis || 1 < analysis)\n            return -1;\n        gfp->analysis = analysis;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_analysis(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        assert(0 <= gfp->analysis && 1 >= gfp->analysis);\n        return gfp->analysis;\n    }\n    return 0;\n}\n\n\n/* write a Xing VBR header frame */\nint\nlame_set_bWriteVbrTag(lame_global_flags * gfp, int bWriteVbrTag)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* default = 1 (on) for VBR/ABR modes, 0 (off) for CBR mode */\n\n        /* enforce disable/enable meaning, if we need more than two values\n           we need to switch to an enum to have an apropriate representation\n           of the possible meanings of the value */\n        if (0 > bWriteVbrTag || 1 < bWriteVbrTag)\n            return -1;\n        gfp->write_lame_tag = bWriteVbrTag;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_bWriteVbrTag(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        assert(0 <= gfp->write_lame_tag && 1 >= gfp->write_lame_tag);\n        return gfp->write_lame_tag;\n    }\n    return 0;\n}\n\n\n\n/* decode only, use lame/mpglib to convert mp3 to wav */\nint\nlame_set_decode_only(lame_global_flags * gfp, int decode_only)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* default = 0 (disabled) */\n\n        /* enforce disable/enable meaning, if we need more than two values\n           we need to switch to an enum to have an apropriate representation\n           of the possible meanings of the value */\n        if (0 > decode_only || 1 < decode_only)\n            return -1;\n        gfp->decode_only = decode_only;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_decode_only(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        assert(0 <= gfp->decode_only && 1 >= gfp->decode_only);\n        return gfp->decode_only;\n    }\n    return 0;\n}\n\n\n#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED\n/* 1=encode a Vorbis .ogg file.  default=0 */\n/* DEPRECATED */\nint CDECL lame_set_ogg(lame_global_flags *, int);\nint CDECL lame_get_ogg(const lame_global_flags *);\n#else\n#endif\n\n/* encode a Vorbis .ogg file */\n/* DEPRECATED */\nint\nlame_set_ogg(lame_global_flags * gfp, int ogg)\n{\n    (void) gfp;\n    (void) ogg;\n    return -1;\n}\n\nint\nlame_get_ogg(const lame_global_flags * gfp)\n{\n    (void) gfp;\n    return 0;\n}\n\n\n/*\n * Internal algorithm selection.\n * True quality is determined by the bitrate but this variable will effect\n * quality by selecting expensive or cheap algorithms.\n * quality=0..9.  0=best (very slow).  9=worst.  \n * recommended:  3     near-best quality, not too slow\n *               5     good quality, fast\n *               7     ok quality, really fast\n */\nint\nlame_set_quality(lame_global_flags * gfp, int quality)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        if (quality < 0) {\n            gfp->quality = 0;\n        }\n        else if (quality > 9) {\n            gfp->quality = 9;\n        }\n        else {\n            gfp->quality = quality;\n        }\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_quality(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->quality;\n    }\n    return 0;\n}\n\n\n/* mode = STEREO, JOINT_STEREO, DUAL_CHANNEL (not supported), MONO */\nint\nlame_set_mode(lame_global_flags * gfp, MPEG_mode mode)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        int     mpg_mode = mode;\n        /* default: lame chooses based on compression ratio and input channels */\n        if (mpg_mode < 0 || MAX_INDICATOR <= mpg_mode)\n            return -1;  /* Unknown MPEG mode! */\n        gfp->mode = mode;\n        return 0;\n    }\n    return -1;\n}\n\nMPEG_mode\nlame_get_mode(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        assert(gfp->mode < MAX_INDICATOR);\n        return gfp->mode;\n    }\n    return NOT_SET;\n}\n\n\n#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED\n/*\n  mode_automs.  Use a M/S mode with a switching threshold based on\n  compression ratio\n  DEPRECATED\n*/\nint CDECL lame_set_mode_automs(lame_global_flags *, int);\nint CDECL lame_get_mode_automs(const lame_global_flags *);\n#else\n#endif\n\n/* Us a M/S mode with a switching threshold based on compression ratio */\n/* DEPRECATED */\nint\nlame_set_mode_automs(lame_global_flags * gfp, int mode_automs)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* default = 0 (disabled) */\n\n        /* enforce disable/enable meaning, if we need more than two values\n           we need to switch to an enum to have an apropriate representation\n           of the possible meanings of the value */\n        if (0 > mode_automs || 1 < mode_automs)\n            return -1;\n        lame_set_mode(gfp, JOINT_STEREO);\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_mode_automs(const lame_global_flags * gfp)\n{\n    (void) gfp;\n    return 1;\n}\n\n\n/*\n * Force M/S for all frames.  For testing only.\n * Requires mode = 1.\n */\nint\nlame_set_force_ms(lame_global_flags * gfp, int force_ms)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* default = 0 (disabled) */\n\n        /* enforce disable/enable meaning, if we need more than two values\n           we need to switch to an enum to have an apropriate representation\n           of the possible meanings of the value */\n        if (0 > force_ms || 1 < force_ms)\n            return -1;\n        gfp->force_ms = force_ms;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_force_ms(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        assert(0 <= gfp->force_ms && 1 >= gfp->force_ms);\n        return gfp->force_ms;\n    }\n    return 0;\n}\n\n\n/* Use free_format. */\nint\nlame_set_free_format(lame_global_flags * gfp, int free_format)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* default = 0 (disabled) */\n\n        /* enforce disable/enable meaning, if we need more than two values\n           we need to switch to an enum to have an apropriate representation\n           of the possible meanings of the value */\n        if (0 > free_format || 1 < free_format)\n            return -1;\n        gfp->free_format = free_format;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_free_format(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        assert(0 <= gfp->free_format && 1 >= gfp->free_format);\n        return gfp->free_format;\n    }\n    return 0;\n}\n\n\n\n/* Perform ReplayGain analysis */\nint\nlame_set_findReplayGain(lame_global_flags * gfp, int findReplayGain)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* default = 0 (disabled) */\n\n        /* enforce disable/enable meaning, if we need more than two values\n           we need to switch to an enum to have an apropriate representation\n           of the possible meanings of the value */\n        if (0 > findReplayGain || 1 < findReplayGain)\n            return -1;\n        gfp->findReplayGain = findReplayGain;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_findReplayGain(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        assert(0 <= gfp->findReplayGain && 1 >= gfp->findReplayGain);\n        return gfp->findReplayGain;\n    }\n    return 0;\n}\n\n\n/* Decode on the fly. Find the peak sample. If ReplayGain analysis is \n   enabled then perform it on the decoded data. */\nint\nlame_set_decode_on_the_fly(lame_global_flags * gfp, int decode_on_the_fly)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n#ifndef DECODE_ON_THE_FLY\n        return -1;\n#else\n        /* default = 0 (disabled) */\n\n        /* enforce disable/enable meaning, if we need more than two values\n           we need to switch to an enum to have an apropriate representation\n           of the possible meanings of the value */\n        if (0 > decode_on_the_fly || 1 < decode_on_the_fly)\n            return -1;\n\n        gfp->decode_on_the_fly = decode_on_the_fly;\n\n        return 0;\n#endif\n    }\n    return -1;\n}\n\nint\nlame_get_decode_on_the_fly(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        assert(0 <= gfp->decode_on_the_fly && 1 >= gfp->decode_on_the_fly);\n        return gfp->decode_on_the_fly;\n    }\n    return 0;\n}\n\n#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED\n/* DEPRECATED: now does the same as lame_set_findReplayGain()\n   default = 0 (disabled) */\nint CDECL lame_set_ReplayGain_input(lame_global_flags *, int);\nint CDECL lame_get_ReplayGain_input(const lame_global_flags *);\n\n/* DEPRECATED: now does the same as\n   lame_set_decode_on_the_fly() && lame_set_findReplayGain()\n   default = 0 (disabled) */\nint CDECL lame_set_ReplayGain_decode(lame_global_flags *, int);\nint CDECL lame_get_ReplayGain_decode(const lame_global_flags *);\n\n/* DEPRECATED: now does the same as lame_set_decode_on_the_fly()\n   default = 0 (disabled) */\nint CDECL lame_set_findPeakSample(lame_global_flags *, int);\nint CDECL lame_get_findPeakSample(const lame_global_flags *);\n#else\n#endif\n\n/* DEPRECATED. same as lame_set_decode_on_the_fly() */\nint\nlame_set_findPeakSample(lame_global_flags * gfp, int arg)\n{\n    return lame_set_decode_on_the_fly(gfp, arg);\n}\n\nint\nlame_get_findPeakSample(const lame_global_flags * gfp)\n{\n    return lame_get_decode_on_the_fly(gfp);\n}\n\n/* DEPRECATED. same as lame_set_findReplayGain() */\nint\nlame_set_ReplayGain_input(lame_global_flags * gfp, int arg)\n{\n    return lame_set_findReplayGain(gfp, arg);\n}\n\nint\nlame_get_ReplayGain_input(const lame_global_flags * gfp)\n{\n    return lame_get_findReplayGain(gfp);\n}\n\n/* DEPRECATED. same as lame_set_decode_on_the_fly() &&\n   lame_set_findReplayGain() */\nint\nlame_set_ReplayGain_decode(lame_global_flags * gfp, int arg)\n{\n    if (lame_set_decode_on_the_fly(gfp, arg) < 0 || lame_set_findReplayGain(gfp, arg) < 0)\n        return -1;\n    else\n        return 0;\n}\n\nint\nlame_get_ReplayGain_decode(const lame_global_flags * gfp)\n{\n    if (lame_get_decode_on_the_fly(gfp) > 0 && lame_get_findReplayGain(gfp) > 0)\n        return 1;\n    else\n        return 0;\n}\n\n\n/* set and get some gapless encoding flags */\n\nint\nlame_set_nogap_total(lame_global_flags * gfp, int the_nogap_total)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->nogap_total = the_nogap_total;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_nogap_total(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->nogap_total;\n    }\n    return 0;\n}\n\nint\nlame_set_nogap_currentindex(lame_global_flags * gfp, int the_nogap_index)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->nogap_current = the_nogap_index;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_nogap_currentindex(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->nogap_current;\n    }\n    return 0;\n}\n\n\n/* message handlers */\nint\nlame_set_errorf(lame_global_flags * gfp, void (*func) (const char *, va_list))\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->report.errorf = func;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_set_debugf(lame_global_flags * gfp, void (*func) (const char *, va_list))\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->report.debugf = func;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_set_msgf(lame_global_flags * gfp, void (*func) (const char *, va_list))\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->report.msgf = func;\n        return 0;\n    }\n    return -1;\n}\n\n\n/*\n * Set one of\n *  - brate\n *  - compression ratio.\n *\n * Default is compression ratio of 11.\n */\nint\nlame_set_brate(lame_global_flags * gfp, int brate)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->brate = brate;\n        if (brate > 320) {\n            gfp->disable_reservoir = 1;\n        }\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_brate(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->brate;\n    }\n    return 0;\n}\n\nint\nlame_set_compression_ratio(lame_global_flags * gfp, float compression_ratio)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->compression_ratio = compression_ratio;\n        return 0;\n    }\n    return -1;\n}\n\nfloat\nlame_get_compression_ratio(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->compression_ratio;\n    }\n    return 0;\n}\n\n\n\n\n/*\n * frame parameters\n */\n\n/* Mark as copyright protected. */\nint\nlame_set_copyright(lame_global_flags * gfp, int copyright)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* default = 0 (disabled) */\n\n        /* enforce disable/enable meaning, if we need more than two values\n           we need to switch to an enum to have an apropriate representation\n           of the possible meanings of the value */\n        if (0 > copyright || 1 < copyright)\n            return -1;\n        gfp->copyright = copyright;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_copyright(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        assert(0 <= gfp->copyright && 1 >= gfp->copyright);\n        return gfp->copyright;\n    }\n    return 0;\n}\n\n\n/* Mark as original. */\nint\nlame_set_original(lame_global_flags * gfp, int original)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* default = 1 (enabled) */\n\n        /* enforce disable/enable meaning, if we need more than two values\n           we need to switch to an enum to have an apropriate representation\n           of the possible meanings of the value */\n        if (0 > original || 1 < original)\n            return -1;\n        gfp->original = original;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_original(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        assert(0 <= gfp->original && 1 >= gfp->original);\n        return gfp->original;\n    }\n    return 0;\n}\n\n\n/*\n * error_protection.\n * Use 2 bytes from each frame for CRC checksum.\n */\nint\nlame_set_error_protection(lame_global_flags * gfp, int error_protection)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* default = 0 (disabled) */\n\n        /* enforce disable/enable meaning, if we need more than two values\n           we need to switch to an enum to have an apropriate representation\n           of the possible meanings of the value */\n        if (0 > error_protection || 1 < error_protection)\n            return -1;\n        gfp->error_protection = error_protection;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_error_protection(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        assert(0 <= gfp->error_protection && 1 >= gfp->error_protection);\n        return gfp->error_protection;\n    }\n    return 0;\n}\n\n\n#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED\n/* padding_type. 0=pad no frames  1=pad all frames 2=adjust padding(default) */\nint CDECL lame_set_padding_type(lame_global_flags *, Padding_type);\nPadding_type CDECL lame_get_padding_type(const lame_global_flags *);\n#else\n#endif\n\n/*\n * padding_type.\n *  PAD_NO     = pad no frames\n *  PAD_ALL    = pad all frames\n *  PAD_ADJUST = adjust padding\n */\nint\nlame_set_padding_type(lame_global_flags * gfp, Padding_type padding_type)\n{\n    (void) gfp;\n    (void) padding_type;\n    return 0;\n}\n\nPadding_type\nlame_get_padding_type(const lame_global_flags * gfp)\n{\n    (void) gfp;\n    return PAD_ADJUST;\n}\n\n\n/* MP3 'private extension' bit. Meaningless. */\nint\nlame_set_extension(lame_global_flags * gfp, int extension)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* default = 0 (disabled) */\n        /* enforce disable/enable meaning, if we need more than two values\n           we need to switch to an enum to have an apropriate representation\n           of the possible meanings of the value */\n        if (0 > extension || 1 < extension)\n            return -1;\n        gfp->extension = extension;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_extension(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        assert(0 <= gfp->extension && 1 >= gfp->extension);\n        return gfp->extension;\n    }\n    return 0;\n}\n\n\n/* Enforce strict ISO compliance. */\nint\nlame_set_strict_ISO(lame_global_flags * gfp, int val)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* default = 0 (disabled) */\n        /* enforce disable/enable meaning, if we need more than two values\n           we need to switch to an enum to have an apropriate representation\n           of the possible meanings of the value */\n        if (val < MDB_DEFAULT || MDB_MAXIMUM < val)\n            return -1;\n        gfp->strict_ISO = val;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_strict_ISO(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->strict_ISO;\n    }\n    return 0;\n}\n\n\n\n\n/********************************************************************\n * quantization/noise shaping \n ***********************************************************************/\n\n/* Disable the bit reservoir. For testing only. */\nint\nlame_set_disable_reservoir(lame_global_flags * gfp, int disable_reservoir)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* default = 0 (disabled) */\n\n        /* enforce disable/enable meaning, if we need more than two values\n           we need to switch to an enum to have an apropriate representation\n           of the possible meanings of the value */\n        if (0 > disable_reservoir || 1 < disable_reservoir)\n            return -1;\n        gfp->disable_reservoir = disable_reservoir;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_disable_reservoir(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        assert(0 <= gfp->disable_reservoir && 1 >= gfp->disable_reservoir);\n        return gfp->disable_reservoir;\n    }\n    return 0;\n}\n\n\n\n\nint\nlame_set_experimentalX(lame_global_flags * gfp, int experimentalX)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        lame_set_quant_comp(gfp, experimentalX);\n        lame_set_quant_comp_short(gfp, experimentalX);\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_experimentalX(const lame_global_flags * gfp)\n{\n    return lame_get_quant_comp(gfp);\n}\n\n\n/* Select a different \"best quantization\" function. default = 0 */\nint\nlame_set_quant_comp(lame_global_flags * gfp, int quant_type)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->quant_comp = quant_type;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_quant_comp(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->quant_comp;\n    }\n    return 0;\n}\n\n\n/* Select a different \"best quantization\" function. default = 0 */\nint\nlame_set_quant_comp_short(lame_global_flags * gfp, int quant_type)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->quant_comp_short = quant_type;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_quant_comp_short(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->quant_comp_short;\n    }\n    return 0;\n}\n\n\n/* Another experimental option. For testing only. */\nint\nlame_set_experimentalY(lame_global_flags * gfp, int experimentalY)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->experimentalY = experimentalY;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_experimentalY(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->experimentalY;\n    }\n    return 0;\n}\n\n\nint\nlame_set_experimentalZ(lame_global_flags * gfp, int experimentalZ)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->experimentalZ = experimentalZ;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_experimentalZ(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->experimentalZ;\n    }\n    return 0;\n}\n\n\n/* Naoki's psycho acoustic model. */\nint\nlame_set_exp_nspsytune(lame_global_flags * gfp, int exp_nspsytune)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* default = 0 (disabled) */\n        gfp->exp_nspsytune = exp_nspsytune;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_exp_nspsytune(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->exp_nspsytune;\n    }\n    return 0;\n}\n\n\n\n\n/********************************************************************\n * VBR control\n ***********************************************************************/\n\n/* Types of VBR.  default = vbr_off = CBR */\nint\nlame_set_VBR(lame_global_flags * gfp, vbr_mode VBR)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        int     vbr_q = VBR;\n        if (0 > vbr_q || vbr_max_indicator <= vbr_q)\n            return -1;  /* Unknown VBR mode! */\n        gfp->VBR = VBR;\n        return 0;\n    }\n    return -1;\n}\n\nvbr_mode\nlame_get_VBR(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        assert(gfp->VBR < vbr_max_indicator);\n        return gfp->VBR;\n    }\n    return vbr_off;\n}\n\n\n/*\n * VBR quality level.\n *  0 = highest\n *  9 = lowest \n */\nint\nlame_set_VBR_q(lame_global_flags * gfp, int VBR_q)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        int     ret = 0;\n\n        if (0 > VBR_q) {\n            ret = -1;   /* Unknown VBR quality level! */\n            VBR_q = 0;\n        }\n        if (9 < VBR_q) {\n            ret = -1;\n            VBR_q = 9;\n        }\n        gfp->VBR_q = VBR_q;\n        gfp->VBR_q_frac = 0;\n        return ret;\n    }\n    return -1;\n}\n\nint\nlame_get_VBR_q(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        assert(0 <= gfp->VBR_q && 10 > gfp->VBR_q);\n        return gfp->VBR_q;\n    }\n    return 0;\n}\n\nint\nlame_set_VBR_quality(lame_global_flags * gfp, float VBR_q)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        int     ret = 0;\n\n        if (0 > VBR_q) {\n            ret = -1;   /* Unknown VBR quality level! */\n            VBR_q = 0;\n        }\n        if (9.999 < VBR_q) {\n            ret = -1;\n            VBR_q = 9.999;\n        }\n\n        gfp->VBR_q = (int) VBR_q;\n        gfp->VBR_q_frac = VBR_q - gfp->VBR_q;\n\n        return ret;\n    }\n    return -1;\n}\n\nfloat\nlame_get_VBR_quality(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->VBR_q + gfp->VBR_q_frac;\n    }\n    return 0;\n}\n\n\n/* Ignored except for VBR = vbr_abr (ABR mode) */\nint\nlame_set_VBR_mean_bitrate_kbps(lame_global_flags * gfp, int VBR_mean_bitrate_kbps)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->VBR_mean_bitrate_kbps = VBR_mean_bitrate_kbps;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_VBR_mean_bitrate_kbps(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->VBR_mean_bitrate_kbps;\n    }\n    return 0;\n}\n\nint\nlame_set_VBR_min_bitrate_kbps(lame_global_flags * gfp, int VBR_min_bitrate_kbps)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->VBR_min_bitrate_kbps = VBR_min_bitrate_kbps;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_VBR_min_bitrate_kbps(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->VBR_min_bitrate_kbps;\n    }\n    return 0;\n}\n\nint\nlame_set_VBR_max_bitrate_kbps(lame_global_flags * gfp, int VBR_max_bitrate_kbps)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->VBR_max_bitrate_kbps = VBR_max_bitrate_kbps;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_VBR_max_bitrate_kbps(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->VBR_max_bitrate_kbps;\n    }\n    return 0;\n}\n\n\n/*\n * Strictly enforce VBR_min_bitrate.\n * Normally it will be violated for analog silence.\n */\nint\nlame_set_VBR_hard_min(lame_global_flags * gfp, int VBR_hard_min)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* default = 0 (disabled) */\n\n        /* enforce disable/enable meaning, if we need more than two values\n           we need to switch to an enum to have an apropriate representation\n           of the possible meanings of the value */\n        if (0 > VBR_hard_min || 1 < VBR_hard_min)\n            return -1;\n\n        gfp->VBR_hard_min = VBR_hard_min;\n\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_VBR_hard_min(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        assert(0 <= gfp->VBR_hard_min && 1 >= gfp->VBR_hard_min);\n        return gfp->VBR_hard_min;\n    }\n    return 0;\n}\n\n\n/********************************************************************\n * Filtering control\n ***********************************************************************/\n\n/*\n * Freqency in Hz to apply lowpass.\n *   0 = default = lame chooses\n *  -1 = disabled\n */\nint\nlame_set_lowpassfreq(lame_global_flags * gfp, int lowpassfreq)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->lowpassfreq = lowpassfreq;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_lowpassfreq(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->lowpassfreq;\n    }\n    return 0;\n}\n\n\n/*\n * Width of transition band (in Hz).\n *  default = one polyphase filter band\n */\nint\nlame_set_lowpasswidth(lame_global_flags * gfp, int lowpasswidth)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->lowpasswidth = lowpasswidth;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_lowpasswidth(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->lowpasswidth;\n    }\n    return 0;\n}\n\n\n/*\n * Frequency in Hz to apply highpass.\n *   0 = default = lame chooses\n *  -1 = disabled\n */\nint\nlame_set_highpassfreq(lame_global_flags * gfp, int highpassfreq)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->highpassfreq = highpassfreq;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_highpassfreq(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->highpassfreq;\n    }\n    return 0;\n}\n\n\n/*\n * Width of transition band (in Hz).\n *  default = one polyphase filter band\n */\nint\nlame_set_highpasswidth(lame_global_flags * gfp, int highpasswidth)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->highpasswidth = highpasswidth;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_highpasswidth(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->highpasswidth;\n    }\n    return 0;\n}\n\n\n\n\n/*\n * psycho acoustics and other arguments which you should not change \n * unless you know what you are doing\n */\n\n\n/* Adjust masking values. */\nint\nlame_set_maskingadjust(lame_global_flags * gfp, float adjust)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->maskingadjust = adjust;\n        return 0;\n    }\n    return -1;\n}\n\nfloat\nlame_get_maskingadjust(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->maskingadjust;\n    }\n    return 0;\n}\n\nint\nlame_set_maskingadjust_short(lame_global_flags * gfp, float adjust)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->maskingadjust_short = adjust;\n        return 0;\n    }\n    return -1;\n}\n\nfloat\nlame_get_maskingadjust_short(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->maskingadjust_short;\n    }\n    return 0;\n}\n\n/* Only use ATH for masking. */\nint\nlame_set_ATHonly(lame_global_flags * gfp, int ATHonly)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->ATHonly = ATHonly;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_ATHonly(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->ATHonly;\n    }\n    return 0;\n}\n\n\n/* Only use ATH for short blocks. */\nint\nlame_set_ATHshort(lame_global_flags * gfp, int ATHshort)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->ATHshort = ATHshort;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_ATHshort(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->ATHshort;\n    }\n    return 0;\n}\n\n\n/* Disable ATH. */\nint\nlame_set_noATH(lame_global_flags * gfp, int noATH)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->noATH = noATH;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_noATH(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->noATH;\n    }\n    return 0;\n}\n\n\n/* Select ATH formula. */\nint\nlame_set_ATHtype(lame_global_flags * gfp, int ATHtype)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* XXX: ATHtype should be converted to an enum. */\n        gfp->ATHtype = ATHtype;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_ATHtype(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->ATHtype;\n    }\n    return 0;\n}\n\n\n/* Select ATH formula 4 shape. */\nint\nlame_set_ATHcurve(lame_global_flags * gfp, float ATHcurve)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->ATHcurve = ATHcurve;\n        return 0;\n    }\n    return -1;\n}\n\nfloat\nlame_get_ATHcurve(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->ATHcurve;\n    }\n    return 0;\n}\n\n\n/* Lower ATH by this many db. */\nint\nlame_set_ATHlower(lame_global_flags * gfp, float ATHlower)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->ATH_lower_db = ATHlower;\n        return 0;\n    }\n    return -1;\n}\n\nfloat\nlame_get_ATHlower(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->ATH_lower_db;\n    }\n    return 0;\n}\n\n\n/* Select ATH adaptive adjustment scheme. */\nint\nlame_set_athaa_type(lame_global_flags * gfp, int athaa_type)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->athaa_type = athaa_type;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_athaa_type(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->athaa_type;\n    }\n    return 0;\n}\n\n\n#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED\nint CDECL lame_set_athaa_loudapprox(lame_global_flags * gfp, int athaa_loudapprox);\nint CDECL lame_get_athaa_loudapprox(const lame_global_flags * gfp);\n#else\n#endif\n\n/* Select the loudness approximation used by the ATH adaptive auto-leveling. */\nint\nlame_set_athaa_loudapprox(lame_global_flags * gfp, int athaa_loudapprox)\n{\n    (void) gfp;\n    (void) athaa_loudapprox;\n    return 0;\n}\n\nint\nlame_get_athaa_loudapprox(const lame_global_flags * gfp)\n{\n    (void) gfp;\n    /* obsolete, the type known under number 2 is the only survival */\n    return 2;\n}\n\n\n/* Adjust (in dB) the point below which adaptive ATH level adjustment occurs. */\nint\nlame_set_athaa_sensitivity(lame_global_flags * gfp, float athaa_sensitivity)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->athaa_sensitivity = athaa_sensitivity;\n        return 0;\n    }\n    return -1;\n}\n\nfloat\nlame_get_athaa_sensitivity(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->athaa_sensitivity;\n    }\n    return 0;\n}\n\n\n/* Predictability limit (ISO tonality formula) */\nint     lame_set_cwlimit(lame_global_flags * gfp, int cwlimit);\nint     lame_get_cwlimit(const lame_global_flags * gfp);\n\nint\nlame_set_cwlimit(lame_global_flags * gfp, int cwlimit)\n{\n    (void) gfp;\n    (void) cwlimit;\n    return 0;\n}\n\nint\nlame_get_cwlimit(const lame_global_flags * gfp)\n{\n    (void) gfp;\n    return 0;\n}\n\n\n\n/*\n * Allow blocktypes to differ between channels.\n * default:\n *  0 for jstereo => block types coupled\n *  1 for stereo  => block types may differ\n */\nint\nlame_set_allow_diff_short(lame_global_flags * gfp, int allow_diff_short)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->short_blocks = allow_diff_short ? short_block_allowed : short_block_coupled;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_allow_diff_short(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        if (gfp->short_blocks == short_block_allowed)\n            return 1;   /* short blocks allowed to differ */\n        else\n            return 0;   /* not set, dispensed, forced or coupled */\n    }\n    return 0;\n}\n\n\n/* Use temporal masking effect */\nint\nlame_set_useTemporal(lame_global_flags * gfp, int useTemporal)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* default = 1 (enabled) */\n\n        /* enforce disable/enable meaning, if we need more than two values\n           we need to switch to an enum to have an apropriate representation\n           of the possible meanings of the value */\n        if (0 <= useTemporal && useTemporal <= 1) {\n            gfp->useTemporal = useTemporal;\n            return 0;\n        }\n    }\n    return -1;\n}\n\nint\nlame_get_useTemporal(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        assert(0 <= gfp->useTemporal && 1 >= gfp->useTemporal);\n        return gfp->useTemporal;\n    }\n    return 0;\n}\n\n\n/* Use inter-channel masking effect */\nint\nlame_set_interChRatio(lame_global_flags * gfp, float ratio)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* default = 0.0 (no inter-channel maskin) */\n        if (0 <= ratio && ratio <= 1.0) {\n            gfp->interChRatio = ratio;\n            return 0;\n        }\n    }\n    return -1;\n}\n\nfloat\nlame_get_interChRatio(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        assert((0 <= gfp->interChRatio && gfp->interChRatio <= 1.0) || EQ(gfp->interChRatio, -1));\n        return gfp->interChRatio;\n    }\n    return 0;\n}\n\n\n/* Use pseudo substep shaping method */\nint\nlame_set_substep(lame_global_flags * gfp, int method)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* default = 0.0 (no substep noise shaping) */\n        if (0 <= method && method <= 7) {\n            gfp->substep_shaping = method;\n            return 0;\n        }\n    }\n    return -1;\n}\n\nint\nlame_get_substep(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        assert(0 <= gfp->substep_shaping && gfp->substep_shaping <= 7);\n        return gfp->substep_shaping;\n    }\n    return 0;\n}\n\n/* scalefactors scale */\nint\nlame_set_sfscale(lame_global_flags * gfp, int val)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->noise_shaping = (val != 0) ? 2 : 1;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_sfscale(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return (gfp->noise_shaping == 2) ? 1 : 0;\n    }\n    return 0;\n}\n\n/* subblock gain */\nint\nlame_set_subblock_gain(lame_global_flags * gfp, int sbgain)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->subblock_gain = sbgain;\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_subblock_gain(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->subblock_gain;\n    }\n    return 0;\n}\n\n\n/* Disable short blocks. */\nint\nlame_set_no_short_blocks(lame_global_flags * gfp, int no_short_blocks)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* enforce disable/enable meaning, if we need more than two values\n           we need to switch to an enum to have an apropriate representation\n           of the possible meanings of the value */\n        if (0 <= no_short_blocks && no_short_blocks <= 1) {\n            gfp->short_blocks = no_short_blocks ? short_block_dispensed : short_block_allowed;\n            return 0;\n        }\n    }\n    return -1;\n}\n\nint\nlame_get_no_short_blocks(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        switch (gfp->short_blocks) {\n        default:\n        case short_block_not_set:\n            return -1;\n        case short_block_dispensed:\n            return 1;\n        case short_block_allowed:\n        case short_block_coupled:\n        case short_block_forced:\n            return 0;\n        }\n    }\n    return -1;\n}\n\n\n/* Force short blocks. */\nint\nlame_set_force_short_blocks(lame_global_flags * gfp, int short_blocks)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* enforce disable/enable meaning, if we need more than two values\n           we need to switch to an enum to have an apropriate representation\n           of the possible meanings of the value */\n        if (0 > short_blocks || 1 < short_blocks)\n            return -1;\n\n        if (short_blocks == 1)\n            gfp->short_blocks = short_block_forced;\n        else if (gfp->short_blocks == short_block_forced)\n            gfp->short_blocks = short_block_allowed;\n\n        return 0;\n    }\n    return -1;\n}\n\nint\nlame_get_force_short_blocks(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        switch (gfp->short_blocks) {\n        default:\n        case short_block_not_set:\n            return -1;\n        case short_block_dispensed:\n        case short_block_allowed:\n        case short_block_coupled:\n            return 0;\n        case short_block_forced:\n            return 1;\n        }\n    }\n    return -1;\n}\n\nint\nlame_set_short_threshold_lrm(lame_global_flags * gfp, float lrm)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->attackthre = lrm;\n        return 0;\n    }\n    return -1;\n}\n\nfloat\nlame_get_short_threshold_lrm(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->attackthre;\n    }\n    return 0;\n}\n\nint\nlame_set_short_threshold_s(lame_global_flags * gfp, float s)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->attackthre_s = s;\n        return 0;\n    }\n    return -1;\n}\n\nfloat\nlame_get_short_threshold_s(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->attackthre_s;\n    }\n    return 0;\n}\n\nint\nlame_set_short_threshold(lame_global_flags * gfp, float lrm, float s)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        lame_set_short_threshold_lrm(gfp, lrm);\n        lame_set_short_threshold_s(gfp, s);\n        return 0;\n    }\n    return -1;\n}\n\n\n/*\n * Input PCM is emphased PCM\n * (for instance from one of the rarely emphased CDs).\n *\n * It is STRONGLY not recommended to use this, because psycho does not\n * take it into account, and last but not least many decoders\n * ignore these bits\n */\nint\nlame_set_emphasis(lame_global_flags * gfp, int emphasis)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* XXX: emphasis should be converted to an enum */\n        if (0 <= emphasis && emphasis < 4) {\n            gfp->emphasis = emphasis;\n            return 0;\n        }\n    }\n    return -1;\n}\n\nint\nlame_get_emphasis(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        assert(0 <= gfp->emphasis && gfp->emphasis < 4);\n        return gfp->emphasis;\n    }\n    return 0;\n}\n\n\n\n\n/***************************************************************/\n/* internal variables, cannot be set...                        */\n/* provided because they may be of use to calling application  */\n/***************************************************************/\n\n/* MPEG version.\n *  0 = MPEG-2\n *  1 = MPEG-1\n * (2 = MPEG-2.5)    \n */\nint\nlame_get_version(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        lame_internal_flags const *const gfc = gfp->internal_flags;\n        if (is_lame_internal_flags_valid(gfc)) {\n            return gfc->cfg.version;\n        }\n    }\n    return 0;\n}\n\n\n/* Encoder delay. */\nint\nlame_get_encoder_delay(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        lame_internal_flags const *const gfc = gfp->internal_flags;\n        if (is_lame_internal_flags_valid(gfc)) {\n            return gfc->ov_enc.encoder_delay;\n        }\n    }\n    return 0;\n}\n\n/* padding added to the end of the input */\nint\nlame_get_encoder_padding(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        lame_internal_flags const *const gfc = gfp->internal_flags;\n        if (is_lame_internal_flags_valid(gfc)) {\n            return gfc->ov_enc.encoder_padding;\n        }\n    }\n    return 0;\n}\n\n\n/* Size of MPEG frame. */\nint\nlame_get_framesize(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        lame_internal_flags const *const gfc = gfp->internal_flags;\n        if (is_lame_internal_flags_valid(gfc)) {\n            SessionConfig_t const *const cfg = &gfc->cfg;\n            return 576 * cfg->mode_gr;\n        }\n    }\n    return 0;\n}\n\n\n/* Number of frames encoded so far. */\nint\nlame_get_frameNum(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        lame_internal_flags const *const gfc = gfp->internal_flags;\n        if (is_lame_internal_flags_valid(gfc)) {\n            return gfc->ov_enc.frame_number;\n        }\n    }\n    return 0;\n}\n\nint\nlame_get_mf_samples_to_encode(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        lame_internal_flags const *const gfc = gfp->internal_flags;\n        if (is_lame_internal_flags_valid(gfc)) {\n            return gfc->sv_enc.mf_samples_to_encode;\n        }\n    }\n    return 0;\n}\n\nint     CDECL\nlame_get_size_mp3buffer(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        lame_internal_flags const *const gfc = gfp->internal_flags;\n        if (is_lame_internal_flags_valid(gfc)) {\n            int     size;\n            compute_flushbits(gfc, &size);\n            return size;\n        }\n    }\n    return 0;\n}\n\nint\nlame_get_RadioGain(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        lame_internal_flags const *const gfc = gfp->internal_flags;\n        if (is_lame_internal_flags_valid(gfc)) {\n            return gfc->ov_rpg.RadioGain;\n        }\n    }\n    return 0;\n}\n\nint\nlame_get_AudiophileGain(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        lame_internal_flags const *const gfc = gfp->internal_flags;\n        if (is_lame_internal_flags_valid(gfc)) {\n            return 0;\n        }\n    }\n    return 0;\n}\n\nfloat\nlame_get_PeakSample(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        lame_internal_flags const *const gfc = gfp->internal_flags;\n        if (is_lame_internal_flags_valid(gfc)) {\n            return (float) gfc->ov_rpg.PeakSample;\n        }\n    }\n    return 0;\n}\n\nint\nlame_get_noclipGainChange(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        lame_internal_flags const *const gfc = gfp->internal_flags;\n        if (is_lame_internal_flags_valid(gfc)) {\n            return gfc->ov_rpg.noclipGainChange;\n        }\n    }\n    return 0;\n}\n\nfloat\nlame_get_noclipScale(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        lame_internal_flags const *const gfc = gfp->internal_flags;\n        if (is_lame_internal_flags_valid(gfc)) {\n            return gfc->ov_rpg.noclipScale;\n        }\n    }\n    return 0;\n}\n\n\n/*\n * LAME's estimate of the total number of frames to be encoded.\n * Only valid if calling program set num_samples.\n */\nint\nlame_get_totalframes(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        lame_internal_flags const *const gfc = gfp->internal_flags;\n        if (is_lame_internal_flags_valid(gfc)) {\n            SessionConfig_t const *const cfg = &gfc->cfg;\n            unsigned long const pcm_samples_per_frame = 576 * cfg->mode_gr;\n            unsigned long pcm_samples_to_encode = gfp->num_samples;\n            unsigned long end_padding = 0;\n\n            /* estimate based on user set num_samples: */\n            if (pcm_samples_to_encode == (0ul-1ul)) {\n                return 0;\n            }\n            if (gfp->samplerate_in != gfp->samplerate_out && gfp->samplerate_in > 0) {\n                double const q = (double)gfp->samplerate_out / gfp->samplerate_in;\n                pcm_samples_to_encode *= q;\n            }\n            pcm_samples_to_encode += 576;\n            end_padding = pcm_samples_per_frame - (pcm_samples_to_encode % pcm_samples_per_frame);\n            if (end_padding < 576) {\n                end_padding += pcm_samples_per_frame;\n            }\n            pcm_samples_to_encode += end_padding;\n            /* check to see if we underestimated totalframes */\n            /*    if (totalframes < gfp->frameNum) */\n            /*        totalframes = gfp->frameNum; */\n            return pcm_samples_to_encode / pcm_samples_per_frame;\n        }\n    }\n    return 0;\n}\n\n\n\n\n\nint\nlame_set_preset(lame_global_flags * gfp, int preset)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->preset = preset;\n        return apply_preset(gfp, preset, 1);\n    }\n    return -1;\n}\n\n\n\nint\nlame_set_asm_optimizations(lame_global_flags * gfp, int optim, int mode)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        mode = (mode == 1 ? 1 : 0);\n        switch (optim) {\n        case MMX:{\n                gfp->asm_optimizations.mmx = mode;\n                return optim;\n            }\n        case AMD_3DNOW:{\n                gfp->asm_optimizations.amd3dnow = mode;\n                return optim;\n            }\n        case SSE:{\n                gfp->asm_optimizations.sse = mode;\n                return optim;\n            }\n        default:\n            return optim;\n        }\n    }\n    return -1;\n}\n\n\nvoid\nlame_set_write_id3tag_automatic(lame_global_flags * gfp, int v)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->write_id3tag_automatic = v;\n    }\n}\n\n\nint\nlame_get_write_id3tag_automatic(lame_global_flags const *gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->write_id3tag_automatic;\n    }\n    return 1;\n}\n\n\n/*\n\nUNDOCUMENTED, experimental settings.  These routines are not prototyped\nin lame.h.  You should not use them, they are experimental and may\nchange.  \n\n*/\n\n\n/*\n *  just another daily changing developer switch  \n */\nvoid CDECL lame_set_tune(lame_global_flags *, float);\n\nvoid\nlame_set_tune(lame_global_flags * gfp, float val)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        gfp->tune_value_a = val;\n        gfp->tune = 1;\n    }\n}\n\n/* Custom msfix hack */\nvoid\nlame_set_msfix(lame_global_flags * gfp, double msfix)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        /* default = 0 */\n        gfp->msfix = msfix;\n    }\n}\n\nfloat\nlame_get_msfix(const lame_global_flags * gfp)\n{\n    if (is_lame_global_flags_valid(gfp)) {\n        return gfp->msfix;\n    }\n    return 0;\n}\n\n#if DEPRECATED_OR_OBSOLETE_CODE_REMOVED\nint CDECL lame_set_preset_expopts(lame_global_flags *, int);\n#else\n#endif\n\nint\nlame_set_preset_expopts(lame_global_flags * gfp, int preset_expopts)\n{\n    (void) gfp;\n    (void) preset_expopts;\n    return 0;\n}\n\n\nint\nlame_set_preset_notune(lame_global_flags * gfp, int preset_notune)\n{\n    (void) gfp;\n    (void) preset_notune;\n    return 0;\n}\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/set_get.h",
    "content": "/*\n * set_get.h -- Internal set/get definitions\n *\n * Copyright (C) 2003 Gabriel Bouvigne / Lame project\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.\n */\n\n#ifndef __SET_GET_H__\n#define __SET_GET_H__\n\n#include \"lame.h\"\n\n#if defined(__cplusplus)\nextern  \"C\" {\n#endif\n\n/* select psychoacoustic model */\n\n/* manage short blocks */\n    int CDECL lame_set_short_threshold(lame_global_flags *, float, float);\n    int CDECL lame_set_short_threshold_lrm(lame_global_flags *, float);\n    float CDECL lame_get_short_threshold_lrm(const lame_global_flags *);\n    int CDECL lame_set_short_threshold_s(lame_global_flags *, float);\n    float CDECL lame_get_short_threshold_s(const lame_global_flags *);\n\n\n    int CDECL lame_set_maskingadjust(lame_global_flags *, float);\n    float CDECL lame_get_maskingadjust(const lame_global_flags *);\n\n    int CDECL lame_set_maskingadjust_short(lame_global_flags *, float);\n    float CDECL lame_get_maskingadjust_short(const lame_global_flags *);\n\n/* select ATH formula 4 shape */\n    int CDECL lame_set_ATHcurve(lame_global_flags *, float);\n    float CDECL lame_get_ATHcurve(const lame_global_flags *);\n\n    int CDECL lame_set_preset_notune(lame_global_flags *, int);\n\n/* substep shaping method */\n    int CDECL lame_set_substep(lame_global_flags *, int);\n    int CDECL lame_get_substep(const lame_global_flags *);\n\n/* scalefactors scale */\n    int CDECL lame_set_sfscale(lame_global_flags *, int);\n    int CDECL lame_get_sfscale(const lame_global_flags *);\n\n/* subblock gain */\n    int CDECL lame_set_subblock_gain(lame_global_flags *, int);\n    int CDECL lame_get_subblock_gain(const lame_global_flags *);\n\n\n\n/*presets*/\n    int     apply_preset(lame_global_flags *, int preset, int enforce);\n\n    void CDECL lame_set_tune(lame_t, float); /* FOR INTERNAL USE ONLY */\n    void CDECL lame_set_msfix(lame_t gfp, double msfix);\n\n\n#if defined(__cplusplus)\n}\n#endif\n#endif\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/tables.c",
    "content": "/*\n *\tMPEG layer 3 tables source file\n *\n *\tCopyright (c) 1999 Albert L Faber\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\t See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n/* $Id: tables.c,v 1.29 2011/05/07 16:05:17 rbrito Exp $ */\n\n#ifdef HAVE_CONFIG_H\n# include <config.h>\n#endif\n\n#include \"machine.h\"\n\n#include \"lame.h\"\n#include \"tables.h\"\n\n\nstatic const uint16_t t1HB[] = {\n    1, 1,\n    1, 0\n};\n\nstatic const uint16_t t2HB[] = {\n    1, 2, 1,\n    3, 1, 1,\n    3, 2, 0\n};\n\nstatic const uint16_t t3HB[] = {\n    3, 2, 1,\n    1, 1, 1,\n    3, 2, 0\n};\n\nstatic const uint16_t t5HB[] = {\n    1, 2, 6, 5,\n    3, 1, 4, 4,\n    7, 5, 7, 1,\n    6, 1, 1, 0\n};\n\nstatic const uint16_t t6HB[] = {\n    7, 3, 5, 1,\n    6, 2, 3, 2,\n    5, 4, 4, 1,\n    3, 3, 2, 0\n};\n\nstatic const uint16_t t7HB[] = {\n    1, 2, 10, 19, 16, 10,\n    3, 3, 7, 10, 5, 3,\n    11, 4, 13, 17, 8, 4,\n    12, 11, 18, 15, 11, 2,\n    7, 6, 9, 14, 3, 1,\n    6, 4, 5, 3, 2, 0\n};\n\nstatic const uint16_t t8HB[] = {\n    3, 4, 6, 18, 12, 5,\n    5, 1, 2, 16, 9, 3,\n    7, 3, 5, 14, 7, 3,\n    19, 17, 15, 13, 10, 4,\n    13, 5, 8, 11, 5, 1,\n    12, 4, 4, 1, 1, 0\n};\n\nstatic const uint16_t t9HB[] = {\n    7, 5, 9, 14, 15, 7,\n    6, 4, 5, 5, 6, 7,\n    7, 6, 8, 8, 8, 5,\n    15, 6, 9, 10, 5, 1,\n    11, 7, 9, 6, 4, 1,\n    14, 4, 6, 2, 6, 0\n};\n\nstatic const uint16_t t10HB[] = {\n    1, 2, 10, 23, 35, 30, 12, 17,\n    3, 3, 8, 12, 18, 21, 12, 7,\n    11, 9, 15, 21, 32, 40, 19, 6,\n    14, 13, 22, 34, 46, 23, 18, 7,\n    20, 19, 33, 47, 27, 22, 9, 3,\n    31, 22, 41, 26, 21, 20, 5, 3,\n    14, 13, 10, 11, 16, 6, 5, 1,\n    9, 8, 7, 8, 4, 4, 2, 0\n};\n\nstatic const uint16_t t11HB[] = {\n    3, 4, 10, 24, 34, 33, 21, 15,\n    5, 3, 4, 10, 32, 17, 11, 10,\n    11, 7, 13, 18, 30, 31, 20, 5,\n    25, 11, 19, 59, 27, 18, 12, 5,\n    35, 33, 31, 58, 30, 16, 7, 5,\n    28, 26, 32, 19, 17, 15, 8, 14,\n    14, 12, 9, 13, 14, 9, 4, 1,\n    11, 4, 6, 6, 6, 3, 2, 0\n};\n\nstatic const uint16_t t12HB[] = {\n    9, 6, 16, 33, 41, 39, 38, 26,\n    7, 5, 6, 9, 23, 16, 26, 11,\n    17, 7, 11, 14, 21, 30, 10, 7,\n    17, 10, 15, 12, 18, 28, 14, 5,\n    32, 13, 22, 19, 18, 16, 9, 5,\n    40, 17, 31, 29, 17, 13, 4, 2,\n    27, 12, 11, 15, 10, 7, 4, 1,\n    27, 12, 8, 12, 6, 3, 1, 0\n};\n\nstatic const uint16_t t13HB[] = {\n    1, 5, 14, 21, 34, 51, 46, 71, 42, 52, 68, 52, 67, 44, 43, 19,\n    3, 4, 12, 19, 31, 26, 44, 33, 31, 24, 32, 24, 31, 35, 22, 14,\n    15, 13, 23, 36, 59, 49, 77, 65, 29, 40, 30, 40, 27, 33, 42, 16,\n    22, 20, 37, 61, 56, 79, 73, 64, 43, 76, 56, 37, 26, 31, 25, 14,\n    35, 16, 60, 57, 97, 75, 114, 91, 54, 73, 55, 41, 48, 53, 23, 24,\n    58, 27, 50, 96, 76, 70, 93, 84, 77, 58, 79, 29, 74, 49, 41, 17,\n    47, 45, 78, 74, 115, 94, 90, 79, 69, 83, 71, 50, 59, 38, 36, 15,\n    72, 34, 56, 95, 92, 85, 91, 90, 86, 73, 77, 65, 51, 44, 43, 42,\n    43, 20, 30, 44, 55, 78, 72, 87, 78, 61, 46, 54, 37, 30, 20, 16,\n    53, 25, 41, 37, 44, 59, 54, 81, 66, 76, 57, 54, 37, 18, 39, 11,\n    35, 33, 31, 57, 42, 82, 72, 80, 47, 58, 55, 21, 22, 26, 38, 22,\n    53, 25, 23, 38, 70, 60, 51, 36, 55, 26, 34, 23, 27, 14, 9, 7,\n    34, 32, 28, 39, 49, 75, 30, 52, 48, 40, 52, 28, 18, 17, 9, 5,\n    45, 21, 34, 64, 56, 50, 49, 45, 31, 19, 12, 15, 10, 7, 6, 3,\n    48, 23, 20, 39, 36, 35, 53, 21, 16, 23, 13, 10, 6, 1, 4, 2,\n    16, 15, 17, 27, 25, 20, 29, 11, 17, 12, 16, 8, 1, 1, 0, 1\n};\n\nstatic const uint16_t t15HB[] = {\n    7, 12, 18, 53, 47, 76, 124, 108, 89, 123, 108, 119, 107, 81, 122, 63,\n    13, 5, 16, 27, 46, 36, 61, 51, 42, 70, 52, 83, 65, 41, 59, 36,\n    19, 17, 15, 24, 41, 34, 59, 48, 40, 64, 50, 78, 62, 80, 56, 33,\n    29, 28, 25, 43, 39, 63, 55, 93, 76, 59, 93, 72, 54, 75, 50, 29,\n    52, 22, 42, 40, 67, 57, 95, 79, 72, 57, 89, 69, 49, 66, 46, 27,\n    77, 37, 35, 66, 58, 52, 91, 74, 62, 48, 79, 63, 90, 62, 40, 38,\n    125, 32, 60, 56, 50, 92, 78, 65, 55, 87, 71, 51, 73, 51, 70, 30,\n    109, 53, 49, 94, 88, 75, 66, 122, 91, 73, 56, 42, 64, 44, 21, 25,\n    90, 43, 41, 77, 73, 63, 56, 92, 77, 66, 47, 67, 48, 53, 36, 20,\n    71, 34, 67, 60, 58, 49, 88, 76, 67, 106, 71, 54, 38, 39, 23, 15,\n    109, 53, 51, 47, 90, 82, 58, 57, 48, 72, 57, 41, 23, 27, 62, 9,\n    86, 42, 40, 37, 70, 64, 52, 43, 70, 55, 42, 25, 29, 18, 11, 11,\n    118, 68, 30, 55, 50, 46, 74, 65, 49, 39, 24, 16, 22, 13, 14, 7,\n    91, 44, 39, 38, 34, 63, 52, 45, 31, 52, 28, 19, 14, 8, 9, 3,\n    123, 60, 58, 53, 47, 43, 32, 22, 37, 24, 17, 12, 15, 10, 2, 1,\n    71, 37, 34, 30, 28, 20, 17, 26, 21, 16, 10, 6, 8, 6, 2, 0\n};\n\nstatic const uint16_t t16HB[] = {\n    1, 5, 14, 44, 74, 63, 110, 93, 172, 149, 138, 242, 225, 195, 376, 17,\n    3, 4, 12, 20, 35, 62, 53, 47, 83, 75, 68, 119, 201, 107, 207, 9,\n    15, 13, 23, 38, 67, 58, 103, 90, 161, 72, 127, 117, 110, 209, 206, 16,\n    45, 21, 39, 69, 64, 114, 99, 87, 158, 140, 252, 212, 199, 387, 365, 26,\n    75, 36, 68, 65, 115, 101, 179, 164, 155, 264, 246, 226, 395, 382, 362, 9,\n    66, 30, 59, 56, 102, 185, 173, 265, 142, 253, 232, 400, 388, 378, 445, 16,\n    111, 54, 52, 100, 184, 178, 160, 133, 257, 244, 228, 217, 385, 366, 715, 10,\n    98, 48, 91, 88, 165, 157, 148, 261, 248, 407, 397, 372, 380, 889, 884, 8,\n    85, 84, 81, 159, 156, 143, 260, 249, 427, 401, 392, 383, 727, 713, 708, 7,\n    154, 76, 73, 141, 131, 256, 245, 426, 406, 394, 384, 735, 359, 710, 352, 11,\n    139, 129, 67, 125, 247, 233, 229, 219, 393, 743, 737, 720, 885, 882, 439, 4,\n    243, 120, 118, 115, 227, 223, 396, 746, 742, 736, 721, 712, 706, 223, 436, 6,\n    202, 224, 222, 218, 216, 389, 386, 381, 364, 888, 443, 707, 440, 437, 1728, 4,\n    747, 211, 210, 208, 370, 379, 734, 723, 714, 1735, 883, 877, 876, 3459, 865, 2,\n    377, 369, 102, 187, 726, 722, 358, 711, 709, 866, 1734, 871, 3458, 870, 434, 0,\n    12, 10, 7, 11, 10, 17, 11, 9, 13, 12, 10, 7, 5, 3, 1, 3\n};\n\nstatic const uint16_t t24HB[] = {\n    15, 13, 46, 80, 146, 262, 248, 434, 426, 669, 653, 649, 621, 517, 1032, 88,\n    14, 12, 21, 38, 71, 130, 122, 216, 209, 198, 327, 345, 319, 297, 279, 42,\n    47, 22, 41, 74, 68, 128, 120, 221, 207, 194, 182, 340, 315, 295, 541, 18,\n    81, 39, 75, 70, 134, 125, 116, 220, 204, 190, 178, 325, 311, 293, 271, 16,\n    147, 72, 69, 135, 127, 118, 112, 210, 200, 188, 352, 323, 306, 285, 540, 14,\n    263, 66, 129, 126, 119, 114, 214, 202, 192, 180, 341, 317, 301, 281, 262, 12,\n    249, 123, 121, 117, 113, 215, 206, 195, 185, 347, 330, 308, 291, 272, 520, 10,\n    435, 115, 111, 109, 211, 203, 196, 187, 353, 332, 313, 298, 283, 531, 381, 17,\n    427, 212, 208, 205, 201, 193, 186, 177, 169, 320, 303, 286, 268, 514, 377, 16,\n    335, 199, 197, 191, 189, 181, 174, 333, 321, 305, 289, 275, 521, 379, 371, 11,\n    668, 184, 183, 179, 175, 344, 331, 314, 304, 290, 277, 530, 383, 373, 366, 10,\n    652, 346, 171, 168, 164, 318, 309, 299, 287, 276, 263, 513, 375, 368, 362, 6,\n    648, 322, 316, 312, 307, 302, 292, 284, 269, 261, 512, 376, 370, 364, 359, 4,\n    620, 300, 296, 294, 288, 282, 273, 266, 515, 380, 374, 369, 365, 361, 357, 2,\n    1033, 280, 278, 274, 267, 264, 259, 382, 378, 372, 367, 363, 360, 358, 356, 0,\n    43, 20, 19, 17, 15, 13, 11, 9, 7, 6, 4, 7, 5, 3, 1, 3\n};\n\nstatic const uint16_t t32HB[] = {\n    1 << 0, 5 << 1, 4 << 1, 5 << 2, 6 << 1, 5 << 2, 4 << 2, 4 << 3,\n    7 << 1, 3 << 2, 6 << 2, 0 << 3, 7 << 2, 2 << 3, 3 << 3, 1 << 4\n};\n\nstatic const uint16_t t33HB[] = {\n    15 << 0, 14 << 1, 13 << 1, 12 << 2, 11 << 1, 10 << 2, 9 << 2, 8 << 3,\n    7 << 1, 6 << 2, 5 << 2, 4 << 3, 3 << 2, 2 << 3, 1 << 3, 0 << 4\n};\n\n\nconst uint8_t t1l[] = {\n    1, 4,\n    3, 5\n};\n\nstatic const uint8_t t2l[] = {\n    1, 4, 7,\n    4, 5, 7,\n    6, 7, 8\n};\n\nstatic const uint8_t t3l[] = {\n    2, 3, 7,\n    4, 4, 7,\n    6, 7, 8\n};\n\nstatic const uint8_t t5l[] = {\n    1, 4, 7, 8,\n    4, 5, 8, 9,\n    7, 8, 9, 10,\n    8, 8, 9, 10\n};\n\nstatic const uint8_t t6l[] = {\n    3, 4, 6, 8,\n    4, 4, 6, 7,\n    5, 6, 7, 8,\n    7, 7, 8, 9\n};\n\nstatic const uint8_t t7l[] = {\n    1, 4, 7, 9, 9, 10,\n    4, 6, 8, 9, 9, 10,\n    7, 7, 9, 10, 10, 11,\n    8, 9, 10, 11, 11, 11,\n    8, 9, 10, 11, 11, 12,\n    9, 10, 11, 12, 12, 12\n};\n\nstatic const uint8_t t8l[] = {\n    2, 4, 7, 9, 9, 10,\n    4, 4, 6, 10, 10, 10,\n    7, 6, 8, 10, 10, 11,\n    9, 10, 10, 11, 11, 12,\n    9, 9, 10, 11, 12, 12,\n    10, 10, 11, 11, 13, 13\n};\n\nstatic const uint8_t t9l[] = {\n    3, 4, 6, 7, 9, 10,\n    4, 5, 6, 7, 8, 10,\n    5, 6, 7, 8, 9, 10,\n    7, 7, 8, 9, 9, 10,\n    8, 8, 9, 9, 10, 11,\n    9, 9, 10, 10, 11, 11\n};\n\nstatic const uint8_t t10l[] = {\n    1, 4, 7, 9, 10, 10, 10, 11,\n    4, 6, 8, 9, 10, 11, 10, 10,\n    7, 8, 9, 10, 11, 12, 11, 11,\n    8, 9, 10, 11, 12, 12, 11, 12,\n    9, 10, 11, 12, 12, 12, 12, 12,\n    10, 11, 12, 12, 13, 13, 12, 13,\n    9, 10, 11, 12, 12, 12, 13, 13,\n    10, 10, 11, 12, 12, 13, 13, 13\n};\n\nstatic const uint8_t t11l[] = {\n    2, 4, 6, 8, 9, 10, 9, 10,\n    4, 5, 6, 8, 10, 10, 9, 10,\n    6, 7, 8, 9, 10, 11, 10, 10,\n    8, 8, 9, 11, 10, 12, 10, 11,\n    9, 10, 10, 11, 11, 12, 11, 12,\n    9, 10, 11, 12, 12, 13, 12, 13,\n    9, 9, 9, 10, 11, 12, 12, 12,\n    9, 9, 10, 11, 12, 12, 12, 12\n};\n\nstatic const uint8_t t12l[] = {\n    4, 4, 6, 8, 9, 10, 10, 10,\n    4, 5, 6, 7, 9, 9, 10, 10,\n    6, 6, 7, 8, 9, 10, 9, 10,\n    7, 7, 8, 8, 9, 10, 10, 10,\n    8, 8, 9, 9, 10, 10, 10, 11,\n    9, 9, 10, 10, 10, 11, 10, 11,\n    9, 9, 9, 10, 10, 11, 11, 12,\n    10, 10, 10, 11, 11, 11, 11, 12\n};\n\nstatic const uint8_t t13l[] = {\n    1, 5, 7, 8, 9, 10, 10, 11, 10, 11, 12, 12, 13, 13, 14, 14,\n    4, 6, 8, 9, 10, 10, 11, 11, 11, 11, 12, 12, 13, 14, 14, 14,\n    7, 8, 9, 10, 11, 11, 12, 12, 11, 12, 12, 13, 13, 14, 15, 15,\n    8, 9, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 15, 15,\n    9, 9, 11, 11, 12, 12, 13, 13, 12, 13, 13, 14, 14, 15, 15, 16,\n    10, 10, 11, 12, 12, 12, 13, 13, 13, 13, 14, 13, 15, 15, 16, 16,\n    10, 11, 12, 12, 13, 13, 13, 13, 13, 14, 14, 14, 15, 15, 16, 16,\n    11, 11, 12, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 16, 18, 18,\n    10, 10, 11, 12, 12, 13, 13, 14, 14, 14, 14, 15, 15, 16, 17, 17,\n    11, 11, 12, 12, 13, 13, 13, 15, 14, 15, 15, 16, 16, 16, 18, 17,\n    11, 12, 12, 13, 13, 14, 14, 15, 14, 15, 16, 15, 16, 17, 18, 19,\n    12, 12, 12, 13, 14, 14, 14, 14, 15, 15, 15, 16, 17, 17, 17, 18,\n    12, 13, 13, 14, 14, 15, 14, 15, 16, 16, 17, 17, 17, 18, 18, 18,\n    13, 13, 14, 15, 15, 15, 16, 16, 16, 16, 16, 17, 18, 17, 18, 18,\n    14, 14, 14, 15, 15, 15, 17, 16, 16, 19, 17, 17, 17, 19, 18, 18,\n    13, 14, 15, 16, 16, 16, 17, 16, 17, 17, 18, 18, 21, 20, 21, 18\n};\n\nstatic const uint8_t t15l[] = {\n    3, 5, 6, 8, 8, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 14,\n    5, 5, 7, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 13,\n    6, 7, 7, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 13, 13, 13,\n    7, 8, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13,\n    8, 8, 9, 9, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13,\n    9, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 13, 13, 13, 14,\n    10, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 14, 14,\n    10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 14,\n    10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 14, 14, 14,\n    10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14,\n    11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 15, 14,\n    11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15,\n    12, 12, 11, 12, 12, 12, 13, 13, 13, 13, 13, 13, 14, 14, 15, 15,\n    12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15,\n    13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 14, 15,\n    13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 15, 15, 15, 15\n};\n\nstatic const uint8_t t16_5l[] = {\n    1, 5, 7, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 11,\n    4, 6, 8, 9, 10, 11, 11, 11, 12, 12, 12, 13, 14, 13, 14, 11,\n    7, 8, 9, 10, 11, 11, 12, 12, 13, 12, 13, 13, 13, 14, 14, 12,\n    9, 9, 10, 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 13,\n    10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 12,\n    10, 10, 11, 11, 12, 13, 13, 14, 13, 14, 14, 15, 15, 15, 16, 13,\n    11, 11, 11, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 16, 13,\n    11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 17, 17, 13,\n    11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 13,\n    12, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 15, 16, 15, 14,\n    12, 13, 12, 13, 14, 14, 14, 14, 15, 16, 16, 16, 17, 17, 16, 13,\n    13, 13, 13, 13, 14, 14, 15, 16, 16, 16, 16, 16, 16, 15, 16, 14,\n    13, 14, 14, 14, 14, 15, 15, 15, 15, 17, 16, 16, 16, 16, 18, 14,\n    15, 14, 14, 14, 15, 15, 16, 16, 16, 18, 17, 17, 17, 19, 17, 14,\n    14, 15, 13, 14, 16, 16, 15, 16, 16, 17, 18, 17, 19, 17, 16, 14,\n    11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 12\n};\n\nstatic const uint8_t t16l[] = {\n    1, 5, 7, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 14, 10,\n    4, 6, 8, 9, 10, 11, 11, 11, 12, 12, 12, 13, 14, 13, 14, 10,\n    7, 8, 9, 10, 11, 11, 12, 12, 13, 12, 13, 13, 13, 14, 14, 11,\n    9, 9, 10, 11, 11, 12, 12, 12, 13, 13, 14, 14, 14, 15, 15, 12,\n    10, 10, 11, 11, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 11,\n    10, 10, 11, 11, 12, 13, 13, 14, 13, 14, 14, 15, 15, 15, 16, 12,\n    11, 11, 11, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 16, 12,\n    11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 17, 17, 12,\n    11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 12,\n    12, 12, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 15, 16, 15, 13,\n    12, 13, 12, 13, 14, 14, 14, 14, 15, 16, 16, 16, 17, 17, 16, 12,\n    13, 13, 13, 13, 14, 14, 15, 16, 16, 16, 16, 16, 16, 15, 16, 13,\n    13, 14, 14, 14, 14, 15, 15, 15, 15, 17, 16, 16, 16, 16, 18, 13,\n    15, 14, 14, 14, 15, 15, 16, 16, 16, 18, 17, 17, 17, 19, 17, 13,\n    14, 15, 13, 14, 16, 16, 15, 16, 16, 17, 18, 17, 19, 17, 16, 13,\n    10, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 10\n};\n\nstatic const uint8_t t24l[] = {\n    4, 5, 7, 8, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 13, 10,\n    5, 6, 7, 8, 9, 10, 10, 11, 11, 11, 12, 12, 12, 12, 12, 10,\n    7, 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 9,\n    8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 9,\n    9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 12, 12, 12, 12, 13, 9,\n    10, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 9,\n    10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 9,\n    11, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 10,\n    11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 10,\n    11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 10,\n    12, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 10,\n    12, 12, 11, 11, 11, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 10,\n    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 10,\n    12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 10,\n    13, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 10,\n    9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 6\n};\n\nconst uint8_t t32l[] = {\n    1 + 0, 4 + 1, 4 + 1, 5 + 2, 4 + 1, 6 + 2, 5 + 2, 6 + 3,\n    4 + 1, 5 + 2, 5 + 2, 6 + 3, 5 + 2, 6 + 3, 6 + 3, 6 + 4\n};\n\nconst uint8_t t33l[] = {\n    4 + 0, 4 + 1, 4 + 1, 4 + 2, 4 + 1, 4 + 2, 4 + 2, 4 + 3,\n    4 + 1, 4 + 2, 4 + 2, 4 + 3, 4 + 2, 4 + 3, 4 + 3, 4 + 4\n};\n\n\nconst struct huffcodetab ht[HTN] = {\n    /* xlen, linmax, table, hlen */\n    {0, 0, NULL, NULL},\n    {2, 0, t1HB, t1l},\n    {3, 0, t2HB, t2l},\n    {3, 0, t3HB, t3l},\n    {0, 0, NULL, NULL}, /* Apparently not used */\n    {4, 0, t5HB, t5l},\n    {4, 0, t6HB, t6l},\n    {6, 0, t7HB, t7l},\n    {6, 0, t8HB, t8l},\n    {6, 0, t9HB, t9l},\n    {8, 0, t10HB, t10l},\n    {8, 0, t11HB, t11l},\n    {8, 0, t12HB, t12l},\n    {16, 0, t13HB, t13l},\n    {0, 0, NULL, t16_5l}, /* Apparently not used */\n    {16, 0, t15HB, t15l},\n\n    {1, 1, t16HB, t16l},\n    {2, 3, t16HB, t16l},\n    {3, 7, t16HB, t16l},\n    {4, 15, t16HB, t16l},\n    {6, 63, t16HB, t16l},\n    {8, 255, t16HB, t16l},\n    {10, 1023, t16HB, t16l},\n    {13, 8191, t16HB, t16l},\n\n    {4, 15, t24HB, t24l},\n    {5, 31, t24HB, t24l},\n    {6, 63, t24HB, t24l},\n    {7, 127, t24HB, t24l},\n    {8, 255, t24HB, t24l},\n    {9, 511, t24HB, t24l},\n    {11, 2047, t24HB, t24l},\n    {13, 8191, t24HB, t24l},\n\n    {0, 0, t32HB, t32l},\n    {0, 0, t33HB, t33l},\n};\n\n\n\n\n\n/*  for (i = 0; i < 16*16; i++) {\n *      largetbl[i] = ((ht[16].hlen[i]) << 16) + ht[24].hlen[i];\n *  }\n */\nconst uint32_t largetbl[16 * 16] = {\n    0x010004, 0x050005, 0x070007, 0x090008, 0x0a0009, 0x0a000a, 0x0b000a, 0x0b000b,\n    0x0c000b, 0x0c000c, 0x0c000c, 0x0d000c, 0x0d000c, 0x0d000c, 0x0e000d, 0x0a000a,\n    0x040005, 0x060006, 0x080007, 0x090008, 0x0a0009, 0x0b000a, 0x0b000a, 0x0b000b,\n    0x0c000b, 0x0c000b, 0x0c000c, 0x0d000c, 0x0e000c, 0x0d000c, 0x0e000c, 0x0a000a,\n    0x070007, 0x080007, 0x090008, 0x0a0009, 0x0b0009, 0x0b000a, 0x0c000a, 0x0c000b,\n    0x0d000b, 0x0c000b, 0x0d000b, 0x0d000c, 0x0d000c, 0x0e000c, 0x0e000d, 0x0b0009,\n    0x090008, 0x090008, 0x0a0009, 0x0b0009, 0x0b000a, 0x0c000a, 0x0c000a, 0x0c000b,\n    0x0d000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x0c0009,\n    0x0a0009, 0x0a0009, 0x0b0009, 0x0b000a, 0x0c000a, 0x0c000a, 0x0d000a, 0x0d000b,\n    0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000d, 0x0b0009,\n    0x0a000a, 0x0a0009, 0x0b000a, 0x0b000a, 0x0c000a, 0x0d000a, 0x0d000b, 0x0e000b,\n    0x0d000b, 0x0e000b, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x10000c, 0x0c0009,\n    0x0b000a, 0x0b000a, 0x0b000a, 0x0c000a, 0x0d000a, 0x0d000b, 0x0d000b, 0x0d000b,\n    0x0e000b, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x10000d, 0x0c0009,\n    0x0b000b, 0x0b000a, 0x0c000a, 0x0c000a, 0x0d000b, 0x0d000b, 0x0d000b, 0x0e000b,\n    0x0e000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x0f000c, 0x11000d, 0x11000d, 0x0c000a,\n    0x0b000b, 0x0c000b, 0x0c000b, 0x0d000b, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000b,\n    0x0f000b, 0x0f000c, 0x0f000c, 0x0f000c, 0x10000c, 0x10000d, 0x10000d, 0x0c000a,\n    0x0c000b, 0x0c000b, 0x0c000b, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000b, 0x0f000c,\n    0x0f000c, 0x0f000c, 0x0f000c, 0x10000c, 0x0f000d, 0x10000d, 0x0f000d, 0x0d000a,\n    0x0c000c, 0x0d000b, 0x0c000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0e000c, 0x0e000c,\n    0x0f000c, 0x10000c, 0x10000c, 0x10000d, 0x11000d, 0x11000d, 0x10000d, 0x0c000a,\n    0x0d000c, 0x0d000c, 0x0d000b, 0x0d000b, 0x0e000b, 0x0e000c, 0x0f000c, 0x10000c,\n    0x10000c, 0x10000c, 0x10000c, 0x10000d, 0x10000d, 0x0f000d, 0x10000d, 0x0d000a,\n    0x0d000c, 0x0e000c, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x0f000c,\n    0x0f000c, 0x11000c, 0x10000d, 0x10000d, 0x10000d, 0x10000d, 0x12000d, 0x0d000a,\n    0x0f000c, 0x0e000c, 0x0e000c, 0x0e000c, 0x0f000c, 0x0f000c, 0x10000c, 0x10000c,\n    0x10000d, 0x12000d, 0x11000d, 0x11000d, 0x11000d, 0x13000d, 0x11000d, 0x0d000a,\n    0x0e000d, 0x0f000c, 0x0d000c, 0x0e000c, 0x10000c, 0x10000c, 0x0f000c, 0x10000d,\n    0x10000d, 0x11000d, 0x12000d, 0x11000d, 0x13000d, 0x11000d, 0x10000d, 0x0d000a,\n    0x0a0009, 0x0a0009, 0x0a0009, 0x0b0009, 0x0b0009, 0x0c0009, 0x0c0009, 0x0c0009,\n    0x0d0009, 0x0d0009, 0x0d0009, 0x0d000a, 0x0d000a, 0x0d000a, 0x0d000a, 0x0a0006\n};\n\n/*  for (i = 0; i < 3*3; i++) {\n *      table23[i] = ((ht[2].hlen[i]) << 16) + ht[3].hlen[i];\n *  }\n */\nconst uint32_t table23[3 * 3] = {\n    0x010002, 0x040003, 0x070007,\n    0x040004, 0x050004, 0x070007,\n    0x060006, 0x070007, 0x080008\n};\n\n/*   for (i = 0; i < 4*4; i++) {\n *       table56[i] = ((ht[5].hlen[i]) << 16) + ht[6].hlen[i];\n *   }\n */\nconst uint32_t table56[4 * 4] = {\n    0x010003, 0x040004, 0x070006, 0x080008, 0x040004, 0x050004, 0x080006, 0x090007,\n    0x070005, 0x080006, 0x090007, 0x0a0008, 0x080007, 0x080007, 0x090008, 0x0a0009\n};\n\n\n\n/* \n * 0: MPEG-2 LSF\n * 1: MPEG-1\n * 2: MPEG-2.5 LSF FhG extention                  (1995-07-11 shn)\n */\n\ntypedef enum {\n    MPEG_2 = 0,\n    MPEG_1 = 1,\n    MPEG_25 = 2\n} MPEG_t;\n\nconst int bitrate_table[3][16] = {\n    {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, -1}, /* MPEG 2 */\n    {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, -1}, /* MPEG 1 */\n    {0, 8, 16, 24, 32, 40, 48, 56, 64, -1, -1, -1, -1, -1, -1, -1}, /* MPEG 2.5 */\n};\n\nconst int samplerate_table[3][4] = {\n    {22050, 24000, 16000, -1}, /* MPEG 2 */\n    {44100, 48000, 32000, -1}, /* MPEG 1 */\n    {11025, 12000, 8000, -1}, /* MPEG 2.5 */\n};\n\nint\nlame_get_bitrate(int mpeg_version, int table_index)\n{\n    if (0 <= mpeg_version && mpeg_version <= 2) {\n        if (0 <= table_index && table_index <= 15) {\n            return bitrate_table[mpeg_version][table_index];\n        }\n    }\n    return -1;\n}\n\nint\nlame_get_samplerate(int mpeg_version, int table_index)\n{\n    if (0 <= mpeg_version && mpeg_version <= 2) {\n        if (0 <= table_index && table_index <= 3) {\n            return samplerate_table[mpeg_version][table_index];\n        }\n    }\n    return -1;\n}\n\n\n/* This is the scfsi_band table from 2.4.2.7 of the IS */\nconst int scfsi_band[5] = { 0, 6, 11, 16, 21 };\n\n/* end of tables.c */\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/tables.h",
    "content": "/*\n *\tMPEG layer 3 tables include file\n *\n *\tCopyright (c) 1999 Albert L Faber\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\t See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n#ifndef LAME_TABLES_H\n#define LAME_TABLES_H\n\n#if 0\ntypedef struct {\n    unsigned char no;\n    unsigned char width;\n    unsigned char minval_2;\n    float   quiet_thr;\n    float   norm;\n    float   bark;\n} type1_t;\n\ntypedef struct {\n    unsigned char no;\n    unsigned char width;\n    float   quiet_thr;\n    float   norm;\n    float   SNR;\n    float   bark;\n} type2_t;\n\ntypedef struct {\n    unsigned int no:5;\n    unsigned int cbw:3;\n    unsigned int bu:6;\n    unsigned int bo:6;\n    unsigned int w1_576:10;\n    unsigned int w2_576:10;\n} type34_t;\n\ntypedef struct {\n    size_t  len1;\n    const type1_t *const tab1;\n    size_t  len2;\n    const type2_t *const tab2;\n    size_t  len3;\n    const type34_t *const tab3;\n    size_t  len4;\n    const type34_t *const tab4;\n} type5_t;\n\nextern const type5_t table5[6];\n\n#endif\n\n#define HTN\t34\n\nstruct huffcodetab {\n    const unsigned int xlen;          /* max. x-index+   */\n    const unsigned int linmax;        /* max number to be stored in linbits */\n    const uint16_t *table;      /* pointer to array[xlen][ylen]  */\n    const uint8_t *hlen;        /* pointer to array[xlen][ylen]  */\n};\n\nextern const struct huffcodetab ht[HTN];\n    /* global memory block   */\n    /* array of all huffcodtable headers */\n    /* 0..31 Huffman code table 0..31  */\n    /* 32,33 count1-tables   */\n\nextern const uint8_t t32l[];\nextern const uint8_t t33l[];\n\nextern const uint32_t largetbl[16 * 16];\nextern const uint32_t table23[3 * 3];\nextern const uint32_t table56[4 * 4];\n\nextern const int scfsi_band[5];\n\nextern const int bitrate_table    [3][16];\nextern const int samplerate_table [3][ 4];\n\n#endif /* LAME_TABLES_H */\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/takehiro.c",
    "content": "/*\n *\tMP3 huffman table selecting and bit counting\n *\n *\tCopyright (c) 1999-2005 Takehiro TOMINAGA\n *\tCopyright (c) 2002-2005 Gabriel Bouvigne\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\t See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n/* $Id: takehiro.c,v 1.79 2011/05/07 16:05:17 rbrito Exp $ */\n\n#ifdef HAVE_CONFIG_H\n# include <config.h>\n#endif\n\n\n#include \"lame.h\"\n#include \"machine.h\"\n#include \"encoder.h\"\n#include \"util.h\"\n#include \"quantize_pvt.h\"\n#include \"tables.h\"\n\n\nstatic const struct {\n    const int region0_count;\n    const int region1_count;\n} subdv_table[23] = {\n    {\n    0, 0},              /* 0 bands */\n    {\n    0, 0},              /* 1 bands */\n    {\n    0, 0},              /* 2 bands */\n    {\n    0, 0},              /* 3 bands */\n    {\n    0, 0},              /* 4 bands */\n    {\n    0, 1},              /* 5 bands */\n    {\n    1, 1},              /* 6 bands */\n    {\n    1, 1},              /* 7 bands */\n    {\n    1, 2},              /* 8 bands */\n    {\n    2, 2},              /* 9 bands */\n    {\n    2, 3},              /* 10 bands */\n    {\n    2, 3},              /* 11 bands */\n    {\n    3, 4},              /* 12 bands */\n    {\n    3, 4},              /* 13 bands */\n    {\n    3, 4},              /* 14 bands */\n    {\n    4, 5},              /* 15 bands */\n    {\n    4, 5},              /* 16 bands */\n    {\n    4, 6},              /* 17 bands */\n    {\n    5, 6},              /* 18 bands */\n    {\n    5, 6},              /* 19 bands */\n    {\n    5, 7},              /* 20 bands */\n    {\n    6, 7},              /* 21 bands */\n    {\n    6, 7},              /* 22 bands */\n};\n\n\n\n\n\n/*********************************************************************\n * nonlinear quantization of xr \n * More accurate formula than the ISO formula.  Takes into account\n * the fact that we are quantizing xr -> ix, but we want ix^4/3 to be \n * as close as possible to x^4/3.  (taking the nearest int would mean\n * ix is as close as possible to xr, which is different.)\n *\n * From Segher Boessenkool <segher@eastsite.nl>  11/1999\n *\n * 09/2000: ASM code removed in favor of IEEE754 hack by Takehiro\n * Tominaga. If you need the ASM code, check CVS circa Aug 2000.\n *\n * 01/2004: Optimizations by Gabriel Bouvigne\n *********************************************************************/\n\n\n\n\n\nstatic void\nquantize_lines_xrpow_01(unsigned int l, FLOAT istep, const FLOAT * xr, int *ix)\n{\n    const FLOAT compareval0 = (1.0f - 0.4054f) / istep;\n    unsigned int i;\n\n    assert(l > 0);\n    assert(l % 2 == 0);\n    for (i = 0; i < l; i += 2) {\n        FLOAT const xr_0 = xr[i+0];\n        FLOAT const xr_1 = xr[i+1];\n        int const ix_0 = (compareval0 > xr_0) ? 0 : 1;\n        int const ix_1 = (compareval0 > xr_1) ? 0 : 1;\n        ix[i+0] = ix_0;\n        ix[i+1] = ix_1;\n    }\n}\n\n\n\n#ifdef TAKEHIRO_IEEE754_HACK\n\ntypedef union {\n    float   f;\n    int     i;\n} fi_union;\n\n#define MAGIC_FLOAT (65536*(128))\n#define MAGIC_INT 0x4b000000\n\n\nstatic void\nquantize_lines_xrpow(unsigned int l, FLOAT istep, const FLOAT * xp, int *pi)\n{\n    fi_union *fi;\n    unsigned int remaining;\n\n    assert(l > 0);\n\n    fi = (fi_union *) pi;\n\n    l = l >> 1;\n    remaining = l % 2;\n    l = l >> 1;\n    while (l--) {\n        double  x0 = istep * xp[0];\n        double  x1 = istep * xp[1];\n        double  x2 = istep * xp[2];\n        double  x3 = istep * xp[3];\n\n        x0 += MAGIC_FLOAT;\n        fi[0].f = x0;\n        x1 += MAGIC_FLOAT;\n        fi[1].f = x1;\n        x2 += MAGIC_FLOAT;\n        fi[2].f = x2;\n        x3 += MAGIC_FLOAT;\n        fi[3].f = x3;\n\n        fi[0].f = x0 + adj43asm[fi[0].i - MAGIC_INT];\n        fi[1].f = x1 + adj43asm[fi[1].i - MAGIC_INT];\n        fi[2].f = x2 + adj43asm[fi[2].i - MAGIC_INT];\n        fi[3].f = x3 + adj43asm[fi[3].i - MAGIC_INT];\n\n        fi[0].i -= MAGIC_INT;\n        fi[1].i -= MAGIC_INT;\n        fi[2].i -= MAGIC_INT;\n        fi[3].i -= MAGIC_INT;\n        fi += 4;\n        xp += 4;\n    };\n    if (remaining) {\n        double  x0 = istep * xp[0];\n        double  x1 = istep * xp[1];\n\n        x0 += MAGIC_FLOAT;\n        fi[0].f = x0;\n        x1 += MAGIC_FLOAT;\n        fi[1].f = x1;\n\n        fi[0].f = x0 + adj43asm[fi[0].i - MAGIC_INT];\n        fi[1].f = x1 + adj43asm[fi[1].i - MAGIC_INT];\n\n        fi[0].i -= MAGIC_INT;\n        fi[1].i -= MAGIC_INT;\n    }\n\n}\n\n\n#else\n\n/*********************************************************************\n * XRPOW_FTOI is a macro to convert floats to ints.  \n * if XRPOW_FTOI(x) = nearest_int(x), then QUANTFAC(x)=adj43asm[x]\n *                                         ROUNDFAC= -0.0946\n *\n * if XRPOW_FTOI(x) = floor(x), then QUANTFAC(x)=asj43[x]   \n *                                   ROUNDFAC=0.4054\n *\n * Note: using floor() or (int) is extremely slow. On machines where\n * the TAKEHIRO_IEEE754_HACK code above does not work, it is worthwile\n * to write some ASM for XRPOW_FTOI().  \n *********************************************************************/\n#define XRPOW_FTOI(src,dest) ((dest) = (int)(src))\n#define QUANTFAC(rx)  adj43[rx]\n#define ROUNDFAC 0.4054\n\n\nstatic void\nquantize_lines_xrpow(unsigned int l, FLOAT istep, const FLOAT * xr, int *ix)\n{\n    unsigned int remaining;\n\n    assert(l > 0);\n\n    l = l >> 1;\n    remaining = l % 2;\n    l = l >> 1;\n    while (l--) {\n        FLOAT   x0, x1, x2, x3;\n        int     rx0, rx1, rx2, rx3;\n\n        x0 = *xr++ * istep;\n        x1 = *xr++ * istep;\n        XRPOW_FTOI(x0, rx0);\n        x2 = *xr++ * istep;\n        XRPOW_FTOI(x1, rx1);\n        x3 = *xr++ * istep;\n        XRPOW_FTOI(x2, rx2);\n        x0 += QUANTFAC(rx0);\n        XRPOW_FTOI(x3, rx3);\n        x1 += QUANTFAC(rx1);\n        XRPOW_FTOI(x0, *ix++);\n        x2 += QUANTFAC(rx2);\n        XRPOW_FTOI(x1, *ix++);\n        x3 += QUANTFAC(rx3);\n        XRPOW_FTOI(x2, *ix++);\n        XRPOW_FTOI(x3, *ix++);\n    };\n    if (remaining) {\n        FLOAT   x0, x1;\n        int     rx0, rx1;\n\n        x0 = *xr++ * istep;\n        x1 = *xr++ * istep;\n        XRPOW_FTOI(x0, rx0);\n        XRPOW_FTOI(x1, rx1);\n        x0 += QUANTFAC(rx0);\n        x1 += QUANTFAC(rx1);\n        XRPOW_FTOI(x0, *ix++);\n        XRPOW_FTOI(x1, *ix++);\n    }\n\n}\n\n\n\n#endif\n\n\n\n/*********************************************************************\n * Quantization function\n * This function will select which lines to quantize and call the\n * proper quantization function\n *********************************************************************/\n\nstatic void\nquantize_xrpow(const FLOAT * xp, int *pi, FLOAT istep, gr_info const *const cod_info,\n               calc_noise_data const *prev_noise)\n{\n    /* quantize on xr^(3/4) instead of xr */\n    int     sfb;\n    int     sfbmax;\n    int     j = 0;\n    int     prev_data_use;\n    int    *iData;\n    int     accumulate = 0;\n    int     accumulate01 = 0;\n    int    *acc_iData;\n    const FLOAT *acc_xp;\n\n    iData = pi;\n    acc_xp = xp;\n    acc_iData = iData;\n\n\n    /* Reusing previously computed data does not seems to work if global gain\n       is changed. Finding why it behaves this way would allow to use a cache of \n       previously computed values (let's 10 cached values per sfb) that would \n       probably provide a noticeable speedup */\n    prev_data_use = (prev_noise && (cod_info->global_gain == prev_noise->global_gain));\n\n    if (cod_info->block_type == SHORT_TYPE)\n        sfbmax = 38;\n    else\n        sfbmax = 21;\n\n    for (sfb = 0; sfb <= sfbmax; sfb++) {\n        int     step = -1;\n\n        if (prev_data_use || cod_info->block_type == NORM_TYPE) {\n            step =\n                cod_info->global_gain\n                - ((cod_info->scalefac[sfb] + (cod_info->preflag ? pretab[sfb] : 0))\n                   << (cod_info->scalefac_scale + 1))\n                - cod_info->subblock_gain[cod_info->window[sfb]] * 8;\n        }\n        assert(cod_info->width[sfb] >= 0);\n        if (prev_data_use && (prev_noise->step[sfb] == step)) {\n            /* do not recompute this part,\n               but compute accumulated lines */\n            if (accumulate) {\n                quantize_lines_xrpow(accumulate, istep, acc_xp, acc_iData);\n                accumulate = 0;\n            }\n            if (accumulate01) {\n                quantize_lines_xrpow_01(accumulate01, istep, acc_xp, acc_iData);\n                accumulate01 = 0;\n            }\n        }\n        else {          /*should compute this part */\n            int     l;\n            l = cod_info->width[sfb];\n\n            if ((j + cod_info->width[sfb]) > cod_info->max_nonzero_coeff) {\n                /*do not compute upper zero part */\n                int     usefullsize;\n                usefullsize = cod_info->max_nonzero_coeff - j + 1;\n                memset(&pi[cod_info->max_nonzero_coeff], 0,\n                       sizeof(int) * (576 - cod_info->max_nonzero_coeff));\n                l = usefullsize;\n\n                if (l < 0) {\n                    l = 0;\n                }\n\n                /* no need to compute higher sfb values */\n                sfb = sfbmax + 1;\n            }\n\n            /*accumulate lines to quantize */\n            if (!accumulate && !accumulate01) {\n                acc_iData = iData;\n                acc_xp = xp;\n            }\n            if (prev_noise &&\n                prev_noise->sfb_count1 > 0 &&\n                sfb >= prev_noise->sfb_count1 &&\n                prev_noise->step[sfb] > 0 && step >= prev_noise->step[sfb]) {\n\n                if (accumulate) {\n                    quantize_lines_xrpow(accumulate, istep, acc_xp, acc_iData);\n                    accumulate = 0;\n                    acc_iData = iData;\n                    acc_xp = xp;\n                }\n                accumulate01 += l;\n            }\n            else {\n                if (accumulate01) {\n                    quantize_lines_xrpow_01(accumulate01, istep, acc_xp, acc_iData);\n                    accumulate01 = 0;\n                    acc_iData = iData;\n                    acc_xp = xp;\n                }\n                accumulate += l;\n            }\n\n            if (l <= 0) {\n                /*  rh: 20040215\n                 *  may happen due to \"prev_data_use\" optimization \n                 */\n                if (accumulate01) {\n                    quantize_lines_xrpow_01(accumulate01, istep, acc_xp, acc_iData);\n                    accumulate01 = 0;\n                }\n                if (accumulate) {\n                    quantize_lines_xrpow(accumulate, istep, acc_xp, acc_iData);\n                    accumulate = 0;\n                }\n\n                break;  /* ends for-loop */\n            }\n        }\n        if (sfb <= sfbmax) {\n            iData += cod_info->width[sfb];\n            xp += cod_info->width[sfb];\n            j += cod_info->width[sfb];\n        }\n    }\n    if (accumulate) {   /*last data part */\n        quantize_lines_xrpow(accumulate, istep, acc_xp, acc_iData);\n        accumulate = 0;\n    }\n    if (accumulate01) { /*last data part */\n        quantize_lines_xrpow_01(accumulate01, istep, acc_xp, acc_iData);\n        accumulate01 = 0;\n    }\n\n}\n\n\n\n\n/*************************************************************************/\n/*\t      ix_max\t\t\t\t\t\t\t */\n/*************************************************************************/\n\nstatic int\nix_max(const int *ix, const int *end)\n{\n    int     max1 = 0, max2 = 0;\n\n    do {\n        int const x1 = *ix++;\n        int const x2 = *ix++;\n        if (max1 < x1)\n            max1 = x1;\n\n        if (max2 < x2)\n            max2 = x2;\n    } while (ix < end);\n    if (max1 < max2)\n        max1 = max2;\n    return max1;\n}\n\n\n\n\n\n\n\n\nstatic int\ncount_bit_ESC(const int *ix, const int *const end, int t1, const int t2, unsigned int *const s)\n{\n    /* ESC-table is used */\n    unsigned int const linbits = ht[t1].xlen * 65536u + ht[t2].xlen;\n    unsigned int sum = 0, sum2;\n\n    do {\n        unsigned int x = *ix++;\n        unsigned int y = *ix++;\n\n        if (x >= 15u) {\n            x = 15u;\n            sum += linbits;\n        }\n        if (y >= 15u) {\n            y = 15u;\n            sum += linbits;\n        }\n        x <<= 4u;\n        x += y;\n        sum += largetbl[x];\n    } while (ix < end);\n\n    sum2 = sum & 0xffffu;\n    sum >>= 16u;\n\n    if (sum > sum2) {\n        sum = sum2;\n        t1 = t2;\n    }\n\n    *s += sum;\n    return t1;\n}\n\n\nstatic int\ncount_bit_noESC(const int *ix, const int *end, int mx, unsigned int *s)\n{\n    /* No ESC-words */\n    unsigned int sum1 = 0;\n    const uint8_t *const hlen1 = ht[1].hlen;\n    (void) mx;\n\n    do {\n        unsigned int const x0 = *ix++;\n        unsigned int const x1 = *ix++;\n        sum1 += hlen1[ x0+x0 + x1 ];\n    } while (ix < end);\n\n    *s += sum1;\n    return 1;\n}\n\n\nstatic const int huf_tbl_noESC[] = {\n    1, 2, 5, 7, 7, 10, 10, 13, 13, 13, 13, 13, 13, 13, 13\n};\n\n\nstatic int\ncount_bit_noESC_from2(const int *ix, const int *end, int max, unsigned int *s)\n{\n    int t1 = huf_tbl_noESC[max - 1];\n    /* No ESC-words */\n    const unsigned int xlen = ht[t1].xlen;\n    uint32_t const* table = (t1 == 2) ? &table23[0] : &table56[0];\n    unsigned int sum = 0, sum2;\n\n    do {\n        unsigned int const x0 = *ix++;\n        unsigned int const x1 = *ix++;\n        sum += table[ x0 * xlen + x1 ];\n    } while (ix < end);\n\n    sum2 = sum & 0xffffu;\n    sum >>= 16u;\n\n    if (sum > sum2) {\n        sum = sum2;\n        t1++;\n    }\n\n    *s += sum;\n    return t1;\n}\n\n\ninline static int\ncount_bit_noESC_from3(const int *ix, const int *end, int max, unsigned int * s)\n{\n    int t1 = huf_tbl_noESC[max - 1];\n    /* No ESC-words */\n    unsigned int sum1 = 0;\n    unsigned int sum2 = 0;\n    unsigned int sum3 = 0;\n    const unsigned int xlen = ht[t1].xlen;\n    const uint8_t *const hlen1 = ht[t1].hlen;\n    const uint8_t *const hlen2 = ht[t1 + 1].hlen;\n    const uint8_t *const hlen3 = ht[t1 + 2].hlen;\n    int     t;\n\n    do {\n        unsigned int x0 = *ix++;\n        unsigned int x1 = *ix++;\n        unsigned int x = x0 * xlen + x1;\n        sum1 += hlen1[x];\n        sum2 += hlen2[x];\n        sum3 += hlen3[x];\n    } while (ix < end);\n\n    t = t1;\n    if (sum1 > sum2) {\n        sum1 = sum2;\n        t++;\n    }\n    if (sum1 > sum3) {\n        sum1 = sum3;\n        t = t1 + 2;\n    }\n    *s += sum1;\n\n    return t;  \n}\n\n\n/*************************************************************************/\n/*\t      choose table\t\t\t\t\t\t */\n/*************************************************************************/\n\n/*\n  Choose the Huffman table that will encode ix[begin..end] with\n  the fewest bits.\n\n  Note: This code contains knowledge about the sizes and characteristics\n  of the Huffman tables as defined in the IS (Table B.7), and will not work\n  with any arbitrary tables.\n*/\nstatic int count_bit_null(const int* ix, const int* end, int max, unsigned int* s)\n{\n    (void) ix;\n    (void) end;\n    (void) max;\n    (void) s;\n    return 0;\n}\n\ntypedef int (*count_fnc)(const int* ix, const int* end, int max, unsigned int* s);\n  \nstatic count_fnc count_fncs[] = \n{ &count_bit_null\n, &count_bit_noESC\n, &count_bit_noESC_from2\n, &count_bit_noESC_from2\n, &count_bit_noESC_from3\n, &count_bit_noESC_from3\n, &count_bit_noESC_from3\n, &count_bit_noESC_from3\n, &count_bit_noESC_from3\n, &count_bit_noESC_from3\n, &count_bit_noESC_from3\n, &count_bit_noESC_from3\n, &count_bit_noESC_from3\n, &count_bit_noESC_from3\n, &count_bit_noESC_from3\n, &count_bit_noESC_from3\n};\n\nstatic int\nchoose_table_nonMMX(const int *ix, const int *const end, int *const _s)\n{\n    unsigned int* s = (unsigned int*)_s;\n    unsigned int  max;\n    int     choice, choice2;\n    max = ix_max(ix, end);\n\n    if (max <= 15) {\n      return count_fncs[max](ix, end, max, s);\n    }\n    /* try tables with linbits */\n    if (max > IXMAX_VAL) {\n        *s = LARGE_BITS;\n        return -1;\n    }\n    max -= 15u;\n    for (choice2 = 24; choice2 < 32; choice2++) {\n        if (ht[choice2].linmax >= max) {\n            break;\n        }\n    }\n\n    for (choice = choice2 - 8; choice < 24; choice++) {\n        if (ht[choice].linmax >= max) {\n            break;\n        }\n    }\n    return count_bit_ESC(ix, end, choice, choice2, s);\n}\n\n\n\n/*************************************************************************/\n/*\t      count_bit\t\t\t\t\t\t\t */\n/*************************************************************************/\nint\nnoquant_count_bits(lame_internal_flags const *const gfc,\n                   gr_info * const gi, calc_noise_data * prev_noise)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    int     bits = 0;\n    int     i, a1, a2;\n    int const *const ix = gi->l3_enc;\n\n    i = Min(576, ((gi->max_nonzero_coeff + 2) >> 1) << 1);\n\n    if (prev_noise)\n        prev_noise->sfb_count1 = 0;\n\n    /* Determine count1 region */\n    for (; i > 1; i -= 2)\n        if (ix[i - 1] | ix[i - 2])\n            break;\n    gi->count1 = i;\n\n    /* Determines the number of bits to encode the quadruples. */\n    a1 = a2 = 0;\n    for (; i > 3; i -= 4) {\n        int x4 = ix[i-4];\n        int x3 = ix[i-3];\n        int x2 = ix[i-2];\n        int x1 = ix[i-1];\n        int     p;\n        /* hack to check if all values <= 1 */\n        if ((unsigned int) (x4 | x3 | x2 | x1) > 1)\n            break;\n\n        p = ((x4 * 2 + x3) * 2 + x2) * 2 + x1;\n        a1 += t32l[p];\n        a2 += t33l[p];\n    }\n\n    bits = a1;\n    gi->count1table_select = 0;\n    if (a1 > a2) {\n        bits = a2;\n        gi->count1table_select = 1;\n    }\n\n    gi->count1bits = bits;\n    gi->big_values = i;\n    if (i == 0)\n        return bits;\n\n    if (gi->block_type == SHORT_TYPE) {\n        a1 = 3 * gfc->scalefac_band.s[3];\n        if (a1 > gi->big_values)\n            a1 = gi->big_values;\n        a2 = gi->big_values;\n\n    }\n    else if (gi->block_type == NORM_TYPE) {\n        assert(i <= 576); /* bv_scf has 576 entries (0..575) */\n        a1 = gi->region0_count = gfc->sv_qnt.bv_scf[i - 2];\n        a2 = gi->region1_count = gfc->sv_qnt.bv_scf[i - 1];\n\n        assert(a1 + a2 + 2 < SBPSY_l);\n        a2 = gfc->scalefac_band.l[a1 + a2 + 2];\n        a1 = gfc->scalefac_band.l[a1 + 1];\n        if (a2 < i)\n            gi->table_select[2] = gfc->choose_table(ix + a2, ix + i, &bits);\n\n    }\n    else {\n        gi->region0_count = 7;\n        /*gi->region1_count = SBPSY_l - 7 - 1; */\n        gi->region1_count = SBMAX_l - 1 - 7 - 1;\n        a1 = gfc->scalefac_band.l[7 + 1];\n        a2 = i;\n        if (a1 > a2) {\n            a1 = a2;\n        }\n    }\n\n\n    /* have to allow for the case when bigvalues < region0 < region1 */\n    /* (and region0, region1 are ignored) */\n    a1 = Min(a1, i);\n    a2 = Min(a2, i);\n\n    assert(a1 >= 0);\n    assert(a2 >= 0);\n\n    /* Count the number of bits necessary to code the bigvalues region. */\n    if (0 < a1)\n        gi->table_select[0] = gfc->choose_table(ix, ix + a1, &bits);\n    if (a1 < a2)\n        gi->table_select[1] = gfc->choose_table(ix + a1, ix + a2, &bits);\n    if (cfg->use_best_huffman == 2) {\n        gi->part2_3_length = bits;\n        best_huffman_divide(gfc, gi);\n        bits = gi->part2_3_length;\n    }\n\n\n    if (prev_noise) {\n        if (gi->block_type == NORM_TYPE) {\n            int     sfb = 0;\n            while (gfc->scalefac_band.l[sfb] < gi->big_values) {\n                sfb++;\n            }\n            prev_noise->sfb_count1 = sfb;\n        }\n    }\n\n    return bits;\n}\n\nint\ncount_bits(lame_internal_flags const *const gfc,\n           const FLOAT * const xr, gr_info * const gi, calc_noise_data * prev_noise)\n{\n    int    *const ix = gi->l3_enc;\n\n    /* since quantize_xrpow uses table lookup, we need to check this first: */\n    FLOAT const w = (IXMAX_VAL) / IPOW20(gi->global_gain);\n\n    if (gi->xrpow_max > w)\n        return LARGE_BITS;\n\n    quantize_xrpow(xr, ix, IPOW20(gi->global_gain), gi, prev_noise);\n\n    if (gfc->sv_qnt.substep_shaping & 2) {\n        int     sfb, j = 0;\n        /* 0.634521682242439 = 0.5946*2**(.5*0.1875) */\n        int const gain = gi->global_gain + gi->scalefac_scale;\n        const FLOAT roundfac = 0.634521682242439 / IPOW20(gain);\n        for (sfb = 0; sfb < gi->sfbmax; sfb++) {\n            int const width = gi->width[sfb];\n            assert(width >= 0);\n            if (!gfc->sv_qnt.pseudohalf[sfb]) {\n                j += width;\n            }\n            else {\n                int     k;\n                for (k = j, j += width; k < j; ++k) {\n                    ix[k] = (xr[k] >= roundfac) ? ix[k] : 0;\n                }\n            }\n        }\n    }\n    return noquant_count_bits(gfc, gi, prev_noise);\n}\n\n/***********************************************************************\n  re-calculate the best scalefac_compress using scfsi\n  the saved bits are kept in the bit reservoir.\n **********************************************************************/\n\n\ninline static void\nrecalc_divide_init(const lame_internal_flags * const gfc,\n                   gr_info const *cod_info,\n                   int const *const ix, int r01_bits[], int r01_div[], int r0_tbl[], int r1_tbl[])\n{\n    int     r0, r1, bigv, r0t, r1t, bits;\n\n    bigv = cod_info->big_values;\n\n    for (r0 = 0; r0 <= 7 + 15; r0++) {\n        r01_bits[r0] = LARGE_BITS;\n    }\n\n    for (r0 = 0; r0 < 16; r0++) {\n        int const a1 = gfc->scalefac_band.l[r0 + 1];\n        int     r0bits;\n        if (a1 >= bigv)\n            break;\n        r0bits = 0;\n        r0t = gfc->choose_table(ix, ix + a1, &r0bits);\n\n        for (r1 = 0; r1 < 8; r1++) {\n            int const a2 = gfc->scalefac_band.l[r0 + r1 + 2];\n            if (a2 >= bigv)\n                break;\n\n            bits = r0bits;\n            r1t = gfc->choose_table(ix + a1, ix + a2, &bits);\n            if (r01_bits[r0 + r1] > bits) {\n                r01_bits[r0 + r1] = bits;\n                r01_div[r0 + r1] = r0;\n                r0_tbl[r0 + r1] = r0t;\n                r1_tbl[r0 + r1] = r1t;\n            }\n        }\n    }\n}\n\ninline static void\nrecalc_divide_sub(const lame_internal_flags * const gfc,\n                  const gr_info * cod_info2,\n                  gr_info * const gi,\n                  const int *const ix,\n                  const int r01_bits[], const int r01_div[], const int r0_tbl[], const int r1_tbl[])\n{\n    int     bits, r2, a2, bigv, r2t;\n\n    bigv = cod_info2->big_values;\n\n    for (r2 = 2; r2 < SBMAX_l + 1; r2++) {\n        a2 = gfc->scalefac_band.l[r2];\n        if (a2 >= bigv)\n            break;\n\n        bits = r01_bits[r2 - 2] + cod_info2->count1bits;\n        if (gi->part2_3_length <= bits)\n            break;\n\n        r2t = gfc->choose_table(ix + a2, ix + bigv, &bits);\n        if (gi->part2_3_length <= bits)\n            continue;\n\n        memcpy(gi, cod_info2, sizeof(gr_info));\n        gi->part2_3_length = bits;\n        gi->region0_count = r01_div[r2 - 2];\n        gi->region1_count = r2 - 2 - r01_div[r2 - 2];\n        gi->table_select[0] = r0_tbl[r2 - 2];\n        gi->table_select[1] = r1_tbl[r2 - 2];\n        gi->table_select[2] = r2t;\n    }\n}\n\n\n\n\nvoid\nbest_huffman_divide(const lame_internal_flags * const gfc, gr_info * const gi)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    int     i, a1, a2;\n    gr_info cod_info2;\n    int const *const ix = gi->l3_enc;\n\n    int     r01_bits[7 + 15 + 1];\n    int     r01_div[7 + 15 + 1];\n    int     r0_tbl[7 + 15 + 1];\n    int     r1_tbl[7 + 15 + 1];\n\n\n    /* SHORT BLOCK stuff fails for MPEG2 */\n    if (gi->block_type == SHORT_TYPE && cfg->mode_gr == 1)\n        return;\n\n\n    memcpy(&cod_info2, gi, sizeof(gr_info));\n    if (gi->block_type == NORM_TYPE) {\n        recalc_divide_init(gfc, gi, ix, r01_bits, r01_div, r0_tbl, r1_tbl);\n        recalc_divide_sub(gfc, &cod_info2, gi, ix, r01_bits, r01_div, r0_tbl, r1_tbl);\n    }\n\n    i = cod_info2.big_values;\n    if (i == 0 || (unsigned int) (ix[i - 2] | ix[i - 1]) > 1)\n        return;\n\n    i = gi->count1 + 2;\n    if (i > 576)\n        return;\n\n    /* Determines the number of bits to encode the quadruples. */\n    memcpy(&cod_info2, gi, sizeof(gr_info));\n    cod_info2.count1 = i;\n    a1 = a2 = 0;\n\n    assert(i <= 576);\n\n    for (; i > cod_info2.big_values; i -= 4) {\n        int const p = ((ix[i - 4] * 2 + ix[i - 3]) * 2 + ix[i - 2]) * 2 + ix[i - 1];\n        a1 += t32l[p];\n        a2 += t33l[p];\n    }\n    cod_info2.big_values = i;\n\n    cod_info2.count1table_select = 0;\n    if (a1 > a2) {\n        a1 = a2;\n        cod_info2.count1table_select = 1;\n    }\n\n    cod_info2.count1bits = a1;\n\n    if (cod_info2.block_type == NORM_TYPE)\n        recalc_divide_sub(gfc, &cod_info2, gi, ix, r01_bits, r01_div, r0_tbl, r1_tbl);\n    else {\n        /* Count the number of bits necessary to code the bigvalues region. */\n        cod_info2.part2_3_length = a1;\n        a1 = gfc->scalefac_band.l[7 + 1];\n        if (a1 > i) {\n            a1 = i;\n        }\n        if (a1 > 0)\n            cod_info2.table_select[0] =\n                gfc->choose_table(ix, ix + a1, (int *) &cod_info2.part2_3_length);\n        if (i > a1)\n            cod_info2.table_select[1] =\n                gfc->choose_table(ix + a1, ix + i, (int *) &cod_info2.part2_3_length);\n        if (gi->part2_3_length > cod_info2.part2_3_length)\n            memcpy(gi, &cod_info2, sizeof(gr_info));\n    }\n}\n\nstatic const int slen1_n[16] = { 1, 1, 1, 1, 8, 2, 2, 2, 4, 4, 4, 8, 8, 8, 16, 16 };\nstatic const int slen2_n[16] = { 1, 2, 4, 8, 1, 2, 4, 8, 2, 4, 8, 2, 4, 8, 4, 8 };\nconst int slen1_tab[16] = { 0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 };\nconst int slen2_tab[16] = { 0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3 };\n\nstatic void\nscfsi_calc(int ch, III_side_info_t * l3_side)\n{\n    unsigned int i;\n    int     s1, s2, c1, c2;\n    int     sfb;\n    gr_info *const gi = &l3_side->tt[1][ch];\n    gr_info const *const g0 = &l3_side->tt[0][ch];\n\n    for (i = 0; i < (sizeof(scfsi_band) / sizeof(int)) - 1; i++) {\n        for (sfb = scfsi_band[i]; sfb < scfsi_band[i + 1]; sfb++) {\n            if (g0->scalefac[sfb] != gi->scalefac[sfb]\n                && gi->scalefac[sfb] >= 0)\n                break;\n        }\n        if (sfb == scfsi_band[i + 1]) {\n            for (sfb = scfsi_band[i]; sfb < scfsi_band[i + 1]; sfb++) {\n                gi->scalefac[sfb] = -1;\n            }\n            l3_side->scfsi[ch][i] = 1;\n        }\n    }\n\n    s1 = c1 = 0;\n    for (sfb = 0; sfb < 11; sfb++) {\n        if (gi->scalefac[sfb] == -1)\n            continue;\n        c1++;\n        if (s1 < gi->scalefac[sfb])\n            s1 = gi->scalefac[sfb];\n    }\n\n    s2 = c2 = 0;\n    for (; sfb < SBPSY_l; sfb++) {\n        if (gi->scalefac[sfb] == -1)\n            continue;\n        c2++;\n        if (s2 < gi->scalefac[sfb])\n            s2 = gi->scalefac[sfb];\n    }\n\n    for (i = 0; i < 16; i++) {\n        if (s1 < slen1_n[i] && s2 < slen2_n[i]) {\n            int const c = slen1_tab[i] * c1 + slen2_tab[i] * c2;\n            if (gi->part2_length > c) {\n                gi->part2_length = c;\n                gi->scalefac_compress = (int)i;\n            }\n        }\n    }\n}\n\n/*\nFind the optimal way to store the scalefactors.\nOnly call this routine after final scalefactors have been\nchosen and the channel/granule will not be re-encoded.\n */\nvoid\nbest_scalefac_store(const lame_internal_flags * gfc,\n                    const int gr, const int ch, III_side_info_t * const l3_side)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    /* use scalefac_scale if we can */\n    gr_info *const gi = &l3_side->tt[gr][ch];\n    int     sfb, i, j, l;\n    int     recalc = 0;\n\n    /* remove scalefacs from bands with ix=0.  This idea comes\n     * from the AAC ISO docs.  added mt 3/00 */\n    /* check if l3_enc=0 */\n    j = 0;\n    for (sfb = 0; sfb < gi->sfbmax; sfb++) {\n        int const width = gi->width[sfb];\n        assert(width >= 0);\n        for (l = j, j += width; l < j; ++l) {\n            if (gi->l3_enc[l] != 0)\n                break;\n        }\n        if (l == j)\n            gi->scalefac[sfb] = recalc = -2; /* anything goes. */\n        /*  only best_scalefac_store and calc_scfsi \n         *  know--and only they should know--about the magic number -2. \n         */\n    }\n\n    if (!gi->scalefac_scale && !gi->preflag) {\n        int     s = 0;\n        for (sfb = 0; sfb < gi->sfbmax; sfb++)\n            if (gi->scalefac[sfb] > 0)\n                s |= gi->scalefac[sfb];\n\n        if (!(s & 1) && s != 0) {\n            for (sfb = 0; sfb < gi->sfbmax; sfb++)\n                if (gi->scalefac[sfb] > 0)\n                    gi->scalefac[sfb] >>= 1;\n\n            gi->scalefac_scale = recalc = 1;\n        }\n    }\n\n    if (!gi->preflag && gi->block_type != SHORT_TYPE && cfg->mode_gr == 2) {\n        for (sfb = 11; sfb < SBPSY_l; sfb++)\n            if (gi->scalefac[sfb] < pretab[sfb] && gi->scalefac[sfb] != -2)\n                break;\n        if (sfb == SBPSY_l) {\n            for (sfb = 11; sfb < SBPSY_l; sfb++)\n                if (gi->scalefac[sfb] > 0)\n                    gi->scalefac[sfb] -= pretab[sfb];\n\n            gi->preflag = recalc = 1;\n        }\n    }\n\n    for (i = 0; i < 4; i++)\n        l3_side->scfsi[ch][i] = 0;\n\n    if (cfg->mode_gr == 2 && gr == 1\n        && l3_side->tt[0][ch].block_type != SHORT_TYPE\n        && l3_side->tt[1][ch].block_type != SHORT_TYPE) {\n        scfsi_calc(ch, l3_side);\n        recalc = 0;\n    }\n    for (sfb = 0; sfb < gi->sfbmax; sfb++) {\n        if (gi->scalefac[sfb] == -2) {\n            gi->scalefac[sfb] = 0; /* if anything goes, then 0 is a good choice */\n        }\n    }\n    if (recalc) {\n        (void) scale_bitcount(gfc, gi);\n    }\n}\n\n\n#ifndef NDEBUG\nstatic int\nall_scalefactors_not_negative(int const *scalefac, int n)\n{\n    int     i;\n    for (i = 0; i < n; ++i) {\n        if (scalefac[i] < 0)\n            return 0;\n    }\n    return 1;\n}\n#endif\n\n\n/* number of bits used to encode scalefacs */\n\n/* 18*slen1_tab[i] + 18*slen2_tab[i] */\nstatic const int scale_short[16] = {\n    0, 18, 36, 54, 54, 36, 54, 72, 54, 72, 90, 72, 90, 108, 108, 126\n};\n\n/* 17*slen1_tab[i] + 18*slen2_tab[i] */\nstatic const int scale_mixed[16] = {\n    0, 18, 36, 54, 51, 35, 53, 71, 52, 70, 88, 69, 87, 105, 104, 122\n};\n\n/* 11*slen1_tab[i] + 10*slen2_tab[i] */\nstatic const int scale_long[16] = {\n    0, 10, 20, 30, 33, 21, 31, 41, 32, 42, 52, 43, 53, 63, 64, 74\n};\n\n\n/*************************************************************************/\n/*            scale_bitcount                                             */\n/*************************************************************************/\n\n/* Also calculates the number of bits necessary to code the scalefactors. */\n\nstatic int\nmpeg1_scale_bitcount(const lame_internal_flags * gfc, gr_info * const cod_info)\n{\n    int     k, sfb, max_slen1 = 0, max_slen2 = 0;\n\n    /* maximum values */\n    const int *tab;\n    int    *const scalefac = cod_info->scalefac;\n\n    (void) gfc;\n    assert(all_scalefactors_not_negative(scalefac, cod_info->sfbmax));\n\n    if (cod_info->block_type == SHORT_TYPE) {\n        tab = scale_short;\n        if (cod_info->mixed_block_flag)\n            tab = scale_mixed;\n    }\n    else {              /* block_type == 1,2,or 3 */\n        tab = scale_long;\n        if (!cod_info->preflag) {\n            for (sfb = 11; sfb < SBPSY_l; sfb++)\n                if (scalefac[sfb] < pretab[sfb])\n                    break;\n\n            if (sfb == SBPSY_l) {\n                cod_info->preflag = 1;\n                for (sfb = 11; sfb < SBPSY_l; sfb++)\n                    scalefac[sfb] -= pretab[sfb];\n            }\n        }\n    }\n\n    for (sfb = 0; sfb < cod_info->sfbdivide; sfb++)\n        if (max_slen1 < scalefac[sfb])\n            max_slen1 = scalefac[sfb];\n\n    for (; sfb < cod_info->sfbmax; sfb++)\n        if (max_slen2 < scalefac[sfb])\n            max_slen2 = scalefac[sfb];\n\n    /* from Takehiro TOMINAGA <tominaga@isoternet.org> 10/99\n     * loop over *all* posible values of scalefac_compress to find the\n     * one which uses the smallest number of bits.  ISO would stop\n     * at first valid index */\n    cod_info->part2_length = LARGE_BITS;\n    for (k = 0; k < 16; k++) {\n        if (max_slen1 < slen1_n[k] && max_slen2 < slen2_n[k]\n            && cod_info->part2_length > tab[k]) {\n            cod_info->part2_length = tab[k];\n            cod_info->scalefac_compress = k;\n        }\n    }\n    return cod_info->part2_length == LARGE_BITS;\n}\n\n\n\n/*\n  table of largest scalefactor values for MPEG2\n*/\nstatic const int max_range_sfac_tab[6][4] = {\n    {15, 15, 7, 7},\n    {15, 15, 7, 0},\n    {7, 3, 0, 0},\n    {15, 31, 31, 0},\n    {7, 7, 7, 0},\n    {3, 3, 0, 0}\n};\n\n\n\n\n/*************************************************************************/\n/*            scale_bitcount_lsf                                         */\n/*************************************************************************/\n\n/* Also counts the number of bits to encode the scalefacs but for MPEG 2 */\n/* Lower sampling frequencies  (24, 22.05 and 16 kHz.)                   */\n\n/*  This is reverse-engineered from section 2.4.3.2 of the MPEG2 IS,     */\n/* \"Audio Decoding Layer III\"                                            */\n\nstatic int\nmpeg2_scale_bitcount(const lame_internal_flags * gfc, gr_info * const cod_info)\n{\n    int     table_number, row_in_table, partition, nr_sfb, window, over;\n    int     i, sfb, max_sfac[4];\n    const int *partition_table;\n    int const *const scalefac = cod_info->scalefac;\n\n    /*\n       Set partition table. Note that should try to use table one,\n       but do not yet...\n     */\n    if (cod_info->preflag)\n        table_number = 2;\n    else\n        table_number = 0;\n\n    for (i = 0; i < 4; i++)\n        max_sfac[i] = 0;\n\n    if (cod_info->block_type == SHORT_TYPE) {\n        row_in_table = 1;\n        partition_table = &nr_of_sfb_block[table_number][row_in_table][0];\n        for (sfb = 0, partition = 0; partition < 4; partition++) {\n            nr_sfb = partition_table[partition] / 3;\n            for (i = 0; i < nr_sfb; i++, sfb++)\n                for (window = 0; window < 3; window++)\n                    if (scalefac[sfb * 3 + window] > max_sfac[partition])\n                        max_sfac[partition] = scalefac[sfb * 3 + window];\n        }\n    }\n    else {\n        row_in_table = 0;\n        partition_table = &nr_of_sfb_block[table_number][row_in_table][0];\n        for (sfb = 0, partition = 0; partition < 4; partition++) {\n            nr_sfb = partition_table[partition];\n            for (i = 0; i < nr_sfb; i++, sfb++)\n                if (scalefac[sfb] > max_sfac[partition])\n                    max_sfac[partition] = scalefac[sfb];\n        }\n    }\n\n    for (over = 0, partition = 0; partition < 4; partition++) {\n        if (max_sfac[partition] > max_range_sfac_tab[table_number][partition])\n            over++;\n    }\n    if (!over) {\n        /*\n           Since no bands have been over-amplified, we can set scalefac_compress\n           and slen[] for the formatter\n         */\n        static const int log2tab[] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 };\n\n        int     slen1, slen2, slen3, slen4;\n\n        cod_info->sfb_partition_table = nr_of_sfb_block[table_number][row_in_table];\n        for (partition = 0; partition < 4; partition++)\n            cod_info->slen[partition] = log2tab[max_sfac[partition]];\n\n        /* set scalefac_compress */\n        slen1 = cod_info->slen[0];\n        slen2 = cod_info->slen[1];\n        slen3 = cod_info->slen[2];\n        slen4 = cod_info->slen[3];\n\n        switch (table_number) {\n        case 0:\n            cod_info->scalefac_compress = (((slen1 * 5) + slen2) << 4)\n                + (slen3 << 2)\n                + slen4;\n            break;\n\n        case 1:\n            cod_info->scalefac_compress = 400 + (((slen1 * 5) + slen2) << 2)\n                + slen3;\n            break;\n\n        case 2:\n            cod_info->scalefac_compress = 500 + (slen1 * 3) + slen2;\n            break;\n\n        default:\n            ERRORF(gfc, \"intensity stereo not implemented yet\\n\");\n            break;\n        }\n    }\n#ifdef DEBUG\n    if (over)\n        ERRORF(gfc, \"---WARNING !! Amplification of some bands over limits\\n\");\n#endif\n    if (!over) {\n        assert(cod_info->sfb_partition_table);\n        cod_info->part2_length = 0;\n        for (partition = 0; partition < 4; partition++)\n            cod_info->part2_length +=\n                cod_info->slen[partition] * cod_info->sfb_partition_table[partition];\n    }\n    return over;\n}\n\n\nint\nscale_bitcount(const lame_internal_flags * gfc, gr_info * cod_info)\n{\n    if (gfc->cfg.mode_gr == 2) {\n        return mpeg1_scale_bitcount(gfc, cod_info);\n    }\n    else {\n        return mpeg2_scale_bitcount(gfc, cod_info);\n    }\n}\n\n\n#ifdef MMX_choose_table\nextern int choose_table_MMX(const int *ix, const int *const end, int *const s);\n#endif\n\nvoid\nhuffman_init(lame_internal_flags * const gfc)\n{\n    int     i;\n\n    gfc->choose_table = choose_table_nonMMX;\n\n#ifdef MMX_choose_table\n    if (gfc->CPU_features.MMX) {\n        gfc->choose_table = choose_table_MMX;\n    }\n#endif\n\n    for (i = 2; i <= 576; i += 2) {\n        int     scfb_anz = 0, bv_index;\n        while (gfc->scalefac_band.l[++scfb_anz] < i);\n\n        bv_index = subdv_table[scfb_anz].region0_count;\n        while (gfc->scalefac_band.l[bv_index + 1] > i)\n            bv_index--;\n\n        if (bv_index < 0) {\n            /* this is an indication that everything is going to\n               be encoded as region0:  bigvalues < region0 < region1\n               so lets set region0, region1 to some value larger\n               than bigvalues */\n            bv_index = subdv_table[scfb_anz].region0_count;\n        }\n\n        gfc->sv_qnt.bv_scf[i - 2] = bv_index;\n\n        bv_index = subdv_table[scfb_anz].region1_count;\n        while (gfc->scalefac_band.l[bv_index + gfc->sv_qnt.bv_scf[i - 2] + 2] > i)\n            bv_index--;\n\n        if (bv_index < 0) {\n            bv_index = subdv_table[scfb_anz].region1_count;\n        }\n\n        gfc->sv_qnt.bv_scf[i - 1] = bv_index;\n    }\n}\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/util.c",
    "content": "/*\n *\tlame utility library source file\n *\n *\tCopyright (c) 1999 Albert L Faber\n *\tCopyright (c) 2000-2005 Alexander Leidinger\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\t See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n/* $Id: util.c,v 1.154.2.1 2012/01/08 23:49:58 robert Exp $ */\n\n#ifdef HAVE_CONFIG_H\n# include <config.h>\n#endif\n\n#include \"lame.h\"\n#include \"machine.h\"\n#include \"encoder.h\"\n#include \"util.h\"\n#include \"tables.h\"\n\n#define PRECOMPUTE\n#if defined(__FreeBSD__) && !defined(__alpha__)\n# include <machine/floatingpoint.h>\n#endif\n\n\n/***********************************************************************\n*\n*  Global Function Definitions\n*\n***********************************************************************/\n/*empty and close mallocs in gfc */\n\nvoid\nfree_id3tag(lame_internal_flags * const gfc)\n{\n    if (gfc->tag_spec.title != 0) {\n        free(gfc->tag_spec.title);\n        gfc->tag_spec.title = 0;\n    }\n    if (gfc->tag_spec.artist != 0) {\n        free(gfc->tag_spec.artist);\n        gfc->tag_spec.artist = 0;\n    }\n    if (gfc->tag_spec.album != 0) {\n        free(gfc->tag_spec.album);\n        gfc->tag_spec.album = 0;\n    }\n    if (gfc->tag_spec.comment != 0) {\n        free(gfc->tag_spec.comment);\n        gfc->tag_spec.comment = 0;\n    }\n\n    if (gfc->tag_spec.albumart != 0) {\n        free(gfc->tag_spec.albumart);\n        gfc->tag_spec.albumart = 0;\n        gfc->tag_spec.albumart_size = 0;\n        gfc->tag_spec.albumart_mimetype = MIMETYPE_NONE;\n    }\n    if (gfc->tag_spec.v2_head != 0) {\n        FrameDataNode *node = gfc->tag_spec.v2_head;\n        do {\n            void   *p = node->dsc.ptr.b;\n            void   *q = node->txt.ptr.b;\n            void   *r = node;\n            node = node->nxt;\n            free(p);\n            free(q);\n            free(r);\n        } while (node != 0);\n        gfc->tag_spec.v2_head = 0;\n        gfc->tag_spec.v2_tail = 0;\n    }\n}\n\n\nstatic void\nfree_global_data(lame_internal_flags * gfc)\n{\n    if (gfc && gfc->cd_psy) {\n        if (gfc->cd_psy->l.s3) {\n            /* XXX allocated in psymodel_init() */\n            free(gfc->cd_psy->l.s3);\n        }\n        if (gfc->cd_psy->s.s3) {\n            /* XXX allocated in psymodel_init() */\n            free(gfc->cd_psy->s.s3);\n        }\n        free(gfc->cd_psy);\n        gfc->cd_psy = 0;\n    }\n}\n\n\nvoid\nfreegfc(lame_internal_flags * const gfc)\n{                       /* bit stream structure */\n    int     i;\n\n\n    for (i = 0; i <= 2 * BPC; i++)\n        if (gfc->sv_enc.blackfilt[i] != NULL) {\n            free(gfc->sv_enc.blackfilt[i]);\n            gfc->sv_enc.blackfilt[i] = NULL;\n        }\n    if (gfc->sv_enc.inbuf_old[0]) {\n        free(gfc->sv_enc.inbuf_old[0]);\n        gfc->sv_enc.inbuf_old[0] = NULL;\n    }\n    if (gfc->sv_enc.inbuf_old[1]) {\n        free(gfc->sv_enc.inbuf_old[1]);\n        gfc->sv_enc.inbuf_old[1] = NULL;\n    }\n\n    if (gfc->bs.buf != NULL) {\n        free(gfc->bs.buf);\n        gfc->bs.buf = NULL;\n    }\n\n    if (gfc->VBR_seek_table.bag) {\n        free(gfc->VBR_seek_table.bag);\n        gfc->VBR_seek_table.bag = NULL;\n        gfc->VBR_seek_table.size = 0;\n    }\n    if (gfc->ATH) {\n        free(gfc->ATH);\n    }\n    if (gfc->sv_rpg.rgdata) {\n        free(gfc->sv_rpg.rgdata);\n    }\n    if (gfc->sv_enc.in_buffer_0) {\n        free(gfc->sv_enc.in_buffer_0);\n    }\n    if (gfc->sv_enc.in_buffer_1) {\n        free(gfc->sv_enc.in_buffer_1);\n    }\n    free_id3tag(gfc);\n\n#ifdef DECODE_ON_THE_FLY\n    if (gfc->hip) {\n        hip_decode_exit(gfc->hip);\n        gfc->hip = 0;\n    }\n#endif\n\n    free_global_data(gfc);\n\n    free(gfc);\n}\n\nvoid\nmalloc_aligned(aligned_pointer_t * ptr, unsigned int size, unsigned int bytes)\n{\n    if (ptr) {\n        if (!ptr->pointer) {\n            ptr->pointer = malloc(size + bytes);\n            if (bytes > 0) {\n                ptr->aligned = (void *) ((((size_t) ptr->pointer + bytes - 1) / bytes) * bytes);\n            }\n            else {\n                ptr->aligned = ptr->pointer;\n            }\n        }\n    }\n}\n\nvoid\nfree_aligned(aligned_pointer_t * ptr)\n{\n    if (ptr) {\n        if (ptr->pointer) {\n            free(ptr->pointer);\n            ptr->pointer = 0;\n            ptr->aligned = 0;\n        }\n    }\n}\n\n/*those ATH formulas are returning\ntheir minimum value for input = -1*/\n\nstatic  FLOAT\nATHformula_GB(FLOAT f, FLOAT value, FLOAT f_min, FLOAT f_max)\n{\n    /* from Painter & Spanias\n       modified by Gabriel Bouvigne to better fit the reality\n       ath =    3.640 * pow(f,-0.8)\n       - 6.800 * exp(-0.6*pow(f-3.4,2.0))\n       + 6.000 * exp(-0.15*pow(f-8.7,2.0))\n       + 0.6* 0.001 * pow(f,4.0);\n\n\n       In the past LAME was using the Painter &Spanias formula.\n       But we had some recurrent problems with HF content.\n       We measured real ATH values, and found the older formula\n       to be inacurate in the higher part. So we made this new\n       formula and this solved most of HF problematic testcases.\n       The tradeoff is that in VBR mode it increases a lot the\n       bitrate. */\n\n\n/*this curve can be udjusted according to the VBR scale:\nit adjusts from something close to Painter & Spanias\non V9 up to Bouvigne's formula for V0. This way the VBR\nbitrate is more balanced according to the -V value.*/\n\n    FLOAT   ath;\n\n    /* the following Hack allows to ask for the lowest value */\n    if (f < -.3)\n        f = 3410;\n\n    f /= 1000;          /* convert to khz */\n    f = Max(f_min, f);\n    f = Min(f_max, f);\n\n    ath = 3.640 * pow(f, -0.8)\n        - 6.800 * exp(-0.6 * pow(f - 3.4, 2.0))\n        + 6.000 * exp(-0.15 * pow(f - 8.7, 2.0))\n        + (0.6 + 0.04 * value) * 0.001 * pow(f, 4.0);\n    return ath;\n}\n\n\n\nFLOAT\nATHformula(SessionConfig_t const *cfg, FLOAT f)\n{\n    FLOAT   ath;\n    switch (cfg->ATHtype) {\n    case 0:\n        ath = ATHformula_GB(f, 9, 0.1f, 24.0f);\n        break;\n    case 1:\n        ath = ATHformula_GB(f, -1, 0.1f, 24.0f); /*over sensitive, should probably be removed */\n        break;\n    case 2:\n        ath = ATHformula_GB(f, 0, 0.1f, 24.0f);\n        break;\n    case 3:\n        ath = ATHformula_GB(f, 1, 0.1f, 24.0f) + 6; /*modification of GB formula by Roel */\n        break;\n    case 4:\n        ath = ATHformula_GB(f, cfg->ATHcurve, 0.1f, 24.0f);\n        break;\n    case 5:\n        ath = ATHformula_GB(f, cfg->ATHcurve, 3.41f, 16.1f);\n        break;\n    default:\n        ath = ATHformula_GB(f, 0, 0.1f, 24.0f);\n        break;\n    }\n    return ath;\n}\n\n/* see for example \"Zwicker: Psychoakustik, 1982; ISBN 3-540-11401-7 */\nFLOAT\nfreq2bark(FLOAT freq)\n{\n    /* input: freq in hz  output: barks */\n    if (freq < 0)\n        freq = 0;\n    freq = freq * 0.001;\n    return 13.0 * atan(.76 * freq) + 3.5 * atan(freq * freq / (7.5 * 7.5));\n}\n\n#if 0\nextern FLOAT freq2cbw(FLOAT freq);\n\n/* see for example \"Zwicker: Psychoakustik, 1982; ISBN 3-540-11401-7 */\nFLOAT\nfreq2cbw(FLOAT freq)\n{\n    /* input: freq in hz  output: critical band width */\n    freq = freq * 0.001;\n    return 25 + 75 * pow(1 + 1.4 * (freq * freq), 0.69);\n}\n\n#endif\n\n\n\n\n#define ABS(A) (((A)>0) ? (A) : -(A))\n\nint\nFindNearestBitrate(int bRate, /* legal rates from 8 to 320 */\n                   int version, int samplerate)\n{                       /* MPEG-1 or MPEG-2 LSF */\n    int     bitrate;\n    int     i;\n\n    if (samplerate < 16000)\n        version = 2;\n\n    bitrate = bitrate_table[version][1];\n\n    for (i = 2; i <= 14; i++) {\n        if (bitrate_table[version][i] > 0) {\n            if (ABS(bitrate_table[version][i] - bRate) < ABS(bitrate - bRate))\n                bitrate = bitrate_table[version][i];\n        }\n    }\n    return bitrate;\n}\n\n\n\n\n\n#ifndef Min\n#define         Min(A, B)       ((A) < (B) ? (A) : (B))\n#endif\n#ifndef Max\n#define         Max(A, B)       ((A) > (B) ? (A) : (B))\n#endif\n\n\n/* Used to find table index when\n * we need bitrate-based values\n * determined using tables\n *\n * bitrate in kbps\n *\n * Gabriel Bouvigne 2002-11-03\n */\nint\nnearestBitrateFullIndex(uint16_t bitrate)\n{\n    /* borrowed from DM abr presets */\n\n    const int full_bitrate_table[] =\n        { 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 };\n\n\n    int     lower_range = 0, lower_range_kbps = 0, upper_range = 0, upper_range_kbps = 0;\n\n\n    int     b;\n\n\n    /* We assume specified bitrate will be 320kbps */\n    upper_range_kbps = full_bitrate_table[16];\n    upper_range = 16;\n    lower_range_kbps = full_bitrate_table[16];\n    lower_range = 16;\n\n    /* Determine which significant bitrates the value specified falls between,\n     * if loop ends without breaking then we were correct above that the value was 320\n     */\n    for (b = 0; b < 16; b++) {\n        if ((Max(bitrate, full_bitrate_table[b + 1])) != bitrate) {\n            upper_range_kbps = full_bitrate_table[b + 1];\n            upper_range = b + 1;\n            lower_range_kbps = full_bitrate_table[b];\n            lower_range = (b);\n            break;      /* We found upper range */\n        }\n    }\n\n    /* Determine which range the value specified is closer to */\n    if ((upper_range_kbps - bitrate) > (bitrate - lower_range_kbps)) {\n        return lower_range;\n    }\n    return upper_range;\n}\n\n\n\n\n\n/* map frequency to a valid MP3 sample frequency\n *\n * Robert Hegemann 2000-07-01\n */\nint\nmap2MP3Frequency(int freq)\n{\n    if (freq <= 8000)\n        return 8000;\n    if (freq <= 11025)\n        return 11025;\n    if (freq <= 12000)\n        return 12000;\n    if (freq <= 16000)\n        return 16000;\n    if (freq <= 22050)\n        return 22050;\n    if (freq <= 24000)\n        return 24000;\n    if (freq <= 32000)\n        return 32000;\n    if (freq <= 44100)\n        return 44100;\n\n    return 48000;\n}\n\nint\nBitrateIndex(int bRate,      /* legal rates from 32 to 448 kbps */\n             int version,    /* MPEG-1 or MPEG-2/2.5 LSF */\n             int samplerate)\n{                       /* convert bitrate in kbps to index */\n    int     i;\n    if (samplerate < 16000)\n        version = 2;\n    for (i = 0; i <= 14; i++) {\n        if (bitrate_table[version][i] > 0) {\n            if (bitrate_table[version][i] == bRate) {\n                return i;\n            }\n        }\n    }\n    return -1;\n}\n\n/* convert samp freq in Hz to index */\n\nint\nSmpFrqIndex(int sample_freq, int *const version)\n{\n    switch (sample_freq) {\n    case 44100:\n        *version = 1;\n        return 0;\n    case 48000:\n        *version = 1;\n        return 1;\n    case 32000:\n        *version = 1;\n        return 2;\n    case 22050:\n        *version = 0;\n        return 0;\n    case 24000:\n        *version = 0;\n        return 1;\n    case 16000:\n        *version = 0;\n        return 2;\n    case 11025:\n        *version = 0;\n        return 0;\n    case 12000:\n        *version = 0;\n        return 1;\n    case 8000:\n        *version = 0;\n        return 2;\n    default:\n        *version = 0;\n        return -1;\n    }\n}\n\n\n/*****************************************************************************\n*\n*  End of bit_stream.c package\n*\n*****************************************************************************/\n\n\n\n\n\n\n\n\n\n\n/* resampling via FIR filter, blackman window */\ninline static FLOAT\nblackman(FLOAT x, FLOAT fcn, int l)\n{\n    /* This algorithm from:\n       SIGNAL PROCESSING ALGORITHMS IN FORTRAN AND C\n       S.D. Stearns and R.A. David, Prentice-Hall, 1992\n     */\n    FLOAT   bkwn, x2;\n    FLOAT const wcn = (PI * fcn);\n\n    x /= l;\n    if (x < 0)\n        x = 0;\n    if (x > 1)\n        x = 1;\n    x2 = x - .5;\n\n    bkwn = 0.42 - 0.5 * cos(2 * x * PI) + 0.08 * cos(4 * x * PI);\n    if (fabs(x2) < 1e-9)\n        return wcn / PI;\n    else\n        return (bkwn * sin(l * wcn * x2) / (PI * l * x2));\n\n\n}\n\n\n\n\n/* gcd - greatest common divisor */\n/* Joint work of Euclid and M. Hendry */\n\nstatic int\ngcd(int i, int j)\n{\n    /*    assert ( i > 0  &&  j > 0 ); */\n    return j ? gcd(j, i % j) : i;\n}\n\n\n\nstatic int\nfill_buffer_resample(lame_internal_flags * gfc,\n                     sample_t * outbuf,\n                     int desired_len, sample_t const *inbuf, int len, int *num_used, int ch)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    EncStateVar_t *esv = &gfc->sv_enc;\n    double  resample_ratio = (double)cfg->samplerate_in / (double)cfg->samplerate_out;\n    int     BLACKSIZE;\n    FLOAT   offset, xvalue;\n    int     i, j = 0, k;\n    int     filter_l;\n    FLOAT   fcn, intratio;\n    FLOAT  *inbuf_old;\n    int     bpc;             /* number of convolution functions to pre-compute */\n    bpc = cfg->samplerate_out / gcd(cfg->samplerate_out, cfg->samplerate_in);\n    if (bpc > BPC)\n        bpc = BPC;\n\n    intratio = (fabs(resample_ratio - floor(.5 + resample_ratio)) < .0001);\n    fcn = 1.00 / resample_ratio;\n    if (fcn > 1.00)\n        fcn = 1.00;\n    filter_l = 31;     /* must be odd */\n    filter_l += intratio; /* unless resample_ratio=int, it must be even */\n\n\n    BLACKSIZE = filter_l + 1; /* size of data needed for FIR */\n\n    if (gfc->fill_buffer_resample_init == 0) {\n        esv->inbuf_old[0] = calloc(BLACKSIZE, sizeof(esv->inbuf_old[0][0]));\n        esv->inbuf_old[1] = calloc(BLACKSIZE, sizeof(esv->inbuf_old[0][0]));\n        for (i = 0; i <= 2 * bpc; ++i)\n            esv->blackfilt[i] = calloc(BLACKSIZE, sizeof(esv->blackfilt[0][0]));\n\n        esv->itime[0] = 0;\n        esv->itime[1] = 0;\n\n        /* precompute blackman filter coefficients */\n        for (j = 0; j <= 2 * bpc; j++) {\n            FLOAT   sum = 0.;\n            offset = (j - bpc) / (2. * bpc);\n            for (i = 0; i <= filter_l; i++)\n                sum += esv->blackfilt[j][i] = blackman(i - offset, fcn, filter_l);\n            for (i = 0; i <= filter_l; i++)\n                esv->blackfilt[j][i] /= sum;\n        }\n        gfc->fill_buffer_resample_init = 1;\n    }\n\n    inbuf_old = esv->inbuf_old[ch];\n\n    /* time of j'th element in inbuf = itime + j/ifreq; */\n    /* time of k'th element in outbuf   =  j/ofreq */\n    for (k = 0; k < desired_len; k++) {\n        double  time0 = k * resample_ratio; /* time of k'th output sample */\n        int     joff;\n\n        j = floor(time0 - esv->itime[ch]);\n\n        /* check if we need more input data */\n        if ((filter_l + j - filter_l / 2) >= len)\n            break;\n\n        /* blackman filter.  by default, window centered at j+.5(filter_l%2) */\n        /* but we want a window centered at time0.   */\n        offset = (time0 - esv->itime[ch] - (j + .5 * (filter_l % 2)));\n        assert(fabs(offset) <= .501);\n\n        /* find the closest precomputed window for this offset: */\n        joff = floor((offset * 2 * bpc) + bpc + .5);\n\n        xvalue = 0.;\n        for (i = 0; i <= filter_l; ++i) {\n            int const j2 = i + j - filter_l / 2;\n            sample_t y;\n            assert(j2 < len);\n            assert(j2 + BLACKSIZE >= 0);\n            y = (j2 < 0) ? inbuf_old[BLACKSIZE + j2] : inbuf[j2];\n#ifdef PRECOMPUTE\n            xvalue += y * esv->blackfilt[joff][i];\n#else\n            xvalue += y * blackman(i - offset, fcn, filter_l); /* very slow! */\n#endif\n        }\n        outbuf[k] = xvalue;\n    }\n\n\n    /* k = number of samples added to outbuf */\n    /* last k sample used data from [j-filter_l/2,j+filter_l-filter_l/2]  */\n\n    /* how many samples of input data were used:  */\n    *num_used = Min(len, filter_l + j - filter_l / 2);\n\n    /* adjust our input time counter.  Incriment by the number of samples used,\n     * then normalize so that next output sample is at time 0, next\n     * input buffer is at time itime[ch] */\n    esv->itime[ch] += *num_used - k * resample_ratio;\n\n    /* save the last BLACKSIZE samples into the inbuf_old buffer */\n    if (*num_used >= BLACKSIZE) {\n        for (i = 0; i < BLACKSIZE; i++)\n            inbuf_old[i] = inbuf[*num_used + i - BLACKSIZE];\n    }\n    else {\n        /* shift in *num_used samples into inbuf_old  */\n        int const n_shift = BLACKSIZE - *num_used; /* number of samples to shift */\n\n        /* shift n_shift samples by *num_used, to make room for the\n         * num_used new samples */\n        for (i = 0; i < n_shift; ++i)\n            inbuf_old[i] = inbuf_old[i + *num_used];\n\n        /* shift in the *num_used samples */\n        for (j = 0; i < BLACKSIZE; ++i, ++j)\n            inbuf_old[i] = inbuf[j];\n\n        assert(j == *num_used);\n    }\n    return k;           /* return the number samples created at the new samplerate */\n}\n\nint\nisResamplingNecessary(SessionConfig_t const* cfg)\n{\n    int const l = cfg->samplerate_out * 0.9995f;\n    int const h = cfg->samplerate_out * 1.0005f;\n    return (cfg->samplerate_in < l) || (h < cfg->samplerate_in) ? 1 : 0;\n}\n\n/* copy in new samples from in_buffer into mfbuf, with resampling\n   if necessary.  n_in = number of samples from the input buffer that\n   were used.  n_out = number of samples copied into mfbuf  */\n\nvoid\nfill_buffer(lame_internal_flags * gfc,\n            sample_t * const mfbuf[2], sample_t const * const in_buffer[2], int nsamples, int *n_in, int *n_out)\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    int     mf_size = gfc->sv_enc.mf_size;\n    int     framesize = 576 * cfg->mode_gr;\n    int     nout, ch = 0;\n    int     nch = cfg->channels_out;\n\n    /* copy in new samples into mfbuf, with resampling if necessary */\n    if (isResamplingNecessary(cfg)) {\n        do {\n            nout =\n                fill_buffer_resample(gfc, &mfbuf[ch][mf_size],\n                                     framesize, in_buffer[ch], nsamples, n_in, ch);\n        } while (++ch < nch);\n        *n_out = nout;\n    }\n    else {\n        nout = Min(framesize, nsamples);\n        do {\n            memcpy(&mfbuf[ch][mf_size], &in_buffer[ch][0], nout * sizeof(mfbuf[0][0]));\n        } while (++ch < nch);\n        *n_out = nout;\n        *n_in = nout;\n    }\n}\n\n\n\n\n\n\n\n/***********************************************************************\n*\n*  Message Output\n*\n***********************************************************************/\n\nvoid\nlame_report_def(const char *format, va_list args)\n{\n    (void) vfprintf(stderr, format, args);\n    fflush(stderr); /* an debug function should flush immediately */\n}\n\nvoid \nlame_report_fnc(lame_report_function print_f, const char *format, ...)\n{\n    if (print_f) {\n        va_list args;\n        va_start(args, format);\n        print_f(format, args);\n        va_end(args);\n    }\n}\n\n\nvoid\nlame_debugf(const lame_internal_flags* gfc, const char *format, ...)\n{\n    if (gfc && gfc->report_dbg) {\n        va_list args;\n        va_start(args, format);\n        gfc->report_dbg(format, args);\n        va_end(args);\n    }\n}\n\n\nvoid\nlame_msgf(const lame_internal_flags* gfc, const char *format, ...)\n{\n    if (gfc && gfc->report_msg) {\n        va_list args;\n        va_start(args, format);\n        gfc->report_msg(format, args);\n        va_end(args);\n    }\n}\n\n\nvoid\nlame_errorf(const lame_internal_flags* gfc, const char *format, ...)\n{\n    if (gfc && gfc->report_err) {\n        va_list args;\n        va_start(args, format);\n        gfc->report_err(format, args);\n        va_end(args);\n    }\n}\n\n\n\n/***********************************************************************\n *\n *      routines to detect CPU specific features like 3DNow, MMX, SSE\n *\n *  donated by Frank Klemm\n *  added Robert Hegemann 2000-10-10\n *\n ***********************************************************************/\n\n#ifdef HAVE_NASM\nextern int has_MMX_nasm(void);\nextern int has_3DNow_nasm(void);\nextern int has_SSE_nasm(void);\nextern int has_SSE2_nasm(void);\n#endif\n\nint\nhas_MMX(void)\n{\n#ifdef HAVE_NASM\n    return has_MMX_nasm();\n#else\n    return 0;           /* don't know, assume not */\n#endif\n}\n\nint\nhas_3DNow(void)\n{\n#ifdef HAVE_NASM\n    return has_3DNow_nasm();\n#else\n    return 0;           /* don't know, assume not */\n#endif\n}\n\nint\nhas_SSE(void)\n{\n#ifdef HAVE_NASM\n    return has_SSE_nasm();\n#else\n#if defined( _M_X64 ) || defined( MIN_ARCH_SSE )\n    return 1;\n#else\n    return 0;           /* don't know, assume not */\n#endif\n#endif\n}\n\nint\nhas_SSE2(void)\n{\n#ifdef HAVE_NASM\n    return has_SSE2_nasm();\n#else\n#if defined( _M_X64 ) || defined( MIN_ARCH_SSE )\n    return 1;\n#else\n    return 0;           /* don't know, assume not */\n#endif\n#endif\n}\n\nvoid\ndisable_FPE(void)\n{\n/* extremly system dependent stuff, move to a lib to make the code readable */\n/*==========================================================================*/\n\n\n\n    /*\n     *  Disable floating point exceptions\n     */\n\n\n\n\n#if defined(__FreeBSD__) && !defined(__alpha__)\n    {\n        /* seet floating point mask to the Linux default */\n        fp_except_t mask;\n        mask = fpgetmask();\n        /* if bit is set, we get SIGFPE on that error! */\n        fpsetmask(mask & ~(FP_X_INV | FP_X_DZ));\n        /*  DEBUGF(\"FreeBSD mask is 0x%x\\n\",mask); */\n    }\n#endif\n\n#if defined(__riscos__) && !defined(ABORTFP)\n    /* Disable FPE's under RISC OS */\n    /* if bit is set, we disable trapping that error! */\n    /*   _FPE_IVO : invalid operation */\n    /*   _FPE_DVZ : divide by zero */\n    /*   _FPE_OFL : overflow */\n    /*   _FPE_UFL : underflow */\n    /*   _FPE_INX : inexact */\n    DisableFPETraps(_FPE_IVO | _FPE_DVZ | _FPE_OFL);\n#endif\n\n    /*\n     *  Debugging stuff\n     *  The default is to ignore FPE's, unless compiled with -DABORTFP\n     *  so add code below to ENABLE FPE's.\n     */\n\n#if defined(ABORTFP)\n#if defined(_MSC_VER)\n    {\n#if 0\n        /* rh 061207\n           the following fix seems to be a workaround for a problem in the\n           parent process calling LAME. It would be better to fix the broken\n           application => code disabled.\n         */\n\n        /* set affinity to a single CPU.  Fix for EAC/lame on SMP systems from\n           \"Todd Richmond\" <todd.richmond@openwave.com> */\n        SYSTEM_INFO si;\n        GetSystemInfo(&si);\n        SetProcessAffinityMask(GetCurrentProcess(), si.dwActiveProcessorMask);\n#endif\n#include <float.h>\n        unsigned int mask;\n        mask = _controlfp(0, 0);\n        mask &= ~(_EM_OVERFLOW | _EM_UNDERFLOW | _EM_ZERODIVIDE | _EM_INVALID);\n        mask = _controlfp(mask, _MCW_EM);\n    }\n#elif defined(__CYGWIN__)\n#  define _FPU_GETCW(cw) __asm__ (\"fnstcw %0\" : \"=m\" (*&cw))\n#  define _FPU_SETCW(cw) __asm__ (\"fldcw %0\" : : \"m\" (*&cw))\n\n#  define _EM_INEXACT     0x00000020 /* inexact (precision) */\n#  define _EM_UNDERFLOW   0x00000010 /* underflow */\n#  define _EM_OVERFLOW    0x00000008 /* overflow */\n#  define _EM_ZERODIVIDE  0x00000004 /* zero divide */\n#  define _EM_INVALID     0x00000001 /* invalid */\n    {\n        unsigned int mask;\n        _FPU_GETCW(mask);\n        /* Set the FPU control word to abort on most FPEs */\n        mask &= ~(_EM_OVERFLOW | _EM_ZERODIVIDE | _EM_INVALID);\n        _FPU_SETCW(mask);\n    }\n# elif defined(__linux__)\n    {\n\n#  include <fpu_control.h>\n#  ifndef _FPU_GETCW\n#  define _FPU_GETCW(cw) __asm__ (\"fnstcw %0\" : \"=m\" (*&cw))\n#  endif\n#  ifndef _FPU_SETCW\n#  define _FPU_SETCW(cw) __asm__ (\"fldcw %0\" : : \"m\" (*&cw))\n#  endif\n\n        /* \n         * Set the Linux mask to abort on most FPE's\n         * if bit is set, we _mask_ SIGFPE on that error!\n         *  mask &= ~( _FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM | _FPU_MASK_UM );\n         */\n\n        unsigned int mask;\n        _FPU_GETCW(mask);\n        mask &= ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM);\n        _FPU_SETCW(mask);\n    }\n#endif\n#endif /* ABORTFP */\n}\n\n\n\n\n\n#ifdef USE_FAST_LOG\n/***********************************************************************\n *\n * Fast Log Approximation for log2, used to approximate every other log\n * (log10 and log)\n * maximum absolute error for log10 is around 10-6\n * maximum *relative* error can be high when x is almost 1 because error/log10(x) tends toward x/e\n *\n * use it if typical RESULT values are > 1e-5 (for example if x>1.00001 or x<0.99999)\n * or if the relative precision in the domain around 1 is not important (result in 1 is exact and 0)\n *\n ***********************************************************************/\n\n\n#define LOG2_SIZE       (512)\n#define LOG2_SIZE_L2    (9)\n\nstatic ieee754_float32_t log_table[LOG2_SIZE + 1];\n\n\n\nvoid\ninit_log_table(void)\n{\n    int     j;\n    static int init = 0;\n\n    /* Range for log2(x) over [1,2[ is [0,1[ */\n    assert((1 << LOG2_SIZE_L2) == LOG2_SIZE);\n\n    if (!init) {\n        for (j = 0; j < LOG2_SIZE + 1; j++)\n            log_table[j] = log(1.0f + j / (ieee754_float32_t) LOG2_SIZE) / log(2.0f);\n    }\n    init = 1;\n}\n\n\n\nieee754_float32_t\nfast_log2(ieee754_float32_t x)\n{\n    ieee754_float32_t log2val, partial;\n    union {\n        ieee754_float32_t f;\n        int     i;\n    } fi;\n    int     mantisse;\n    fi.f = x;\n    mantisse = fi.i & 0x7fffff;\n    log2val = ((fi.i >> 23) & 0xFF) - 0x7f;\n    partial = (mantisse & ((1 << (23 - LOG2_SIZE_L2)) - 1));\n    partial *= 1.0f / ((1 << (23 - LOG2_SIZE_L2)));\n\n\n    mantisse >>= (23 - LOG2_SIZE_L2);\n\n    /* log2val += log_table[mantisse];  without interpolation the results are not good */\n    log2val += log_table[mantisse] * (1.0f - partial) + log_table[mantisse + 1] * partial;\n\n    return log2val;\n}\n\n#else /* Don't use FAST_LOG */\n\n\nvoid\ninit_log_table(void)\n{\n}\n\n\n#endif\n\n/* end of util.c */\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/util.h",
    "content": "/*\n *      lame utility library include file\n *\n *      Copyright (c) 1999 Albert L Faber\n *      Copyright (c) 2008 Robert Hegemann\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n#ifndef LAME_UTIL_H\n#define LAME_UTIL_H\n\n#include \"l3side.h\"\n#include \"id3tag.h\"\n#include \"lame_global_flags.h\"\n\n#ifdef __cplusplus\nextern  \"C\" {\n#endif\n\n/***********************************************************************\n*\n*  Global Definitions\n*\n***********************************************************************/\n\n#ifndef FALSE\n#define         FALSE                   0\n#endif\n\n#ifndef TRUE\n#define         TRUE                    (!FALSE)\n#endif\n\n#ifdef UINT_MAX\n# define         MAX_U_32_NUM            UINT_MAX\n#else\n# define         MAX_U_32_NUM            0xFFFFFFFF\n#endif\n\n#ifndef PI\n# ifdef M_PI\n#  define       PI                      M_PI\n# else\n#  define       PI                      3.14159265358979323846\n# endif\n#endif\n\n\n#ifdef M_LN2\n# define        LOG2                    M_LN2\n#else\n# define        LOG2                    0.69314718055994530942\n#endif\n\n#ifdef M_LN10\n# define        LOG10                   M_LN10\n#else\n# define        LOG10                   2.30258509299404568402\n#endif\n\n\n#ifdef M_SQRT2\n# define        SQRT2                   M_SQRT2\n#else\n# define        SQRT2                   1.41421356237309504880\n#endif\n\n\n#define         CRC16_POLYNOMIAL        0x8005\n\n#define MAX_BITS_PER_CHANNEL 4095\n#define MAX_BITS_PER_GRANULE 7680\n\n/* \"bit_stream.h\" Definitions */\n#define         BUFFER_SIZE     LAME_MAXMP3BUFFER\n\n#define         Min(A, B)       ((A) < (B) ? (A) : (B))\n#define         Max(A, B)       ((A) > (B) ? (A) : (B))\n\n/* log/log10 approximations */\n#ifdef USE_FAST_LOG\n#define         FAST_LOG10(x)       (fast_log2(x)*(LOG2/LOG10))\n#define         FAST_LOG(x)         (fast_log2(x)*LOG2)\n#define         FAST_LOG10_X(x,y)   (fast_log2(x)*(LOG2/LOG10*(y)))\n#define         FAST_LOG_X(x,y)     (fast_log2(x)*(LOG2*(y)))\n#else\n#define         FAST_LOG10(x)       log10(x)\n#define         FAST_LOG(x)         log(x)\n#define         FAST_LOG10_X(x,y)   (log10(x)*(y))\n#define         FAST_LOG_X(x,y)     (log(x)*(y))\n#endif\n\n\n    struct replaygain_data;\n#ifndef replaygain_data_defined\n#define replaygain_data_defined\n    typedef struct replaygain_data replaygain_t;\n#endif\n    struct plotting_data;\n#ifndef plotting_data_defined\n#define plotting_data_defined\n    typedef struct plotting_data plotting_data;\n#endif\n\n/***********************************************************************\n*\n*  Global Type Definitions\n*\n***********************************************************************/\n\n    typedef struct {\n        void   *aligned;     /* pointer to ie. 128 bit aligned memory */\n        void   *pointer;     /* to use with malloc/free */\n    } aligned_pointer_t;\n\n    void    malloc_aligned(aligned_pointer_t * ptr, unsigned int size, unsigned int bytes);\n    void    free_aligned(aligned_pointer_t * ptr);\n\n\n    typedef void (*iteration_loop_t) (lame_internal_flags * gfc, const FLOAT pe[2][2],\n                                      const FLOAT ms_ratio[2], const III_psy_ratio ratio[2][2]);\n\n\n    /* \"bit_stream.h\" Type Definitions */\n\n    typedef struct bit_stream_struc {\n        unsigned char *buf;  /* bit stream buffer */\n        int     buf_size;    /* size of buffer (in number of bytes) */\n        int     totbit;      /* bit counter of bit stream */\n        int     buf_byte_idx; /* pointer to top byte in buffer */\n        int     buf_bit_idx; /* pointer to top bit of top byte in buffer */\n\n        /* format of file in rd mode (BINARY/ASCII) */\n    } Bit_stream_struc;\n\n\n\n    typedef struct {\n        int     sum;         /* what we have seen so far */\n        int     seen;        /* how many frames we have seen in this chunk */\n        int     want;        /* how many frames we want to collect into one chunk */\n        int     pos;         /* actual position in our bag */\n        int     size;        /* size of our bag */\n        int    *bag;         /* pointer to our bag */\n        unsigned int nVbrNumFrames;\n        unsigned long nBytesWritten;\n        /* VBR tag data */\n        unsigned int TotalFrameSize;\n    } VBR_seek_info_t;\n\n\n    /**\n     *  ATH related stuff, if something new ATH related has to be added,\n     *  please plugg it here into the ATH_t struct\n     */\n    typedef struct {\n        int     use_adjust;  /* method for the auto adjustment  */\n        FLOAT   aa_sensitivity_p; /* factor for tuning the (sample power)\n                                     point below which adaptive threshold\n                                     of hearing adjustment occurs */\n        FLOAT   adjust_factor; /* lowering based on peak volume, 1 = no lowering */\n        FLOAT   adjust_limit; /* limit for dynamic ATH adjust */\n        FLOAT   decay;       /* determined to lower x dB each second */\n        FLOAT   floor;       /* lowest ATH value */\n        FLOAT   l[SBMAX_l];  /* ATH for sfbs in long blocks */\n        FLOAT   s[SBMAX_s];  /* ATH for sfbs in short blocks */\n        FLOAT   psfb21[PSFB21]; /* ATH for partitionned sfb21 in long blocks */\n        FLOAT   psfb12[PSFB12]; /* ATH for partitionned sfb12 in short blocks */\n        FLOAT   cb_l[CBANDS]; /* ATH for long block convolution bands */\n        FLOAT   cb_s[CBANDS]; /* ATH for short block convolution bands */\n        FLOAT   eql_w[BLKSIZE / 2]; /* equal loudness weights (based on ATH) */\n    } ATH_t;\n\n    /**\n     *  PSY Model related stuff\n     */\n\n    typedef struct {\n        FLOAT   masking_lower[CBANDS];\n        FLOAT   minval[CBANDS];\n        FLOAT   rnumlines[CBANDS];\n        FLOAT   mld_cb[CBANDS];\n        FLOAT   mld[Max(SBMAX_l,SBMAX_s)];\n        FLOAT   bo_weight[Max(SBMAX_l,SBMAX_s)]; /* band weight long scalefactor bands, at transition */\n        FLOAT   attack_threshold; /* short block tuning */\n        int     s3ind[CBANDS][2];\n        int     numlines[CBANDS];\n        int     bm[Max(SBMAX_l,SBMAX_s)];\n        int     bo[Max(SBMAX_l,SBMAX_s)];\n        int     npart;\n        int     n_sb; /* SBMAX_l or SBMAX_s */\n        FLOAT  *s3;\n    } PsyConst_CB2SB_t;\n\n\n    /**\n     *  global data constants\n     */\n    typedef struct {\n        PsyConst_CB2SB_t l;\n        PsyConst_CB2SB_t s;\n        PsyConst_CB2SB_t l_to_s;\n        FLOAT   attack_threshold[4];\n        FLOAT   decay;\n        int     force_short_block_calc;\n    } PsyConst_t;\n\n\n    typedef struct {\n\n        FLOAT   nb_l1[4][CBANDS], nb_l2[4][CBANDS];\n        FLOAT   nb_s1[4][CBANDS], nb_s2[4][CBANDS];\n\n        III_psy_xmin thm[4];\n        III_psy_xmin en[4];\n\n        /* loudness calculation (for adaptive threshold of hearing) */\n        FLOAT   loudness_sq_save[2]; /* account for granule delay of L3psycho_anal */\n\n        FLOAT   tot_ener[4];\n\n        FLOAT   last_en_subshort[4][9];\n        int     last_attacks[4];\n\n        int     blocktype_old[2];\n    } PsyStateVar_t;\n\n\n    typedef struct {\n        /* loudness calculation (for adaptive threshold of hearing) */\n        FLOAT   loudness_sq[2][2]; /* loudness^2 approx. per granule and channel */\n    } PsyResult_t;\n\n\n    /* variables used by encoder.c */\n    typedef struct {\n        /* variables for newmdct.c */\n        FLOAT   sb_sample[2][2][18][SBLIMIT];\n        FLOAT   amp_filter[32];\n\n        /* variables used by util.c */\n        /* BPC = maximum number of filter convolution windows to precompute */\n#define BPC 320\n        double  itime[2]; /* float precision seems to be not enough */\n        sample_t *inbuf_old[2];\n        sample_t *blackfilt[2 * BPC + 1];\n\n        FLOAT   pefirbuf[19];\n        \n        /* used for padding */\n        int     frac_SpF;\n        int     slot_lag;\n\n        /* variables for bitstream.c */\n        /* mpeg1: buffer=511 bytes  smallest frame: 96-38(sideinfo)=58\n         * max number of frames in reservoir:  8\n         * mpeg2: buffer=255 bytes.  smallest frame: 24-23bytes=1\n         * with VBR, if you are encoding all silence, it is possible to\n         * have 8kbs/24khz frames with 1byte of data each, which means we need\n         * to buffer up to 255 headers! */\n        /* also, max_header_buf has to be a power of two */\n#define MAX_HEADER_BUF 256\n#define MAX_HEADER_LEN 40    /* max size of header is 38 */\n        struct {\n            int     write_timing;\n            int     ptr;\n            char    buf[MAX_HEADER_LEN];\n        } header[MAX_HEADER_BUF];\n\n        int     h_ptr;\n        int     w_ptr;\n        int     ancillary_flag;\n\n        /* variables for reservoir.c */\n        int     ResvSize;    /* in bits */\n        int     ResvMax;     /* in bits */\n\n        int     in_buffer_nsamples;\n        sample_t *in_buffer_0;\n        sample_t *in_buffer_1;\n\n#ifndef  MFSIZE\n# define MFSIZE  ( 3*1152 + ENCDELAY - MDCTDELAY )\n#endif\n        sample_t mfbuf[2][MFSIZE];\n\n        int     mf_samples_to_encode;\n        int     mf_size;\n\n    } EncStateVar_t;\n\n\n    typedef struct {\n        /* simple statistics */\n        int     bitrate_channelmode_hist[16][4 + 1];\n        int     bitrate_blocktype_hist[16][4 + 1 + 1]; /*norm/start/short/stop/mixed(short)/sum */\n\n        int     bitrate_index;\n        int     frame_number; /* number of frames encoded             */\n        int     padding;     /* padding for the current frame? */\n        int     mode_ext;\n        int     encoder_delay;\n        int     encoder_padding; /* number of samples of padding appended to input */\n    } EncResult_t;\n\n\n    /* variables used by quantize.c */\n    typedef struct {\n        /* variables for nspsytune */\n        FLOAT   longfact[SBMAX_l];\n        FLOAT   shortfact[SBMAX_s];\n        FLOAT   masking_lower;\n        FLOAT   mask_adjust; /* the dbQ stuff */\n        FLOAT   mask_adjust_short; /* the dbQ stuff */\n        int     OldValue[2];\n        int     CurrentStep[2];\n        int     pseudohalf[SFBMAX];\n        int     sfb21_extra; /* will be set in lame_init_params */\n        int     substep_shaping; /* 0 = no substep\n                                    1 = use substep shaping at last step(VBR only)\n                                    (not implemented yet)\n                                    2 = use substep inside loop\n                                    3 = use substep inside loop and last step\n                                  */\n\n\n        char    bv_scf[576];\n    } QntStateVar_t;\n\n\n    typedef struct {\n        replaygain_t *rgdata;\n        /* ReplayGain */\n    } RpgStateVar_t;\n\n\n    typedef struct {\n        FLOAT   noclipScale; /* user-specified scale factor required for preventing clipping */\n        sample_t PeakSample;\n        int     RadioGain;\n        int     noclipGainChange; /* gain change required for preventing clipping */\n    } RpgResult_t;\n\n\n    typedef struct {\n        int     version;     /* 0=MPEG-2/2.5  1=MPEG-1               */\n        int     samplerate_index;\n        int     sideinfo_len;\n\n        int     noise_shaping; /* 0 = none\n                                  1 = ISO AAC model\n                                  2 = allow scalefac_select=1\n                                */\n\n        int     subblock_gain; /*  0 = no, 1 = yes */\n        int     use_best_huffman; /* 0 = no.  1=outside loop  2=inside loop(slow) */\n        int     noise_shaping_amp; /*  0 = ISO model: amplify all distorted bands\n                                      1 = amplify within 50% of max (on db scale)\n                                      2 = amplify only most distorted band\n                                      3 = method 1 and refine with method 2\n                                    */\n\n        int     noise_shaping_stop; /* 0 = stop at over=0, all scalefacs amplified or\n                                       a scalefac has reached max value\n                                       1 = stop when all scalefacs amplified or\n                                       a scalefac has reached max value\n                                       2 = stop when all scalefacs amplified\n                                     */\n\n\n        int     full_outer_loop; /* 0 = stop early after 0 distortion found. 1 = full search */\n\n        int     lowpassfreq;\n        int     highpassfreq;\n        int     samplerate_in; /* input_samp_rate in Hz. default=44.1 kHz     */\n        int     samplerate_out; /* output_samp_rate. */\n        int     channels_in; /* number of channels in the input data stream (PCM or decoded PCM) */\n        int     channels_out; /* number of channels in the output data stream (not used for decoding) */\n        int     mode_gr;     /* granules per frame */\n        int     force_ms;    /* force M/S mode.  requires mode=1            */\n\n        int     quant_comp;\n        int     quant_comp_short;\n\n        int     use_temporal_masking_effect;\n        int     use_safe_joint_stereo;\n\n        int     preset;\n\n        vbr_mode vbr;\n        int     vbr_avg_bitrate_kbps;\n        int     vbr_min_bitrate_index; /* min bitrate index */\n        int     vbr_max_bitrate_index; /* max bitrate index */\n        int     avg_bitrate;\n        int     enforce_min_bitrate; /* strictly enforce VBR_min_bitrate normaly, it will be violated for analog silence */\n\n        int     findReplayGain; /* find the RG value? default=0       */\n        int     findPeakSample;\n        int     decode_on_the_fly; /* decode on the fly? default=0                */\n        int     analysis;\n        int     disable_reservoir;\n        int     buffer_constraint;  /* enforce ISO spec as much as possible   */\n        int     free_format;\n        int     write_lame_tag; /* add Xing VBR tag?                           */\n\n        int     error_protection; /* use 2 bytes per frame for a CRC checksum. default=0 */\n        int     copyright;   /* mark as copyright. default=0           */\n        int     original;    /* mark as original. default=1            */\n        int     extension;   /* the MP3 'private extension' bit. Meaningless */\n        int     emphasis;    /* Input PCM is emphased PCM (for\n                                instance from one of the rarely\n                                emphased CDs), it is STRONGLY not\n                                recommended to use this, because\n                                psycho does not take it into account,\n                                and last but not least many decoders\n                                don't care about these bits          */\n\n\n        MPEG_mode mode;\n        short_block_t short_blocks;\n\n        float   interChRatio;\n        float   msfix;       /* Naoki's adjustment of Mid/Side maskings */\n        float   ATH_offset_db;/* add to ATH this many db            */\n        float   ATH_offset_factor;/* change ATH by this factor, derived from ATH_offset_db */\n        float   ATHcurve;    /* change ATH formula 4 shape           */\n        int     ATHtype;\n        int     ATHonly;     /* only use ATH                         */\n        int     ATHshort;    /* only use ATH for short blocks        */\n        int     noATH;       /* disable ATH                          */\n        \n        float   ATHfixpoint;\n\n        float   adjust_alto_db;\n        float   adjust_bass_db;\n        float   adjust_treble_db;\n        float   adjust_sfb21_db;\n\n        float   compression_ratio; /* sizeof(wav file)/sizeof(mp3 file)          */\n\n        /* lowpass and highpass filter control */\n        FLOAT   lowpass1, lowpass2; /* normalized frequency bounds of passband */\n        FLOAT   highpass1, highpass2; /* normalized frequency bounds of passband */\n\n        /* scale input by this amount before encoding at least not used for MP3 decoding */\n        FLOAT   pcm_transform[2][2];\n\n        FLOAT   minval;\n    } SessionConfig_t;\n\n\n    struct lame_internal_flags {\n\n  /********************************************************************\n   * internal variables NOT set by calling program, and should not be *\n   * modified by the calling program                                  *\n   ********************************************************************/\n\n        /*\n         * Some remarks to the Class_ID field:\n         * The Class ID is an Identifier for a pointer to this struct.\n         * It is very unlikely that a pointer to lame_global_flags has the same 32 bits\n         * in it's structure (large and other special properties, for instance prime).\n         *\n         * To test that the structure is right and initialized, use:\n         *     if ( gfc -> Class_ID == LAME_ID ) ...\n         * Other remark:\n         *     If you set a flag to 0 for uninit data and 1 for init data, the right test\n         *     should be \"if (flag == 1)\" and NOT \"if (flag)\". Unintended modification\n         *     of this element will be otherwise misinterpreted as an init.\n         */\n#  define  LAME_ID   0xFFF88E3B\n        unsigned long class_id;\n\n        int     lame_encode_frame_init;\n        int     iteration_init_init;\n        int     fill_buffer_resample_init;\n\n        SessionConfig_t cfg;\n\n        /* variables used by lame.c */\n        Bit_stream_struc bs;\n        III_side_info_t l3_side;\n\n        scalefac_struct scalefac_band;\n\n        PsyStateVar_t sv_psy; /* DATA FROM PSYMODEL.C */\n        PsyResult_t ov_psy;\n        EncStateVar_t sv_enc; /* DATA FROM ENCODER.C */\n        EncResult_t ov_enc;\n        QntStateVar_t sv_qnt; /* DATA FROM QUANTIZE.C */\n\n        RpgStateVar_t sv_rpg;\n        RpgResult_t ov_rpg;\n\n        /* optional ID3 tags, used in id3tag.c  */\n        struct id3tag_spec tag_spec;\n        uint16_t nMusicCRC;\n\n        uint16_t _unused;\n\n        /* CPU features */\n        struct {\n            unsigned int MMX:1; /* Pentium MMX, Pentium II...IV, K6, K6-2,\n                                   K6-III, Athlon */\n            unsigned int AMD_3DNow:1; /* K6-2, K6-III, Athlon      */\n            unsigned int SSE:1; /* Pentium III, Pentium 4    */\n            unsigned int SSE2:1; /* Pentium 4, K8             */\n            unsigned int _unused:28;\n        } CPU_features;\n\n\n        VBR_seek_info_t VBR_seek_table; /* used for Xing VBR header */\n\n        ATH_t  *ATH;         /* all ATH related stuff */\n\n        PsyConst_t *cd_psy;\n\n        /* used by the frame analyzer */\n        plotting_data *pinfo;\n        hip_t hip;\n\n        iteration_loop_t iteration_loop;\n\n        /* functions to replace with CPU feature optimized versions in takehiro.c */\n        int     (*choose_table) (const int *ix, const int *const end, int *const s);\n        void    (*fft_fht) (FLOAT *, int);\n        void    (*init_xrpow_core) (gr_info * const cod_info, FLOAT xrpow[576], int upper,\n                                    FLOAT * sum);\n\n        lame_report_function report_msg;\n        lame_report_function report_dbg;\n        lame_report_function report_err;\n    };\n\n#ifndef lame_internal_flags_defined\n#define lame_internal_flags_defined\n    typedef struct lame_internal_flags lame_internal_flags;\n#endif\n\n\n/***********************************************************************\n*\n*  Global Function Prototype Declarations\n*\n***********************************************************************/\n    void    freegfc(lame_internal_flags * const gfc);\n    void    free_id3tag(lame_internal_flags * const gfc);\n    extern int BitrateIndex(int, int, int);\n    extern int FindNearestBitrate(int, int, int);\n    extern int map2MP3Frequency(int freq);\n    extern int SmpFrqIndex(int, int *const);\n    extern int nearestBitrateFullIndex(uint16_t brate);\n    extern FLOAT ATHformula(SessionConfig_t const *cfg, FLOAT freq);\n    extern FLOAT freq2bark(FLOAT freq);\n    void    disable_FPE(void);\n\n/* log/log10 approximations */\n    extern void init_log_table(void);\n    extern float fast_log2(float x);//extern ieee754_float32_t fast_log2(ieee754_float32_t x);\n\n    int     isResamplingNecessary(SessionConfig_t const* cfg);\n\n    void    fill_buffer(lame_internal_flags * gfc,\n                        sample_t *const mfbuf[2],\n                        sample_t const *const in_buffer[2], int nsamples, int *n_in, int *n_out);\n\n/* same as lame_decode1 (look in lame.h), but returns\n   unclipped raw floating-point samples. It is declared\n   here, not in lame.h, because it returns LAME's\n   internal type sample_t. No more than 1152 samples\n   per channel are allowed. */\n    int     hip_decode1_unclipped(hip_t hip, unsigned char *mp3buf,\n                                   size_t len, sample_t pcm_l[], sample_t pcm_r[]);\n\n\n    extern int has_MMX(void);\n    extern int has_3DNow(void);\n    extern int has_SSE(void);\n    extern int has_SSE2(void);\n\n\n\n/***********************************************************************\n*\n*  Macros about Message Printing and Exit\n*\n***********************************************************************/\n\n    extern void lame_report_def(const char* format, va_list args);\n    extern void lame_report_fnc(lame_report_function print_f, const char *, ...);\n    extern void lame_errorf(const lame_internal_flags * gfc, const char *, ...);\n    extern void lame_debugf(const lame_internal_flags * gfc, const char *, ...);\n    extern void lame_msgf(const lame_internal_flags * gfc, const char *, ...);\n#define DEBUGF  lame_debugf\n#define ERRORF  lame_errorf\n#define MSGF    lame_msgf\n\n    int     is_lame_internal_flags_valid(const lame_internal_flags * gfp);\n    \n    extern void hip_set_pinfo(hip_t hip, plotting_data* pinfo);\n\n#ifdef __cplusplus\n}\n#endif\n#endif                       /* LAME_UTIL_H */\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/vbrquantize.c",
    "content": "/*\n *\tMP3 quantization\n *\n *\tCopyright (c) 1999-2000 Mark Taylor\n *\tCopyright (c) 2000-2012 Robert Hegemann\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\t See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n/* $Id: vbrquantize.c,v 1.141.2.1 2012/02/07 13:40:37 robert Exp $ */\n\n#ifdef HAVE_CONFIG_H\n#  include <config.h>\n#endif\n\n\n#include \"lame.h\"\n#include \"machine.h\"\n#include \"encoder.h\"\n#include \"util.h\"\n#include \"vbrquantize.h\"\n#include \"quantize_pvt.h\"\n\n\n\n\nstruct algo_s;\ntypedef struct algo_s algo_t;\n\ntypedef void (*alloc_sf_f) (const algo_t *, const int *, const int *, int);\ntypedef uint8_t (*find_sf_f) (const FLOAT *, const FLOAT *, FLOAT, unsigned int, uint8_t);\n\nstruct algo_s {\n    alloc_sf_f alloc;\n    find_sf_f  find;\n    const FLOAT *xr34orig;\n    lame_internal_flags *gfc;\n    gr_info *cod_info;\n    int     mingain_l;\n    int     mingain_s[3];\n};\n\n\n\n/*  Remarks on optimizing compilers:\n *\n *  the MSVC compiler may get into aliasing problems when accessing\n *  memory through the fi_union. declaring it volatile does the trick here\n *\n *  the calc_sfb_noise_* functions are not inlined because the intel compiler\n *  optimized executeables won't work as expected anymore\n */\n\n#ifdef _MSC_VER\n#  if _MSC_VER < 1400\n#  define VOLATILE volatile\n#  else\n#  define VOLATILE\n#  endif\n#else\n#  define VOLATILE\n#endif\n\ntypedef VOLATILE union {\n    float   f;\n    int     i;\n} fi_union;\n\n\n\n#ifdef TAKEHIRO_IEEE754_HACK\n#define DOUBLEX double\n#else\n#define DOUBLEX FLOAT\n#endif\n \n#define MAGIC_FLOAT_def (65536*(128))\n#define MAGIC_INT_def    0x4b000000\n\n#ifdef TAKEHIRO_IEEE754_HACK\n#else\n/*********************************************************************\n * XRPOW_FTOI is a macro to convert floats to ints.\n * if XRPOW_FTOI(x) = nearest_int(x), then QUANTFAC(x)=adj43asm[x]\n *                                         ROUNDFAC= -0.0946\n *\n * if XRPOW_FTOI(x) = floor(x), then QUANTFAC(x)=asj43[x]\n *                                   ROUNDFAC=0.4054\n *********************************************************************/\n#  define QUANTFAC(rx)  adj43[rx]\n#  define ROUNDFAC_def 0.4054f\n#  define XRPOW_FTOI(src,dest) ((dest) = (int)(src))\n#endif\n\nstatic int const MAGIC_INT = MAGIC_INT_def;\n#ifndef TAKEHIRO_IEEE754_HACK\nstatic DOUBLEX const ROUNDFAC = ROUNDFAC_def;\n#endif\nstatic DOUBLEX const MAGIC_FLOAT = MAGIC_FLOAT_def;\n\n\ninline static  float\nvec_max_c(const float * xr34, unsigned int bw)\n{\n    float   xfsf = 0;\n    unsigned int i = bw >> 2u;\n    unsigned int const remaining = (bw & 0x03u);\n\n    while (i-- > 0) {\n        if (xfsf < xr34[0]) {\n            xfsf = xr34[0];\n        }\n        if (xfsf < xr34[1]) {\n            xfsf = xr34[1];\n        }\n        if (xfsf < xr34[2]) {\n            xfsf = xr34[2];\n        }\n        if (xfsf < xr34[3]) {\n            xfsf = xr34[3];\n        }\n        xr34 += 4;\n    }\n    switch( remaining ) {\n    case 3: if (xfsf < xr34[2]) xfsf = xr34[2];\n    case 2: if (xfsf < xr34[1]) xfsf = xr34[1];\n    case 1: if (xfsf < xr34[0]) xfsf = xr34[0];\n    default: break;\n    }\n    return xfsf;\n}\n\n\ninline static  uint8_t\nfind_lowest_scalefac(const FLOAT xr34)\n{\n    uint8_t sf_ok = 255;\n    uint8_t sf = 128, delsf = 64;\n    uint8_t i;\n    FLOAT const ixmax_val = IXMAX_VAL;\n    for (i = 0; i < 8; ++i) {\n        FLOAT const xfsf = ipow20[sf] * xr34;\n        if (xfsf <= ixmax_val) {\n            sf_ok = sf;\n            sf -= delsf;\n        }\n        else {\n            sf += delsf;\n        }\n        delsf >>= 1;\n    }\n    return sf_ok;\n}\n\n\ninline static void\nk_34_4(DOUBLEX x[4], int l3[4])\n{\n#ifdef TAKEHIRO_IEEE754_HACK\n    fi_union fi[4];\n\n    assert(x[0] <= IXMAX_VAL && x[1] <= IXMAX_VAL && x[2] <= IXMAX_VAL && x[3] <= IXMAX_VAL);\n    x[0] += MAGIC_FLOAT;\n    fi[0].f = x[0];\n    x[1] += MAGIC_FLOAT;\n    fi[1].f = x[1];\n    x[2] += MAGIC_FLOAT;\n    fi[2].f = x[2];\n    x[3] += MAGIC_FLOAT;\n    fi[3].f = x[3];\n    fi[0].f = x[0] + adj43asm[fi[0].i - MAGIC_INT];\n    fi[1].f = x[1] + adj43asm[fi[1].i - MAGIC_INT];\n    fi[2].f = x[2] + adj43asm[fi[2].i - MAGIC_INT];\n    fi[3].f = x[3] + adj43asm[fi[3].i - MAGIC_INT];\n    l3[0] = fi[0].i - MAGIC_INT;\n    l3[1] = fi[1].i - MAGIC_INT;\n    l3[2] = fi[2].i - MAGIC_INT;\n    l3[3] = fi[3].i - MAGIC_INT;\n#else\n    assert(x[0] <= IXMAX_VAL && x[1] <= IXMAX_VAL && x[2] <= IXMAX_VAL && x[3] <= IXMAX_VAL);\n    XRPOW_FTOI(x[0], l3[0]);\n    XRPOW_FTOI(x[1], l3[1]);\n    XRPOW_FTOI(x[2], l3[2]);\n    XRPOW_FTOI(x[3], l3[3]);\n    x[0] += QUANTFAC(l3[0]);\n    x[1] += QUANTFAC(l3[1]);\n    x[2] += QUANTFAC(l3[2]);\n    x[3] += QUANTFAC(l3[3]);\n    XRPOW_FTOI(x[0], l3[0]);\n    XRPOW_FTOI(x[1], l3[1]);\n    XRPOW_FTOI(x[2], l3[2]);\n    XRPOW_FTOI(x[3], l3[3]);\n#endif\n}\n\n\n\n\n\n/*  do call the calc_sfb_noise_* functions only with sf values\n *  for which holds: sfpow34*xr34 <= IXMAX_VAL\n */\n\nstatic  FLOAT\ncalc_sfb_noise_x34(const FLOAT * xr, const FLOAT * xr34, unsigned int bw, uint8_t sf)\n{\n    DOUBLEX x[4];\n    int     l3[4];\n    const FLOAT sfpow = pow20[sf + Q_MAX2]; /*pow(2.0,sf/4.0); */\n    const FLOAT sfpow34 = ipow20[sf]; /*pow(sfpow,-3.0/4.0); */\n\n    FLOAT   xfsf = 0;\n    unsigned int i = bw >> 2u;\n    unsigned int const remaining = (bw & 0x03u);\n\n    while (i-- > 0) {\n        x[0] = sfpow34 * xr34[0];\n        x[1] = sfpow34 * xr34[1];\n        x[2] = sfpow34 * xr34[2];\n        x[3] = sfpow34 * xr34[3];\n\n        k_34_4(x, l3);\n\n        x[0] = fabsf(xr[0]) - sfpow * pow43[l3[0]];\n        x[1] = fabsf(xr[1]) - sfpow * pow43[l3[1]];\n        x[2] = fabsf(xr[2]) - sfpow * pow43[l3[2]];\n        x[3] = fabsf(xr[3]) - sfpow * pow43[l3[3]];\n        xfsf += (x[0] * x[0] + x[1] * x[1]) + (x[2] * x[2] + x[3] * x[3]);\n\n        xr += 4;\n        xr34 += 4;\n    }\n    if (remaining) {\n        x[0] = x[1] = x[2] = x[3] = 0;\n        switch( remaining ) {\n        case 3: x[2] = sfpow34 * xr34[2];\n        case 2: x[1] = sfpow34 * xr34[1];\n        case 1: x[0] = sfpow34 * xr34[0];\n        }\n\n        k_34_4(x, l3);\n        x[0] = x[1] = x[2] = x[3] = 0;\n\n        switch( remaining ) {\n        case 3: x[2] = fabsf(xr[2]) - sfpow * pow43[l3[2]];\n        case 2: x[1] = fabsf(xr[1]) - sfpow * pow43[l3[1]];\n        case 1: x[0] = fabsf(xr[0]) - sfpow * pow43[l3[0]];\n        }\n        xfsf += (x[0] * x[0] + x[1] * x[1]) + (x[2] * x[2] + x[3] * x[3]);\n    }\n    return xfsf;\n}\n\n\n\nstruct calc_noise_cache {\n    int     valid;\n    FLOAT   value;\n};\n\ntypedef struct calc_noise_cache calc_noise_cache_t;\n\n\nstatic  uint8_t\ntri_calc_sfb_noise_x34(const FLOAT * xr, const FLOAT * xr34, FLOAT l3_xmin, unsigned int bw,\n                       uint8_t sf, calc_noise_cache_t * did_it)\n{\n    if (did_it[sf].valid == 0) {\n        did_it[sf].valid = 1;\n        did_it[sf].value = calc_sfb_noise_x34(xr, xr34, bw, sf);\n    }\n    if (l3_xmin < did_it[sf].value) {\n        return 1;\n    }\n    if (sf < 255) {\n        uint8_t const sf_x = sf + 1;\n        if (did_it[sf_x].valid == 0) {\n            did_it[sf_x].valid = 1;\n            did_it[sf_x].value = calc_sfb_noise_x34(xr, xr34, bw, sf_x);\n        }\n        if (l3_xmin < did_it[sf_x].value) {\n            return 1;\n        }\n    }\n    if (sf > 0) {\n        uint8_t const sf_x = sf - 1;\n        if (did_it[sf_x].valid == 0) {\n            did_it[sf_x].valid = 1;\n            did_it[sf_x].value = calc_sfb_noise_x34(xr, xr34, bw, sf_x);\n        }\n        if (l3_xmin < did_it[sf_x].value) {\n            return 1;\n        }\n    }\n    return 0;\n}\n\n\n/**\n *  Robert Hegemann 2001-05-01\n *  calculates quantization step size determined by allowed masking\n */\nstatic int\ncalc_scalefac(FLOAT l3_xmin, int bw)\n{\n    FLOAT const c = 5.799142446; /* 10 * 10^(2/3) * log10(4/3) */\n    return 210 + (int) (c * log10f(l3_xmin / bw) - .5f);\n}\n\nstatic uint8_t\nguess_scalefac_x34(const FLOAT * xr, const FLOAT * xr34, FLOAT l3_xmin, unsigned int bw, uint8_t sf_min)\n{\n    int const guess = calc_scalefac(l3_xmin, bw);\n    if (guess < sf_min) return sf_min;\n    if (guess >= 255) return 255;\n    (void) xr;\n    (void) xr34;\n    return guess;\n}\n\n\n/* the find_scalefac* routines calculate\n * a quantization step size which would\n * introduce as much noise as is allowed.\n * The larger the step size the more\n * quantization noise we'll get. The\n * scalefactors are there to lower the\n * global step size, allowing limited\n * differences in quantization step sizes\n * per band (shaping the noise).\n */\n\nstatic  uint8_t\nfind_scalefac_x34(const FLOAT * xr, const FLOAT * xr34, FLOAT l3_xmin, unsigned int bw,\n                  uint8_t sf_min)\n{\n    calc_noise_cache_t did_it[256];\n    uint8_t sf = 128, sf_ok = 255, delsf = 128, seen_good_one = 0, i;\n    memset(did_it, 0, sizeof(did_it));\n    for (i = 0; i < 8; ++i) {\n        delsf >>= 1;\n        if (sf <= sf_min) {\n            sf += delsf;\n        }\n        else {\n            uint8_t const bad = tri_calc_sfb_noise_x34(xr, xr34, l3_xmin, bw, sf, did_it);\n            if (bad) {  /* distortion.  try a smaller scalefactor */\n                sf -= delsf;\n            }\n            else {\n                sf_ok = sf;\n                sf += delsf;\n                seen_good_one = 1;\n            }\n        }\n    }\n    /*  returning a scalefac without distortion, if possible\n     */\n    if (seen_good_one > 0) {\n        sf = sf_ok;\n    }\n    if (sf <= sf_min) {\n        sf = sf_min;\n    }\n    return sf;\n}\n\n\n\n/***********************************************************************\n *\n *      calc_short_block_vbr_sf()\n *      calc_long_block_vbr_sf()\n *\n *  Mark Taylor 2000-??-??\n *  Robert Hegemann 2000-10-25 made functions of it\n *\n ***********************************************************************/\n\n/* a variation for vbr-mtrh */\nstatic int\nblock_sf(algo_t * that, const FLOAT l3_xmin[SFBMAX], int vbrsf[SFBMAX], int vbrsfmin[SFBMAX])\n{\n    FLOAT   max_xr34;\n    const FLOAT *const xr = &that->cod_info->xr[0];\n    const FLOAT *const xr34_orig = &that->xr34orig[0];\n    const int *const width = &that->cod_info->width[0];\n    const char *const energy_above_cutoff = &that->cod_info->energy_above_cutoff[0];\n    unsigned int const max_nonzero_coeff = (unsigned int) that->cod_info->max_nonzero_coeff;\n    uint8_t maxsf = 0;\n    int     sfb = 0, m_o = -1;\n    unsigned int j = 0, i = 0;\n    int const psymax = that->cod_info->psymax;\n\n    assert(that->cod_info->max_nonzero_coeff >= 0);\n\n    that->mingain_l = 0;\n    that->mingain_s[0] = 0;\n    that->mingain_s[1] = 0;\n    that->mingain_s[2] = 0;\n    while (j <= max_nonzero_coeff) {\n        unsigned int const w = (unsigned int) width[sfb];\n        unsigned int const m = (unsigned int) (max_nonzero_coeff - j + 1);\n        unsigned int l = w;\n        uint8_t m1, m2;\n        if (l > m) {\n            l = m;\n        }\n        max_xr34 = vec_max_c(&xr34_orig[j], l);\n\n        m1 = find_lowest_scalefac(max_xr34);\n        vbrsfmin[sfb] = m1;\n        if (that->mingain_l < m1) {\n            that->mingain_l = m1;\n        }\n        if (that->mingain_s[i] < m1) {\n            that->mingain_s[i] = m1;\n        }\n        if (++i > 2) {\n            i = 0;\n        }\n        if (sfb < psymax && w > 2) { /* mpeg2.5 at 8 kHz doesn't use all scalefactors, unused have width 2 */\n            if (energy_above_cutoff[sfb]) {\n                m2 = that->find(&xr[j], &xr34_orig[j], l3_xmin[sfb], l, m1);\n#if 0\n                if (0) {\n                    /** Robert Hegemann 2007-09-29:\n                     *  It seems here is some more potential for speed improvements.\n                     *  Current find method does 11-18 quantization calculations.\n                     *  Using a \"good guess\" may help to reduce this amount.\n                     */\n                    uint8_t guess = calc_scalefac(l3_xmin[sfb], l);\n                    DEBUGF(that->gfc, \"sfb=%3d guess=%3d found=%3d diff=%3d\\n\", sfb, guess, m2,\n                           m2 - guess);\n                }\n#endif\n                if (maxsf < m2) {\n                    maxsf = m2;\n                }\n                if (m_o < m2 && m2 < 255) {\n                    m_o = m2;\n                }\n            }\n            else {\n                m2 = 255;\n                maxsf = 255;\n            }\n        }\n        else {\n            if (maxsf < m1) {\n                maxsf = m1;\n            }\n            m2 = maxsf;\n        }\n        vbrsf[sfb] = m2;\n        ++sfb;\n        j += w;        \n    }\n    for (; sfb < SFBMAX; ++sfb) {\n        vbrsf[sfb] = maxsf;\n        vbrsfmin[sfb] = 0;\n    }\n    if (m_o > -1) {\n        maxsf = m_o;\n        for (sfb = 0; sfb < SFBMAX; ++sfb) {\n            if (vbrsf[sfb] == 255) {\n                vbrsf[sfb] = m_o;\n            }\n        }\n    }\n    return maxsf;\n}\n\n\n\n/***********************************************************************\n *\n *  quantize xr34 based on scalefactors\n *\n *  block_xr34\n *\n *  Mark Taylor 2000-??-??\n *  Robert Hegemann 2000-10-20 made functions of them\n *\n ***********************************************************************/\n\nstatic void\nquantize_x34(const algo_t * that)\n{\n    DOUBLEX x[4];\n    const FLOAT *xr34_orig = that->xr34orig;\n    gr_info *const cod_info = that->cod_info;\n    int const ifqstep = (cod_info->scalefac_scale == 0) ? 2 : 4;\n    int    *l3 = cod_info->l3_enc;\n    unsigned int j = 0, sfb = 0;\n    unsigned int const max_nonzero_coeff = (unsigned int) cod_info->max_nonzero_coeff;\n\n    assert(cod_info->max_nonzero_coeff >= 0);\n    assert(cod_info->max_nonzero_coeff < 576);\n\n    while (j <= max_nonzero_coeff) {\n        int const s =\n            (cod_info->scalefac[sfb] + (cod_info->preflag ? pretab[sfb] : 0)) * ifqstep\n            + cod_info->subblock_gain[cod_info->window[sfb]] * 8;\n        uint8_t const sfac = (uint8_t) (cod_info->global_gain - s);\n        FLOAT const sfpow34 = ipow20[sfac];\n        unsigned int const w = (unsigned int) cod_info->width[sfb];\n        unsigned int const m = (unsigned int) (max_nonzero_coeff - j + 1);\n        unsigned int i, remaining;\n\n        assert((cod_info->global_gain - s) >= 0);\n        assert(cod_info->width[sfb] >= 0);\n        j += w;\n        ++sfb;\n        \n        i = (w <= m) ? w : m;\n        remaining = (i & 0x03u);\n        i >>= 2u;\n\n        while (i-- > 0) {\n            x[0] = sfpow34 * xr34_orig[0];\n            x[1] = sfpow34 * xr34_orig[1];\n            x[2] = sfpow34 * xr34_orig[2];\n            x[3] = sfpow34 * xr34_orig[3];\n\n            k_34_4(x, l3);\n\n            l3 += 4;\n            xr34_orig += 4;\n        }\n        if (remaining) {\n            int tmp_l3[4];\n            x[0] = x[1] = x[2] = x[3] = 0;\n            switch( remaining ) {\n            case 3: x[2] = sfpow34 * xr34_orig[2];\n            case 2: x[1] = sfpow34 * xr34_orig[1];\n            case 1: x[0] = sfpow34 * xr34_orig[0];\n            }\n\n            k_34_4(x, tmp_l3);\n\n            switch( remaining ) {\n            case 3: l3[2] = tmp_l3[2];\n            case 2: l3[1] = tmp_l3[1];\n            case 1: l3[0] = tmp_l3[0];\n            }\n\n            l3 += remaining;\n            xr34_orig += remaining;\n        }\n    }\n}\n\n\n\nstatic const uint8_t max_range_short[SBMAX_s * 3] = {\n    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,\n    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\n    0, 0, 0\n};\n\nstatic const uint8_t max_range_long[SBMAX_l] = {\n    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0\n};\n\nstatic const uint8_t max_range_long_lsf_pretab[SBMAX_l] = {\n    7, 7, 7, 7, 7, 7, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\n};\n\n\n\n/*\n    sfb=0..5  scalefac < 16\n    sfb>5     scalefac < 8\n\n    ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4;\n    ol_sf =  (cod_info->global_gain-210.0);\n    ol_sf -= 8*cod_info->subblock_gain[i];\n    ol_sf -= ifqstep*scalefac[gr][ch].s[sfb][i];\n*/\n\nstatic void\nset_subblock_gain(gr_info * cod_info, const int mingain_s[3], int sf[])\n{\n    const int maxrange1 = 15, maxrange2 = 7;\n    const int ifqstepShift = (cod_info->scalefac_scale == 0) ? 1 : 2;\n    int    *const sbg = cod_info->subblock_gain;\n    unsigned int const psymax = (unsigned int) cod_info->psymax;\n    unsigned int psydiv = 18;\n    int     sbg0, sbg1, sbg2;\n    unsigned int sfb, i;\n    int     min_sbg = 7;\n\n    if (psydiv > psymax) {\n        psydiv = psymax;\n    }\n    for (i = 0; i < 3; ++i) {\n        int     maxsf1 = 0, maxsf2 = 0, minsf = 1000;\n        /* see if we should use subblock gain */\n        for (sfb = i; sfb < psydiv; sfb += 3) { /* part 1 */\n            int const v = -sf[sfb];\n            if (maxsf1 < v) {\n                maxsf1 = v;\n            }\n            if (minsf > v) {\n                minsf = v;\n            }\n        }\n        for (; sfb < SFBMAX; sfb += 3) { /* part 2 */\n            int const v = -sf[sfb];\n            if (maxsf2 < v) {\n                maxsf2 = v;\n            }\n            if (minsf > v) {\n                minsf = v;\n            }\n        }\n\n        /* boost subblock gain as little as possible so we can\n         * reach maxsf1 with scalefactors\n         * 8*sbg >= maxsf1\n         */\n        {\n            int const m1 = maxsf1 - (maxrange1 << ifqstepShift);\n            int const m2 = maxsf2 - (maxrange2 << ifqstepShift);\n\n            maxsf1 = Max(m1, m2);\n        }\n        if (minsf > 0) {\n            sbg[i] = minsf >> 3;\n        }\n        else {\n            sbg[i] = 0;\n        }\n        if (maxsf1 > 0) {\n            int const m1 = sbg[i];\n            int const m2 = (maxsf1 + 7) >> 3;\n            sbg[i] = Max(m1, m2);\n        }\n        if (sbg[i] > 0 && mingain_s[i] > (cod_info->global_gain - sbg[i] * 8)) {\n            sbg[i] = (cod_info->global_gain - mingain_s[i]) >> 3;\n        }\n        if (sbg[i] > 7) {\n            sbg[i] = 7;\n        }\n        if (min_sbg > sbg[i]) {\n            min_sbg = sbg[i];\n        }\n    }\n    sbg0 = sbg[0] * 8;\n    sbg1 = sbg[1] * 8;\n    sbg2 = sbg[2] * 8;\n    for (sfb = 0; sfb < SFBMAX; sfb += 3) {\n        sf[sfb + 0] += sbg0;\n        sf[sfb + 1] += sbg1;\n        sf[sfb + 2] += sbg2;\n    }\n    if (min_sbg > 0) {\n        for (i = 0; i < 3; ++i) {\n            sbg[i] -= min_sbg;\n        }\n        cod_info->global_gain -= min_sbg * 8;\n    }\n}\n\n\n\n/*\n\t  ifqstep = ( cod_info->scalefac_scale == 0 ) ? 2 : 4;\n\t  ol_sf =  (cod_info->global_gain-210.0);\n\t  ol_sf -= ifqstep*scalefac[gr][ch].l[sfb];\n\t  if (cod_info->preflag && sfb>=11)\n\t  ol_sf -= ifqstep*pretab[sfb];\n*/\nstatic void\nset_scalefacs(gr_info * cod_info, const int *vbrsfmin, int sf[], const uint8_t * max_range)\n{\n    const int ifqstep = (cod_info->scalefac_scale == 0) ? 2 : 4;\n    const int ifqstepShift = (cod_info->scalefac_scale == 0) ? 1 : 2;\n    int    *const scalefac = cod_info->scalefac;\n    int const sfbmax = cod_info->sfbmax;\n    int     sfb;\n    int const *const sbg = cod_info->subblock_gain;\n    int const *const window = cod_info->window;\n    int const preflag = cod_info->preflag;\n\n    if (preflag) {\n        for (sfb = 11; sfb < sfbmax; ++sfb) {\n            sf[sfb] += pretab[sfb] * ifqstep;\n        }\n    }\n    for (sfb = 0; sfb < sfbmax; ++sfb) {\n        int const gain = cod_info->global_gain - (sbg[window[sfb]] * 8)\n            - ((preflag ? pretab[sfb] : 0) * ifqstep);\n\n        if (sf[sfb] < 0) {\n            int const m = gain - vbrsfmin[sfb];\n            /* ifqstep*scalefac >= -sf[sfb], so round UP */\n            scalefac[sfb] = (ifqstep - 1 - sf[sfb]) >> ifqstepShift;\n\n            if (scalefac[sfb] > max_range[sfb]) {\n                scalefac[sfb] = max_range[sfb];\n            }\n            if (scalefac[sfb] > 0 && (scalefac[sfb] << ifqstepShift) > m) {\n                scalefac[sfb] = m >> ifqstepShift;\n            }\n        }\n        else {\n            scalefac[sfb] = 0;\n        }\n    }\n    for (; sfb < SFBMAX; ++sfb) {\n        scalefac[sfb] = 0; /* sfb21 */\n    }\n}\n\n\n#ifndef NDEBUG\nstatic int\ncheckScalefactor(const gr_info * cod_info, const int vbrsfmin[SFBMAX])\n{\n    int const ifqstep = cod_info->scalefac_scale == 0 ? 2 : 4;\n    int     sfb;\n    for (sfb = 0; sfb < cod_info->psymax; ++sfb) {\n        const int s =\n            ((cod_info->scalefac[sfb] +\n              (cod_info->preflag ? pretab[sfb] : 0)) * ifqstep) +\n            cod_info->subblock_gain[cod_info->window[sfb]] * 8;\n\n        if ((cod_info->global_gain - s) < vbrsfmin[sfb]) {\n            /*\n               fprintf( stdout, \"sf %d\\n\", sfb );\n               fprintf( stdout, \"min %d\\n\", vbrsfmin[sfb] );\n               fprintf( stdout, \"ggain %d\\n\", cod_info->global_gain );\n               fprintf( stdout, \"scalefac %d\\n\", cod_info->scalefac[sfb] );\n               fprintf( stdout, \"pretab %d\\n\", (cod_info->preflag ? pretab[sfb] : 0) );\n               fprintf( stdout, \"scale %d\\n\", (cod_info->scalefac_scale + 1) );\n               fprintf( stdout, \"subgain %d\\n\", cod_info->subblock_gain[cod_info->window[sfb]] * 8 );\n               fflush( stdout );\n               exit(-1);\n             */\n            return 0;\n        }\n    }\n    return 1;\n}\n#endif\n\n\n/******************************************************************\n *\n *  short block scalefacs\n *\n ******************************************************************/\n\nstatic void\nshort_block_constrain(const algo_t * that, const int vbrsf[SFBMAX],\n                      const int vbrsfmin[SFBMAX], int vbrmax)\n{\n    gr_info *const cod_info = that->cod_info;\n    lame_internal_flags const *const gfc = that->gfc;\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    int const maxminsfb = that->mingain_l;\n    int     mover, maxover0 = 0, maxover1 = 0, delta = 0;\n    int     v, v0, v1;\n    int     sfb;\n    int const psymax = cod_info->psymax;\n\n    for (sfb = 0; sfb < psymax; ++sfb) {\n        assert(vbrsf[sfb] >= vbrsfmin[sfb]);\n        v = vbrmax - vbrsf[sfb];\n        if (delta < v) {\n            delta = v;\n        }\n        v0 = v - (4 * 14 + 2 * max_range_short[sfb]);\n        v1 = v - (4 * 14 + 4 * max_range_short[sfb]);\n        if (maxover0 < v0) {\n            maxover0 = v0;\n        }\n        if (maxover1 < v1) {\n            maxover1 = v1;\n        }\n    }\n    if (cfg->noise_shaping == 2) {\n        /* allow scalefac_scale=1 */\n        mover = Min(maxover0, maxover1);\n    }\n    else {\n        mover = maxover0;\n    }\n    if (delta > mover) {\n        delta = mover;\n    }\n    vbrmax -= delta;\n    maxover0 -= mover;\n    maxover1 -= mover;\n\n    if (maxover0 == 0) {\n        cod_info->scalefac_scale = 0;\n    }\n    else if (maxover1 == 0) {\n        cod_info->scalefac_scale = 1;\n    }\n    if (vbrmax < maxminsfb) {\n        vbrmax = maxminsfb;\n    }\n    cod_info->global_gain = vbrmax;\n\n    if (cod_info->global_gain < 0) {\n        cod_info->global_gain = 0;\n    }\n    else if (cod_info->global_gain > 255) {\n        cod_info->global_gain = 255;\n    }\n    {\n        int     sf_temp[SFBMAX];\n        for (sfb = 0; sfb < SFBMAX; ++sfb) {\n            sf_temp[sfb] = vbrsf[sfb] - vbrmax;\n        }\n        set_subblock_gain(cod_info, &that->mingain_s[0], sf_temp);\n        set_scalefacs(cod_info, vbrsfmin, sf_temp, max_range_short);\n    }\n    assert(checkScalefactor(cod_info, vbrsfmin));\n}\n\n\n\n/******************************************************************\n *\n *  long block scalefacs\n *\n ******************************************************************/\n\nstatic void\nlong_block_constrain(const algo_t * that, const int vbrsf[SFBMAX], const int vbrsfmin[SFBMAX],\n                     int vbrmax)\n{\n    gr_info *const cod_info = that->cod_info;\n    lame_internal_flags const *const gfc = that->gfc;\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    uint8_t const *max_rangep;\n    int const maxminsfb = that->mingain_l;\n    int     sfb;\n    int     maxover0, maxover1, maxover0p, maxover1p, mover, delta = 0;\n    int     v, v0, v1, v0p, v1p, vm0p = 1, vm1p = 1;\n    int const psymax = cod_info->psymax;\n\n    max_rangep = cfg->mode_gr == 2 ? max_range_long : max_range_long_lsf_pretab;\n\n    maxover0 = 0;\n    maxover1 = 0;\n    maxover0p = 0;      /* pretab */\n    maxover1p = 0;      /* pretab */\n\n    for (sfb = 0; sfb < psymax; ++sfb) {\n        assert(vbrsf[sfb] >= vbrsfmin[sfb]);\n        v = vbrmax - vbrsf[sfb];\n        if (delta < v) {\n            delta = v;\n        }\n        v0 = v - 2 * max_range_long[sfb];\n        v1 = v - 4 * max_range_long[sfb];\n        v0p = v - 2 * (max_rangep[sfb] + pretab[sfb]);\n        v1p = v - 4 * (max_rangep[sfb] + pretab[sfb]);\n        if (maxover0 < v0) {\n            maxover0 = v0;\n        }\n        if (maxover1 < v1) {\n            maxover1 = v1;\n        }\n        if (maxover0p < v0p) {\n            maxover0p = v0p;\n        }\n        if (maxover1p < v1p) {\n            maxover1p = v1p;\n        }\n    }\n    if (vm0p == 1) {\n        int     gain = vbrmax - maxover0p;\n        if (gain < maxminsfb) {\n            gain = maxminsfb;\n        }\n        for (sfb = 0; sfb < psymax; ++sfb) {\n            int const a = (gain - vbrsfmin[sfb]) - 2 * pretab[sfb];\n            if (a <= 0) {\n                vm0p = 0;\n                vm1p = 0;\n                break;\n            }\n        }\n    }\n    if (vm1p == 1) {\n        int     gain = vbrmax - maxover1p;\n        if (gain < maxminsfb) {\n            gain = maxminsfb;\n        }\n        for (sfb = 0; sfb < psymax; ++sfb) {\n            int const b = (gain - vbrsfmin[sfb]) - 4 * pretab[sfb];\n            if (b <= 0) {\n                vm1p = 0;\n                break;\n            }\n        }\n    }\n    if (vm0p == 0) {\n        maxover0p = maxover0;\n    }\n    if (vm1p == 0) {\n        maxover1p = maxover1;\n    }\n    if (cfg->noise_shaping != 2) {\n        maxover1 = maxover0;\n        maxover1p = maxover0p;\n    }\n    mover = Min(maxover0, maxover0p);\n    mover = Min(mover, maxover1);\n    mover = Min(mover, maxover1p);\n\n    if (delta > mover) {\n        delta = mover;\n    }\n    vbrmax -= delta;\n    if (vbrmax < maxminsfb) {\n        vbrmax = maxminsfb;\n    }\n    maxover0 -= mover;\n    maxover0p -= mover;\n    maxover1 -= mover;\n    maxover1p -= mover;\n\n    if (maxover0 == 0) {\n        cod_info->scalefac_scale = 0;\n        cod_info->preflag = 0;\n        max_rangep = max_range_long;\n    }\n    else if (maxover0p == 0) {\n        cod_info->scalefac_scale = 0;\n        cod_info->preflag = 1;\n    }\n    else if (maxover1 == 0) {\n        cod_info->scalefac_scale = 1;\n        cod_info->preflag = 0;\n        max_rangep = max_range_long;\n    }\n    else if (maxover1p == 0) {\n        cod_info->scalefac_scale = 1;\n        cod_info->preflag = 1;\n    }\n    else {\n        assert(0);      /* this should not happen */\n    }\n    cod_info->global_gain = vbrmax;\n    if (cod_info->global_gain < 0) {\n        cod_info->global_gain = 0;\n    }\n    else if (cod_info->global_gain > 255) {\n        cod_info->global_gain = 255;\n    }\n    {\n        int     sf_temp[SFBMAX];\n        for (sfb = 0; sfb < SFBMAX; ++sfb) {\n            sf_temp[sfb] = vbrsf[sfb] - vbrmax;\n        }\n        set_scalefacs(cod_info, vbrsfmin, sf_temp, max_rangep);\n    }\n    assert(checkScalefactor(cod_info, vbrsfmin));\n}\n\n\n\nstatic void\nbitcount(const algo_t * that)\n{\n    int     rc = scale_bitcount(that->gfc, that->cod_info);\n\n    if (rc == 0) {\n        return;\n    }\n    /*  this should not happen due to the way the scalefactors are selected  */\n    ERRORF(that->gfc, \"INTERNAL ERROR IN VBR NEW CODE (986), please send bug report\\n\");\n    exit(-1);\n}\n\n\n\nstatic int\nquantizeAndCountBits(const algo_t * that)\n{\n    quantize_x34(that);\n    that->cod_info->part2_3_length = noquant_count_bits(that->gfc, that->cod_info, 0);\n    return that->cod_info->part2_3_length;\n}\n\n\n\n\n\nstatic int\ntryGlobalStepsize(const algo_t * that, const int sfwork[SFBMAX],\n                  const int vbrsfmin[SFBMAX], int delta)\n{\n    FLOAT const xrpow_max = that->cod_info->xrpow_max;\n    int     sftemp[SFBMAX], i, nbits;\n    int     gain, vbrmax = 0;\n    for (i = 0; i < SFBMAX; ++i) {\n        gain = sfwork[i] + delta;\n        if (gain < vbrsfmin[i]) {\n            gain = vbrsfmin[i];\n        }\n        if (gain > 255) {\n            gain = 255;\n        }\n        if (vbrmax < gain) {\n            vbrmax = gain;\n        }\n        sftemp[i] = gain;\n    }\n    that->alloc(that, sftemp, vbrsfmin, vbrmax);\n    bitcount(that);\n    nbits = quantizeAndCountBits(that);\n    that->cod_info->xrpow_max = xrpow_max;\n    return nbits;\n}\n\n\n\nstatic void\nsearchGlobalStepsizeMax(const algo_t * that, const int sfwork[SFBMAX],\n                        const int vbrsfmin[SFBMAX], int target)\n{\n    gr_info const *const cod_info = that->cod_info;\n    const int gain = cod_info->global_gain;\n    int     curr = gain;\n    int     gain_ok = 1024;\n    int     nbits = LARGE_BITS;\n    int     l = gain, r = 512;\n\n    assert(gain >= 0);\n    while (l <= r) {\n        curr = (l + r) >> 1;\n        nbits = tryGlobalStepsize(that, sfwork, vbrsfmin, curr - gain);\n        if (nbits == 0 || (nbits + cod_info->part2_length) < target) {\n            r = curr - 1;\n            gain_ok = curr;\n        }\n        else {\n            l = curr + 1;\n            if (gain_ok == 1024) {\n                gain_ok = curr;\n            }\n        }\n    }\n    if (gain_ok != curr) {\n        curr = gain_ok;\n        nbits = tryGlobalStepsize(that, sfwork, vbrsfmin, curr - gain);\n    }\n}\n\n\n\nstatic int\nsfDepth(const int sfwork[SFBMAX])\n{\n    int     m = 0;\n    unsigned int i, j;\n    for (j = SFBMAX, i = 0; j > 0; --j, ++i) {\n        int const di = 255 - sfwork[i];\n        if (m < di) {\n            m = di;\n        }\n        assert(sfwork[i] >= 0);\n        assert(sfwork[i] <= 255);\n    }\n    assert(m >= 0);\n    assert(m <= 255);\n    return m;\n}\n\n\nstatic void\ncutDistribution(const int sfwork[SFBMAX], int sf_out[SFBMAX], int cut)\n{\n    unsigned int i, j;\n    for (j = SFBMAX, i = 0; j > 0; --j, ++i) {\n        int const x = sfwork[i];\n        sf_out[i] = x < cut ? x : cut;\n    }\n}\n\n\nstatic int\nflattenDistribution(const int sfwork[SFBMAX], int sf_out[SFBMAX], int dm, int k, int p)\n{\n    unsigned int i, j;\n    int     x, sfmax = 0;\n    if (dm > 0) {\n        for (j = SFBMAX, i = 0; j > 0; --j, ++i) {\n            int const di = p - sfwork[i];\n            x = sfwork[i] + (k * di) / dm;\n            if (x < 0) {\n                x = 0;\n            }\n            else {\n                if (x > 255) {\n                    x = 255;\n                }\n            }\n            sf_out[i] = x;\n            if (sfmax < x) {\n                sfmax = x;\n            }\n        }\n    }\n    else {\n        for (j = SFBMAX, i = 0; j > 0u; --j, ++i) {\n            x = sfwork[i];\n            sf_out[i] = x;\n            if (sfmax < x) {\n                sfmax = x;\n            }\n        }\n    }\n    return sfmax;\n}\n\n\nstatic int\ntryThatOne(algo_t const* that, const int sftemp[SFBMAX], const int vbrsfmin[SFBMAX], int vbrmax)\n{\n    FLOAT const xrpow_max = that->cod_info->xrpow_max;\n    int     nbits = LARGE_BITS;\n    that->alloc(that, sftemp, vbrsfmin, vbrmax);\n    bitcount(that);\n    nbits = quantizeAndCountBits(that);\n    nbits += that->cod_info->part2_length;\n    that->cod_info->xrpow_max = xrpow_max;\n    return nbits;\n}\n\n\nstatic void\noutOfBitsStrategy(algo_t const* that, const int sfwork[SFBMAX], const int vbrsfmin[SFBMAX], int target)\n{\n    int     wrk[SFBMAX];\n    int const dm = sfDepth(sfwork);\n    int const p = that->cod_info->global_gain;\n    int     nbits;\n\n    /* PART 1 */\n    {\n        int     bi = dm / 2;\n        int     bi_ok = -1;\n        int     bu = 0;\n        int     bo = dm;\n        for (;;) {\n            int const sfmax = flattenDistribution(sfwork, wrk, dm, bi, p);\n            nbits = tryThatOne(that, wrk, vbrsfmin, sfmax);\n            if (nbits <= target) {\n                bi_ok = bi;\n                bo = bi - 1;\n            }\n            else {\n                bu = bi + 1;\n            }\n            if (bu <= bo) {\n                bi = (bu + bo) / 2;\n            }\n            else {\n                break;\n            }\n        }\n        if (bi_ok >= 0) {\n            if (bi != bi_ok) {\n                int const sfmax = flattenDistribution(sfwork, wrk, dm, bi_ok, p);\n                nbits = tryThatOne(that, wrk, vbrsfmin, sfmax);\n            }\n            return;\n        }\n    }\n\n    /* PART 2: */\n    {\n        int     bi = (255 + p) / 2;\n        int     bi_ok = -1;\n        int     bu = p;\n        int     bo = 255;\n        for (;;) {\n            int const sfmax = flattenDistribution(sfwork, wrk, dm, dm, bi);\n            nbits = tryThatOne(that, wrk, vbrsfmin, sfmax);\n            if (nbits <= target) {\n                bi_ok = bi;\n                bo = bi - 1;\n            }\n            else {\n                bu = bi + 1;\n            }\n            if (bu <= bo) {\n                bi = (bu + bo) / 2;\n            }\n            else {\n                break;\n            }\n        }\n        if (bi_ok >= 0) {\n            if (bi != bi_ok) {\n                int const sfmax = flattenDistribution(sfwork, wrk, dm, dm, bi_ok);\n                nbits = tryThatOne(that, wrk, vbrsfmin, sfmax);\n            }\n            return;\n        }\n    }\n\n    /* fall back to old code, likely to be never called */\n    searchGlobalStepsizeMax(that, wrk, vbrsfmin, target);\n}\n\n\nstatic int\nreduce_bit_usage(lame_internal_flags * gfc, int gr, int ch\n#if 0\n                 , const FLOAT xr34orig[576], const FLOAT l3_xmin[SFBMAX], int maxbits\n#endif\n    )\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    gr_info *const cod_info = &gfc->l3_side.tt[gr][ch];\n    /*  try some better scalefac storage\n     */\n    best_scalefac_store(gfc, gr, ch, &gfc->l3_side);\n\n    /*  best huffman_divide may save some bits too\n     */\n    if (cfg->use_best_huffman == 1)\n        best_huffman_divide(gfc, cod_info);\n    return cod_info->part2_3_length + cod_info->part2_length;\n}\n\n\n\n\nint\nVBR_encode_frame(lame_internal_flags * gfc, const FLOAT xr34orig[2][2][576],\n                 const FLOAT l3_xmin[2][2][SFBMAX], const int max_bits[2][2])\n{\n    SessionConfig_t const *const cfg = &gfc->cfg;\n    int     sfwork_[2][2][SFBMAX];\n    int     vbrsfmin_[2][2][SFBMAX];\n    algo_t  that_[2][2];\n    int const ngr = cfg->mode_gr;\n    int const nch = cfg->channels_out;\n    int     max_nbits_ch[2][2] = {{0, 0}, {0 ,0}};\n    int     max_nbits_gr[2] = {0, 0};\n    int     max_nbits_fr = 0;\n    int     use_nbits_ch[2][2] = {{MAX_BITS_PER_CHANNEL+1, MAX_BITS_PER_CHANNEL+1}\n                                 ,{MAX_BITS_PER_CHANNEL+1, MAX_BITS_PER_CHANNEL+1}};\n    int     use_nbits_gr[2] = { MAX_BITS_PER_GRANULE+1, MAX_BITS_PER_GRANULE+1 };\n    int     use_nbits_fr = MAX_BITS_PER_GRANULE+MAX_BITS_PER_GRANULE;\n    int     gr, ch;\n    int     ok, sum_fr;\n\n    /* set up some encoding parameters\n     */\n    for (gr = 0; gr < ngr; ++gr) {\n        max_nbits_gr[gr] = 0;\n        for (ch = 0; ch < nch; ++ch) {\n            max_nbits_ch[gr][ch] = max_bits[gr][ch];\n            use_nbits_ch[gr][ch] = 0;\n            max_nbits_gr[gr] += max_bits[gr][ch];\n            max_nbits_fr += max_bits[gr][ch];\n            that_[gr][ch].find = (cfg->full_outer_loop < 0) ? guess_scalefac_x34 : find_scalefac_x34;\n            that_[gr][ch].gfc = gfc;\n            that_[gr][ch].cod_info = &gfc->l3_side.tt[gr][ch];\n            that_[gr][ch].xr34orig = xr34orig[gr][ch];\n            if (that_[gr][ch].cod_info->block_type == SHORT_TYPE) {\n                that_[gr][ch].alloc = short_block_constrain;\n            }\n            else {\n                that_[gr][ch].alloc = long_block_constrain;\n            }\n        }               /* for ch */\n    }\n    /* searches scalefactors\n     */\n    for (gr = 0; gr < ngr; ++gr) {\n        for (ch = 0; ch < nch; ++ch) {\n            if (max_bits[gr][ch] > 0) {\n                algo_t *that = &that_[gr][ch];\n                int    *sfwork = sfwork_[gr][ch];\n                int    *vbrsfmin = vbrsfmin_[gr][ch];\n                int     vbrmax;\n\n                vbrmax = block_sf(that, l3_xmin[gr][ch], sfwork, vbrsfmin);\n                that->alloc(that, sfwork, vbrsfmin, vbrmax);\n                bitcount(that);\n            }\n            else {\n                /*  xr contains no energy \n                 *  l3_enc, our encoding data, will be quantized to zero\n                 *  continue with next channel\n                 */\n            }\n        }               /* for ch */\n    }\n    /* encode 'as is'\n     */\n    use_nbits_fr = 0;\n    for (gr = 0; gr < ngr; ++gr) {\n        use_nbits_gr[gr] = 0;\n        for (ch = 0; ch < nch; ++ch) {\n            algo_t const *that = &that_[gr][ch];\n            if (max_bits[gr][ch] > 0) {\n                memset(&that->cod_info->l3_enc[0], 0, sizeof(that->cod_info->l3_enc));\n                (void) quantizeAndCountBits(that);\n            }\n            else {\n                /*  xr contains no energy \n                 *  l3_enc, our encoding data, will be quantized to zero\n                 *  continue with next channel\n                 */\n            }\n            use_nbits_ch[gr][ch] = reduce_bit_usage(gfc, gr, ch);\n            use_nbits_gr[gr] += use_nbits_ch[gr][ch];\n        }               /* for ch */\n        use_nbits_fr += use_nbits_gr[gr];\n    }\n\n    /* check bit constrains\n     */\n    if (use_nbits_fr <= max_nbits_fr) {\n        ok = 1;\n        for (gr = 0; gr < ngr; ++gr) {\n            if (use_nbits_gr[gr] > MAX_BITS_PER_GRANULE) {\n                /* violates the rule that every granule has to use no more\n                 * bits than MAX_BITS_PER_GRANULE\n                 */\n                ok = 0;\n            }\n            for (ch = 0; ch < nch; ++ch) {\n                if (use_nbits_ch[gr][ch] > MAX_BITS_PER_CHANNEL) {\n                    /* violates the rule that every gr_ch has to use no more\n                     * bits than MAX_BITS_PER_CHANNEL\n                     *\n                     * This isn't explicitly stated in the ISO docs, but the\n                     * part2_3_length field has only 12 bits, that makes it\n                     * up to a maximum size of 4095 bits!!!\n                     */\n                    ok = 0;\n                }\n            }\n        }\n        if (ok) {\n            return use_nbits_fr;\n        }\n    }\n    \n    /* OK, we are in trouble and have to define how many bits are\n     * to be used for each granule\n     */\n    {\n        ok = 1;\n        sum_fr = 0;\n\n        for (gr = 0; gr < ngr; ++gr) {\n            max_nbits_gr[gr] = 0;\n            for (ch = 0; ch < nch; ++ch) {\n                if (use_nbits_ch[gr][ch] > MAX_BITS_PER_CHANNEL) {\n                    max_nbits_ch[gr][ch] = MAX_BITS_PER_CHANNEL;\n                }\n                else {\n                    max_nbits_ch[gr][ch] = use_nbits_ch[gr][ch];\n                }\n                max_nbits_gr[gr] += max_nbits_ch[gr][ch];\n            }\n            if (max_nbits_gr[gr] > MAX_BITS_PER_GRANULE) {\n                float   f[2] = {0.0f, 0.0f}, s = 0.0f;\n                for (ch = 0; ch < nch; ++ch) {\n                    if (max_nbits_ch[gr][ch] > 0) {\n                        f[ch] = sqrt(sqrt(max_nbits_ch[gr][ch]));\n                        s += f[ch];\n                    }\n                    else {\n                        f[ch] = 0;\n                    }\n                }\n                for (ch = 0; ch < nch; ++ch) {\n                    if (s > 0) {\n                        max_nbits_ch[gr][ch] = MAX_BITS_PER_GRANULE * f[ch] / s;\n                    }\n                    else {\n                        max_nbits_ch[gr][ch] = 0;\n                    }\n                }\n                if (nch > 1) {\n                    if (max_nbits_ch[gr][0] > use_nbits_ch[gr][0] + 32) {\n                        max_nbits_ch[gr][1] += max_nbits_ch[gr][0];\n                        max_nbits_ch[gr][1] -= use_nbits_ch[gr][0] + 32;\n                        max_nbits_ch[gr][0] = use_nbits_ch[gr][0] + 32;\n                    }\n                    if (max_nbits_ch[gr][1] > use_nbits_ch[gr][1] + 32) {\n                        max_nbits_ch[gr][0] += max_nbits_ch[gr][1];\n                        max_nbits_ch[gr][0] -= use_nbits_ch[gr][1] + 32;\n                        max_nbits_ch[gr][1] = use_nbits_ch[gr][1] + 32;\n                    }\n                    if (max_nbits_ch[gr][0] > MAX_BITS_PER_CHANNEL) {\n                        max_nbits_ch[gr][0] = MAX_BITS_PER_CHANNEL;\n                    }\n                    if (max_nbits_ch[gr][1] > MAX_BITS_PER_CHANNEL) {\n                        max_nbits_ch[gr][1] = MAX_BITS_PER_CHANNEL;\n                    }\n                }\n                max_nbits_gr[gr] = 0;\n                for (ch = 0; ch < nch; ++ch) {\n                    max_nbits_gr[gr] += max_nbits_ch[gr][ch];\n                }\n            }\n            sum_fr += max_nbits_gr[gr];\n        }\n        if (sum_fr > max_nbits_fr) {\n            {\n                float   f[2] = {0.0f, 0.0f}, s = 0.0f;\n                for (gr = 0; gr < ngr; ++gr) {\n                    if (max_nbits_gr[gr] > 0) {\n                        f[gr] = sqrt(max_nbits_gr[gr]);\n                        s += f[gr];\n                    }\n                    else {\n                        f[gr] = 0;\n                    }\n                }\n                for (gr = 0; gr < ngr; ++gr) {\n                    if (s > 0) {\n                        max_nbits_gr[gr] = max_nbits_fr * f[gr] / s;\n                    }\n                    else {\n                        max_nbits_gr[gr] = 0;\n                    }\n                }\n            }\n            if (ngr > 1) {\n                if (max_nbits_gr[0] > use_nbits_gr[0] + 125) {\n                    max_nbits_gr[1] += max_nbits_gr[0];\n                    max_nbits_gr[1] -= use_nbits_gr[0] + 125;\n                    max_nbits_gr[0] = use_nbits_gr[0] + 125;\n                }\n                if (max_nbits_gr[1] > use_nbits_gr[1] + 125) {\n                    max_nbits_gr[0] += max_nbits_gr[1];\n                    max_nbits_gr[0] -= use_nbits_gr[1] + 125;\n                    max_nbits_gr[1] = use_nbits_gr[1] + 125;\n                }\n                for (gr = 0; gr < ngr; ++gr) {\n                    if (max_nbits_gr[gr] > MAX_BITS_PER_GRANULE) {\n                        max_nbits_gr[gr] = MAX_BITS_PER_GRANULE;\n                    }\n                }\n            }\n            for (gr = 0; gr < ngr; ++gr) {\n                float   f[2] = {0.0f, 0.0f}, s = 0.0f;\n                for (ch = 0; ch < nch; ++ch) {\n                    if (max_nbits_ch[gr][ch] > 0) {\n                        f[ch] = sqrt(max_nbits_ch[gr][ch]);\n                        s += f[ch];\n                    }\n                    else {\n                        f[ch] = 0;\n                    }\n                }\n                for (ch = 0; ch < nch; ++ch) {\n                    if (s > 0) {\n                        max_nbits_ch[gr][ch] = max_nbits_gr[gr] * f[ch] / s;\n                    }\n                    else {\n                        max_nbits_ch[gr][ch] = 0;\n                    }\n                }\n                if (nch > 1) {\n                    if (max_nbits_ch[gr][0] > use_nbits_ch[gr][0] + 32) {\n                        max_nbits_ch[gr][1] += max_nbits_ch[gr][0];\n                        max_nbits_ch[gr][1] -= use_nbits_ch[gr][0] + 32;\n                        max_nbits_ch[gr][0] = use_nbits_ch[gr][0] + 32;\n                    }\n                    if (max_nbits_ch[gr][1] > use_nbits_ch[gr][1] + 32) {\n                        max_nbits_ch[gr][0] += max_nbits_ch[gr][1];\n                        max_nbits_ch[gr][0] -= use_nbits_ch[gr][1] + 32;\n                        max_nbits_ch[gr][1] = use_nbits_ch[gr][1] + 32;\n                    }\n                    for (ch = 0; ch < nch; ++ch) {\n                        if (max_nbits_ch[gr][ch] > MAX_BITS_PER_CHANNEL) {\n                            max_nbits_ch[gr][ch] = MAX_BITS_PER_CHANNEL;\n                        }\n                    }\n                }\n            }\n        }\n        /* sanity check */\n        sum_fr = 0;\n        for (gr = 0; gr < ngr; ++gr) {\n            int     sum_gr = 0;\n            for (ch = 0; ch < nch; ++ch) {\n                sum_gr += max_nbits_ch[gr][ch];\n                if (max_nbits_ch[gr][ch] > MAX_BITS_PER_CHANNEL) {\n                    ok = 0;\n                }\n            }\n            sum_fr += sum_gr;\n            if (sum_gr > MAX_BITS_PER_GRANULE) {\n                ok = 0;\n            }\n        }\n        if (sum_fr > max_nbits_fr) {\n            ok = 0;\n        }\n        if (!ok) {\n            /* we must have done something wrong, fallback to 'on_pe' based constrain */\n            for (gr = 0; gr < ngr; ++gr) {\n                for (ch = 0; ch < nch; ++ch) {\n                    max_nbits_ch[gr][ch] = max_bits[gr][ch];\n                }\n            }\n        }\n    }\n\n    /* we already called the 'best_scalefac_store' function, so we need to reset some\n     * variables before we can do it again.\n     */\n    for (ch = 0; ch < nch; ++ch) {\n        gfc->l3_side.scfsi[ch][0] = 0;\n        gfc->l3_side.scfsi[ch][1] = 0;\n        gfc->l3_side.scfsi[ch][2] = 0;\n        gfc->l3_side.scfsi[ch][3] = 0;\n    }\n    for (gr = 0; gr < ngr; ++gr) {\n        for (ch = 0; ch < nch; ++ch) {\n            gfc->l3_side.tt[gr][ch].scalefac_compress = 0;\n        }\n    }\n\n    /* alter our encoded data, until it fits into the target bitrate\n     */\n    use_nbits_fr = 0;\n    for (gr = 0; gr < ngr; ++gr) {\n        use_nbits_gr[gr] = 0;\n        for (ch = 0; ch < nch; ++ch) {\n            algo_t const *that = &that_[gr][ch];\n            use_nbits_ch[gr][ch] = 0;\n            if (max_bits[gr][ch] > 0) {\n                int    *sfwork = sfwork_[gr][ch];\n                int const *vbrsfmin = vbrsfmin_[gr][ch];\n                cutDistribution(sfwork, sfwork, that->cod_info->global_gain);\n                outOfBitsStrategy(that, sfwork, vbrsfmin, max_nbits_ch[gr][ch]);\n            }\n            use_nbits_ch[gr][ch] = reduce_bit_usage(gfc, gr, ch);\n            assert(use_nbits_ch[gr][ch] <= max_nbits_ch[gr][ch]);\n            use_nbits_gr[gr] += use_nbits_ch[gr][ch];\n        }               /* for ch */\n        use_nbits_fr += use_nbits_gr[gr];\n    }\n\n    /* check bit constrains, but it should always be ok, iff there are no bugs ;-)\n     */\n    if (use_nbits_fr <= max_nbits_fr) {\n        return use_nbits_fr;\n    }\n\n    ERRORF(gfc, \"INTERNAL ERROR IN VBR NEW CODE (1313), please send bug report\\n\"\n           \"maxbits=%d usedbits=%d\\n\", max_nbits_fr, use_nbits_fr);\n    exit(-1);\n}\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/vbrquantize.h",
    "content": "/*\n * MP3 VBR quantization\n *\n * Copyright (c) 1999 Mark Taylor\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\t See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n#ifndef LAME_VBRQUANTIZE_H\n#define LAME_VBRQUANTIZE_H\n\nint     VBR_encode_frame(lame_internal_flags * gfc, const FLOAT xr34orig[2][2][576],\n                         const FLOAT l3_xmin[2][2][SFBMAX], const int maxbits[2][2]);\n\n#endif /* LAME_VBRQUANTIZE_H */\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/version.c",
    "content": "/*\n *      Version numbering for LAME.\n *\n *      Copyright (c) 1999 A.L. Faber\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n/*!\n  \\file   version.c\n  \\brief  Version numbering for LAME.\n\n  Contains functions which describe the version of LAME.\n\n  \\author A.L. Faber\n  \\version \\$Id: version.c,v 1.32.2.2 2011/11/18 09:18:28 robert Exp $\n  \\ingroup libmp3lame\n*/\n\n\n#ifdef HAVE_CONFIG_H\n# include <config.h>\n#endif\n\n\n#include \"lame.h\"\n#include \"machine.h\"\n\n#include \"version.h\"    /* macros of version numbers */\n\n\n\n\n\n/*! Get the LAME version string. */\n/*!\n  \\param void\n  \\return a pointer to a string which describes the version of LAME.\n*/\nconst char *\nget_lame_version(void)\n{                       /* primary to write screen reports */\n    /* Here we can also add informations about compile time configurations */\n\n#if   LAME_ALPHA_VERSION\n    static /*@observer@ */ const char *const str =\n        STR(LAME_MAJOR_VERSION) \".\" STR(LAME_MINOR_VERSION) \" \"\n        \"(alpha \" STR(LAME_PATCH_VERSION) \", \" __DATE__ \" \" __TIME__ \")\";\n#elif LAME_BETA_VERSION\n    static /*@observer@ */ const char *const str =\n        STR(LAME_MAJOR_VERSION) \".\" STR(LAME_MINOR_VERSION) \" \"\n        \"(beta \" STR(LAME_PATCH_VERSION) \", \" __DATE__ \")\";\n#elif LAME_RELEASE_VERSION && (LAME_PATCH_VERSION > 0)\n    static /*@observer@ */ const char *const str =\n        STR(LAME_MAJOR_VERSION) \".\" STR(LAME_MINOR_VERSION) \".\" STR(LAME_PATCH_VERSION);\n#else\n    static /*@observer@ */ const char *const str =\n        STR(LAME_MAJOR_VERSION) \".\" STR(LAME_MINOR_VERSION);\n#endif\n\n    return str;\n}\n\n\n/*! Get the short LAME version string. */\n/*!\n  It's mainly for inclusion into the MP3 stream.\n\n  \\param void   \n  \\return a pointer to the short version of the LAME version string.\n*/\nconst char *\nget_lame_short_version(void)\n{\n    /* adding date and time to version string makes it harder for output\n       validation */\n\n#if   LAME_ALPHA_VERSION\n    static /*@observer@ */ const char *const str =\n        STR(LAME_MAJOR_VERSION) \".\" STR(LAME_MINOR_VERSION) \" (alpha \" STR(LAME_PATCH_VERSION) \")\";\n#elif LAME_BETA_VERSION\n    static /*@observer@ */ const char *const str =\n        STR(LAME_MAJOR_VERSION) \".\" STR(LAME_MINOR_VERSION) \" (beta \" STR(LAME_PATCH_VERSION) \")\";\n#elif LAME_RELEASE_VERSION && (LAME_PATCH_VERSION > 0)\n    static /*@observer@ */ const char *const str =\n        STR(LAME_MAJOR_VERSION) \".\" STR(LAME_MINOR_VERSION) \".\" STR(LAME_PATCH_VERSION);\n#else\n    static /*@observer@ */ const char *const str =\n        STR(LAME_MAJOR_VERSION) \".\" STR(LAME_MINOR_VERSION);\n#endif\n\n    return str;\n}\n\n/*! Get the _very_ short LAME version string. */\n/*!\n  It's used in the LAME VBR tag only.\n\n  \\param void   \n  \\return a pointer to the short version of the LAME version string.\n*/\nconst char *\nget_lame_very_short_version(void)\n{\n    /* adding date and time to version string makes it harder for output\n       validation */\n#if   LAME_ALPHA_VERSION\n#define P \"a\"\n#elif LAME_BETA_VERSION\n#define P \"b\"\n#elif LAME_RELEASE_VERSION && (LAME_PATCH_VERSION > 0)\n#define P \"r\"\n#else\n#define P \"\"\n#endif\n    static /*@observer@ */ const char *const str =\n#if (LAME_PATCH_VERSION > 0)\n      \"LAME\" STR(LAME_MAJOR_VERSION) \".\" STR(LAME_MINOR_VERSION) P STR(LAME_PATCH_VERSION)\n#else\n      \"LAME\" STR(LAME_MAJOR_VERSION) \".\" STR(LAME_MINOR_VERSION) P\n#endif\n      ;\n    return str;\n}\n\n/*! Get the _very_ short LAME version string. */\n/*!\n  It's used in the LAME VBR tag only, limited to 9 characters max.\n  Due to some 3rd party HW/SW decoders, it has to start with LAME.\n\n  \\param void   \n  \\return a pointer to the short version of the LAME version string.\n */\nconst char*\nget_lame_tag_encoder_short_version(void)\n{\n    static /*@observer@ */ const char *const str =\n            /* FIXME: new scheme / new version counting / drop versioning here ? */\n    \"LAME\" STR(LAME_MAJOR_VERSION) \".\" STR(LAME_MINOR_VERSION) P\n    ;\n    return str;\n}\n\n/*! Get the version string for GPSYCHO. */\n/*!\n  \\param void\n  \\return a pointer to a string which describes the version of GPSYCHO.\n*/\nconst char *\nget_psy_version(void)\n{\n#if   PSY_ALPHA_VERSION > 0\n    static /*@observer@ */ const char *const str =\n        STR(PSY_MAJOR_VERSION) \".\" STR(PSY_MINOR_VERSION)\n        \" (alpha \" STR(PSY_ALPHA_VERSION) \", \" __DATE__ \" \" __TIME__ \")\";\n#elif PSY_BETA_VERSION > 0\n    static /*@observer@ */ const char *const str =\n        STR(PSY_MAJOR_VERSION) \".\" STR(PSY_MINOR_VERSION)\n        \" (beta \" STR(PSY_BETA_VERSION) \", \" __DATE__ \")\";\n#else\n    static /*@observer@ */ const char *const str =\n        STR(PSY_MAJOR_VERSION) \".\" STR(PSY_MINOR_VERSION);\n#endif\n\n    return str;\n}\n\n\n/*! Get the URL for the LAME website. */\n/*!\n  \\param void\n  \\return a pointer to a string which is a URL for the LAME website.\n*/\nconst char *\nget_lame_url(void)\n{\n    static /*@observer@ */ const char *const str = LAME_URL;\n\n    return str;\n}\n\n\n/*! Get the numerical representation of the version. */\n/*!\n  Writes the numerical representation of the version of LAME and\n  GPSYCHO into lvp.\n\n  \\param lvp    \n*/\nvoid\nget_lame_version_numerical(lame_version_t * lvp)\n{\n    static /*@observer@ */ const char *const features = \"\"; /* obsolete */\n\n    /* generic version */\n    lvp->major = LAME_MAJOR_VERSION;\n    lvp->minor = LAME_MINOR_VERSION;\n#if LAME_ALPHA_VERSION\n    lvp->alpha = LAME_PATCH_VERSION;\n    lvp->beta = 0;\n#elif LAME_BETA_VERSION\n    lvp->alpha = 0;\n    lvp->beta = LAME_PATCH_VERSION;\n#else\n    lvp->alpha = 0;\n    lvp->beta = 0;\n#endif\n\n    /* psy version */\n    lvp->psy_major = PSY_MAJOR_VERSION;\n    lvp->psy_minor = PSY_MINOR_VERSION;\n    lvp->psy_alpha = PSY_ALPHA_VERSION;\n    lvp->psy_beta = PSY_BETA_VERSION;\n\n    /* compile time features */\n    /*@-mustfree@ */\n    lvp->features = features;\n    /*@=mustfree@ */\n}\n\n\nconst char *\nget_lame_os_bitness(void)\n{\n    static /*@observer@ */ const char *const strXX = \"\";\n    static /*@observer@ */ const char *const str32 = \"32bits\";\n    static /*@observer@ */ const char *const str64 = \"64bits\";\n\n    switch (sizeof(void *)) {\n    case 4:\n        return str32;\n\n    case 8:\n        return str64;\n\n    default:\n        return strXX;\n    }\n}\n\n/* end of version.c */\n"
  },
  {
    "path": "app/src/main/jni/libmp3lame/version.h",
    "content": "/*\n *      Version numbering for LAME.\n *\n *      Copyright (c) 1999 A.L. Faber\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Library General Public\n * License as published by the Free Software Foundation; either\n * version 2 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Library General Public License for more details.\n *\n * You should have received a copy of the GNU Library General Public\n * License along with this library; if not, write to the\n * Free Software Foundation, Inc., 59 Temple Place - Suite 330,\n * Boston, MA 02111-1307, USA.\n */\n\n#ifndef LAME_VERSION_H\n#define LAME_VERSION_H\n\n\n/*\n * To make a string from a token, use the # operator:\n */\n#ifndef STR\n# define __STR(x)  #x\n# define STR(x)    __STR(x)\n#endif\n\n# define LAME_URL              \"http://lame.sf.net\"\n\n\n# define LAME_MAJOR_VERSION      3 /* Major version number */\n# define LAME_MINOR_VERSION     99 /* Minor version number */\n# define LAME_TYPE_VERSION       2 /* 0:alpha 1:beta 2:release */\n# define LAME_PATCH_VERSION      5 /* Patch level */\n# define LAME_ALPHA_VERSION     (LAME_TYPE_VERSION==0)\n# define LAME_BETA_VERSION      (LAME_TYPE_VERSION==1)\n# define LAME_RELEASE_VERSION   (LAME_TYPE_VERSION==2)\n\n# define PSY_MAJOR_VERSION       1 /* Major version number */\n# define PSY_MINOR_VERSION       0 /* Minor version number */\n# define PSY_ALPHA_VERSION       0 /* Set number if this is an alpha version, otherwise zero */\n# define PSY_BETA_VERSION        0 /* Set number if this is a beta version, otherwise zero */\n\n#if LAME_ALPHA_VERSION\n#define LAME_PATCH_LEVEL_STRING \" alpha \" STR(LAME_PATCH_VERSION)\n#endif\n#if LAME_BETA_VERSION\n#define LAME_PATCH_LEVEL_STRING \" beta \" STR(LAME_PATCH_VERSION)\n#endif\n#if LAME_RELEASE_VERSION\n#if LAME_PATCH_VERSION\n#define LAME_PATCH_LEVEL_STRING \" release \" STR(LAME_PATCH_VERSION)\n#else\n#define LAME_PATCH_LEVEL_STRING \"\"\n#endif\n#endif\n\n# define LAME_VERSION_STRING STR(LAME_MAJOR_VERSION) \".\" STR(LAME_MINOR_VERSION) LAME_PATCH_LEVEL_STRING\n\n#endif /* LAME_VERSION_H */\n\n/* End of version.h */\n"
  },
  {
    "path": "app/src/main/library/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.convert.mymp3convert\">\n\n    <uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\" />\n    <uses-permission android:name=\"android.permission.RECORD_AUDIO\" />\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/Theme.MyMp3Convert\"\n        android:requestLegacyExternalStorage=\"true\">\n        <activity android:name=\".MainActivity\">\n        </activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "app/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"108\"\n    android:viewportHeight=\"108\">\n    <path\n        android:fillColor=\"#3DDC84\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"108\"\n    android:viewportHeight=\"108\">\n    <path android:pathData=\"M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"85.84757\"\n                android:endY=\"92.4963\"\n                android:startX=\"42.9492\"\n                android:startY=\"49.59793\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        android:pathData=\"M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#00000000\" />\n</vector>"
  },
  {
    "path": "app/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\".MainActivity\"\n    android:orientation=\"vertical\">\n\n    <TextView\n        android:id=\"@+id/tv\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"Hello World!\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintLeft_toLeftOf=\"parent\"\n        app:layout_constraintRight_toRightOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\" />\n    <Button\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"test\"\n        android:onClick=\"test\"\n        />\n    <Button\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"convert\"\n        android:onClick=\"convert\"\n        />\n    <Button\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"convertByHelper01\"\n        android:onClick=\"convertByHelper01\"\n        />\n    <Button\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"convertByHelper02\"\n        android:onClick=\"convertByHelper02\"\n        />\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/layout/activity_main2.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\".MainActivity2\">\n\n</androidx.constraintlayout.widget.ConstraintLayout>"
  },
  {
    "path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"purple_200\">#FFBB86FC</color>\n    <color name=\"purple_500\">#FF6200EE</color>\n    <color name=\"purple_700\">#FF3700B3</color>\n    <color name=\"teal_200\">#FF03DAC5</color>\n    <color name=\"teal_700\">#FF018786</color>\n    <color name=\"black\">#FF000000</color>\n    <color name=\"white\">#FFFFFFFF</color>\n</resources>"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">MyMp3Convert</string>\n</resources>"
  },
  {
    "path": "app/src/main/res/values/themes.xml",
    "content": "<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <!-- Base application theme. -->\n    <style name=\"Theme.MyMp3Convert\" parent=\"Theme.MaterialComponents.DayNight.DarkActionBar\">\n        <!-- Primary brand color. -->\n        <item name=\"colorPrimary\">@color/purple_500</item>\n        <item name=\"colorPrimaryVariant\">@color/purple_700</item>\n        <item name=\"colorOnPrimary\">@color/white</item>\n        <!-- Secondary brand color. -->\n        <item name=\"colorSecondary\">@color/teal_200</item>\n        <item name=\"colorSecondaryVariant\">@color/teal_700</item>\n        <item name=\"colorOnSecondary\">@color/black</item>\n        <!-- Status bar color. -->\n        <item name=\"android:statusBarColor\" tools:targetApi=\"l\">?attr/colorPrimaryVariant</item>\n        <!-- Customize your theme here. -->\n    </style>\n</resources>"
  },
  {
    "path": "app/src/main/res/values-night/themes.xml",
    "content": "<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <!-- Base application theme. -->\n    <style name=\"Theme.MyMp3Convert\" parent=\"Theme.MaterialComponents.DayNight.DarkActionBar\">\n        <!-- Primary brand color. -->\n        <item name=\"colorPrimary\">@color/purple_200</item>\n        <item name=\"colorPrimaryVariant\">@color/purple_700</item>\n        <item name=\"colorOnPrimary\">@color/black</item>\n        <!-- Secondary brand color. -->\n        <item name=\"colorSecondary\">@color/teal_200</item>\n        <item name=\"colorSecondaryVariant\">@color/teal_200</item>\n        <item name=\"colorOnSecondary\">@color/black</item>\n        <!-- Status bar color. -->\n        <item name=\"android:statusBarColor\" tools:targetApi=\"l\">?attr/colorPrimaryVariant</item>\n        <!-- Customize your theme here. -->\n    </style>\n</resources>"
  },
  {
    "path": "app/src/test/java/com/convert/mymp3convert/ExampleUnitTest.java",
    "content": "package com.convert.mymp3convert;\n\nimport org.junit.Test;\n\nimport java.util.concurrent.ConcurrentHashMap;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() {\n        assertEquals(4, 2 + 2);\n    }\n    @Test\n    public void test(){\n        ConcurrentHashMap map = new ConcurrentHashMap<String,Integer>();\n        map.put(\"m1\",1);\n        map.put(\"m2\",2);\n        map.put(\"m3\",3);\n        map.put(\"m4\",4);\n        map.put(\"m5\",5);\n        map.put(\"m6\",6);\n        System.out.println(map);\n        map.remove(\"m1\");\n        System.out.println(map);\n        System.out.println(map.contains(2));\n        System.out.println(map.containsValue(2));\n        System.out.println(map.containsKey(\"m2\"));\n        System.out.println(map.contains(1));\n        System.out.println(map.containsValue(1));\n        System.out.println(map.containsKey(\"m1\"));\n        System.out.println(map.get(\"m1\"));\n        map.put(\"m3\",100);\n        System.out.println(map.get(\"m3\"));\n        System.out.println(map);\n    }\n}"
  },
  {
    "path": "app/说明 .txt",
    "content": "G:\\e\\work\\test\\MyJniDemo\\app\\src\\main\\java>javac com\\example\\myjnidemo\\LameUtils.java\n\nG:\\e\\work\\test\\MyJniDemo\\app\\src\\main\\java>javap -s -p com.example.myjnidemo.LameUtils\nCompiled from \"LameUtils.java\"\npublic class com.example.myjnidemo.LameUtils {\n  public com.example.myjnidemo.LameUtils();\n    descriptor: ()V\n\n  public static native void convertmp3(java.lang.String, java.lang.String);\n    descriptor: (Ljava/lang/String;Ljava/lang/String;)V\n\n  public static native java.lang.String getLameVersion();\n    descriptor: ()Ljava/lang/String;\n\n  public static void setConvertProgress(int);\n    descriptor: (I)V\n\n  public static void convertFinish(java.lang.String);\n    descriptor: (Ljava/lang/String;)V\n}\n\nG:\\e\\work\\test\\MyJniDemo\\app\\src\\main\\java>\n\n\nE:\\work\\test\\MyMp3Convert\\app\\src\\main\\java>javah -classpath . com.convert.mp3.ConvertUtil\n\n\nE:\\work\\test\\MyMp3Convert\\app\\src\\main\\java>javac -encoding UTF-8 com\\convert\\mp3\\Mp3ConvertUtil.java\n\nE:\\work\\test\\MyMp3Convert\\app\\src\\main\\java>javap -s -p  com\\convert\\mymp3convert\\Mp3ConvertUtil.class\nCompiled from \"Mp3ConvertUtil.java\"\npublic class com.convert.mymp3convert.Mp3ConvertUtil {\n  public com.convert.mymp3convert.Mp3ConvertUtil();\n    descriptor: ()V\n\n  public static native java.lang.String hello(java.lang.String);\n    descriptor: (Ljava/lang/String;)Ljava/lang/String;\n\n  public static native java.lang.String getLameVer();\n    descriptor: ()Ljava/lang/String;\n\n  public static native void convertmp3(java.lang.String, java.lang.String);\n    descriptor: (Ljava/lang/String;Ljava/lang/String;)V\n\n  public static void setConvertProgress(int);\n    descriptor: (I)V\n\n  public static void convertFinish(java.lang.String);\n    descriptor: (Ljava/lang/String;)V\n\n  public static void convertError(java.lang.String);\n    descriptor: (Ljava/lang/String;)V\n\n  static {};\n    descriptor: ()V\n}\n"
  },
  {
    "path": "build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\nbuildscript {\n    ext {\n        kotlin_version = '1.4.21'\n    }\n    repositories {\n        google()\n        jcenter()\n    }\n    dependencies {\n        classpath \"com.android.tools.build:gradle:4.1.0\"\n        classpath \"org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version\"\n\n        // NOTE: Do not place your application dependencies here; they belong\n        // in the individual module build.gradle files\n    }\n}\n\nallprojects {\n    repositories {\n        google()\n        jcenter()\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}"
  },
  {
    "path": "demo/.gitignore",
    "content": "/build"
  },
  {
    "path": "demo/build.gradle",
    "content": "plugins {\n    id 'com.android.application'\n}\n\nandroid {\n    compileSdkVersion 30\n    buildToolsVersion \"30.0.3\"\n\n    defaultConfig {\n        applicationId \"com.convert.demo\"\n        minSdkVersion 18\n        targetSdkVersion 30\n        versionCode 1\n        versionName \"1.0\"\n\n        testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n    }\n    repositories {\n        flatDir {\n            dirs 'libs'\n        }\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n        }\n    }\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n}\n\ndependencies {\n\n    implementation 'androidx.appcompat:appcompat:1.2.0'\n    implementation 'com.google.android.material:material:1.2.1'\n    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'\n    testImplementation 'junit:junit:4.+'\n    androidTestImplementation 'androidx.test.ext:junit:1.1.2'\n    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'\n\n    implementation(name:'app-release', ext: 'aar')\n\n}"
  },
  {
    "path": "demo/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile"
  },
  {
    "path": "demo/src/androidTest/java/com/convert/demo/ExampleInstrumentedTest.java",
    "content": "package com.convert.demo;\n\nimport android.content.Context;\n\nimport androidx.test.platform.app.InstrumentationRegistry;\nimport androidx.test.ext.junit.runners.AndroidJUnit4;\n\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\n\nimport static org.junit.Assert.*;\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\n@RunWith(AndroidJUnit4.class)\npublic class ExampleInstrumentedTest {\n    @Test\n    public void useAppContext() {\n        // Context of the app under test.\n        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();\n        assertEquals(\"com.convert.demo\", appContext.getPackageName());\n    }\n}"
  },
  {
    "path": "demo/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.convert.demo\">\n\n    <application\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/Theme.MyMp3Convert\">\n        <activity android:name=\".MainActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "demo/src/main/java/com/convert/demo/MainActivity.java",
    "content": "package com.convert.demo;\n\nimport androidx.appcompat.app.AppCompatActivity;\n\nimport android.os.Bundle;\nimport android.util.Log;\nimport android.view.View;\nimport android.widget.TextView;\n\nimport com.convert.mymp3convert.Mp3ConvertUtil;\n\npublic class MainActivity extends AppCompatActivity {\n    TextView tv;\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_main);\n        tv = findViewById(R.id.tv);\n    }\n    public void click(View v){\n        Log.d(\"ddebug\",Mp3ConvertUtil.getLameVer());\n        tv.append(\"\\n \" + Mp3ConvertUtil.hello(\"hello\"));\n    }\n}"
  },
  {
    "path": "demo/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"108\"\n    android:viewportHeight=\"108\">\n    <path\n        android:fillColor=\"#3DDC84\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n</vector>\n"
  },
  {
    "path": "demo/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"108\"\n    android:viewportHeight=\"108\">\n    <path android:pathData=\"M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"85.84757\"\n                android:endY=\"92.4963\"\n                android:startX=\"42.9492\"\n                android:startY=\"49.59793\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        android:pathData=\"M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#00000000\" />\n</vector>"
  },
  {
    "path": "demo/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\".MainActivity\"\n    android:orientation=\"vertical\">\n\n    <TextView\n        android:id=\"@+id/tv\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"Hello World!\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintLeft_toLeftOf=\"parent\"\n        app:layout_constraintRight_toRightOf=\"parent\"\n        app:layout_constraintTop_toTopOf=\"parent\" />\n\n    <Button\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:text=\"click\"\n        android:onClick=\"click\"/>\n\n</LinearLayout>"
  },
  {
    "path": "demo/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "demo/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "demo/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"purple_200\">#FFBB86FC</color>\n    <color name=\"purple_500\">#FF6200EE</color>\n    <color name=\"purple_700\">#FF3700B3</color>\n    <color name=\"teal_200\">#FF03DAC5</color>\n    <color name=\"teal_700\">#FF018786</color>\n    <color name=\"black\">#FF000000</color>\n    <color name=\"white\">#FFFFFFFF</color>\n</resources>"
  },
  {
    "path": "demo/src/main/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">demo</string>\n</resources>"
  },
  {
    "path": "demo/src/main/res/values/themes.xml",
    "content": "<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <!-- Base application theme. -->\n    <style name=\"Theme.MyMp3Convert\" parent=\"Theme.MaterialComponents.DayNight.DarkActionBar\">\n        <!-- Primary brand color. -->\n        <item name=\"colorPrimary\">@color/purple_500</item>\n        <item name=\"colorPrimaryVariant\">@color/purple_700</item>\n        <item name=\"colorOnPrimary\">@color/white</item>\n        <!-- Secondary brand color. -->\n        <item name=\"colorSecondary\">@color/teal_200</item>\n        <item name=\"colorSecondaryVariant\">@color/teal_700</item>\n        <item name=\"colorOnSecondary\">@color/black</item>\n        <!-- Status bar color. -->\n        <item name=\"android:statusBarColor\" tools:targetApi=\"l\">?attr/colorPrimaryVariant</item>\n        <!-- Customize your theme here. -->\n    </style>\n</resources>"
  },
  {
    "path": "demo/src/main/res/values-night/themes.xml",
    "content": "<resources xmlns:tools=\"http://schemas.android.com/tools\">\n    <!-- Base application theme. -->\n    <style name=\"Theme.MyMp3Convert\" parent=\"Theme.MaterialComponents.DayNight.DarkActionBar\">\n        <!-- Primary brand color. -->\n        <item name=\"colorPrimary\">@color/purple_200</item>\n        <item name=\"colorPrimaryVariant\">@color/purple_700</item>\n        <item name=\"colorOnPrimary\">@color/black</item>\n        <!-- Secondary brand color. -->\n        <item name=\"colorSecondary\">@color/teal_200</item>\n        <item name=\"colorSecondaryVariant\">@color/teal_200</item>\n        <item name=\"colorOnSecondary\">@color/black</item>\n        <!-- Status bar color. -->\n        <item name=\"android:statusBarColor\" tools:targetApi=\"l\">?attr/colorPrimaryVariant</item>\n        <!-- Customize your theme here. -->\n    </style>\n</resources>"
  },
  {
    "path": "demo/src/test/java/com/convert/demo/ExampleUnitTest.java",
    "content": "package com.convert.demo;\n\nimport org.junit.Test;\n\nimport static org.junit.Assert.*;\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * @see <a href=\"http://d.android.com/tools/testing\">Testing documentation</a>\n */\npublic class ExampleUnitTest {\n    @Test\n    public void addition_isCorrect() {\n        assertEquals(4, 2 + 2);\n    }\n}"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#Thu Jan 14 21:57:53 CST 2021\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-6.5-bin.zip\n"
  },
  {
    "path": "gradle.properties",
    "content": "# Project-wide Gradle settings.\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\norg.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n# AndroidX package structure to make it clearer which packages are bundled with the\n# Android operating system, and which are packaged with your app\"s APK\n# https://developer.android.com/topic/libraries/support-library/androidx-rn\nandroid.useAndroidX=true\n# Automatically convert third-party libraries to use AndroidX\nandroid.enableJetifier=true\n#isAppLibrary=false\nisAppLibrary=false"
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env sh\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto init\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto init\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:init\n@rem Get command-line arguments, handling Windows variants\n\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\n\n:win9xME_args\n@rem Slurp the command line arguments.\nset CMD_LINE_ARGS=\nset _SKIP=2\n\n:win9xME_args_slurp\nif \"x%~1\" == \"x\" goto execute\n\nset CMD_LINE_ARGS=%*\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "settings.gradle",
    "content": "include ':demo'\ninclude ':app'\nrootProject.name = \"MyMp3Convert\""
  }
]