├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── CMakeLists.txt ├── build.gradle ├── lame │ └── armeabi │ │ └── liblamemp3.so ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── clam314 │ │ └── lame │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── cpp │ │ ├── SimpleLame.cpp │ │ ├── SimpleLame.h │ │ └── lamemp3 │ │ │ ├── VbrTag.c │ │ │ ├── VbrTag.h │ │ │ ├── bitstream.c │ │ │ ├── bitstream.h │ │ │ ├── encoder.c │ │ │ ├── encoder.h │ │ │ ├── fft.c │ │ │ ├── fft.h │ │ │ ├── gain_analysis.c │ │ │ ├── gain_analysis.h │ │ │ ├── id3tag.c │ │ │ ├── id3tag.h │ │ │ ├── l3side.h │ │ │ ├── lame-analysis.h │ │ │ ├── lame.c │ │ │ ├── lame.h │ │ │ ├── lame_global_flags.h │ │ │ ├── lameerror.h │ │ │ ├── machine.h │ │ │ ├── mpglib_interface.c │ │ │ ├── newmdct.c │ │ │ ├── newmdct.h │ │ │ ├── presets.c │ │ │ ├── psymodel.c │ │ │ ├── psymodel.h │ │ │ ├── quantize.c │ │ │ ├── quantize.h │ │ │ ├── quantize_pvt.c │ │ │ ├── quantize_pvt.h │ │ │ ├── reservoir.c │ │ │ ├── reservoir.h │ │ │ ├── set_get.c │ │ │ ├── set_get.h │ │ │ ├── tables.c │ │ │ ├── tables.h │ │ │ ├── takehiro.c │ │ │ ├── util.c │ │ │ ├── util.h │ │ │ ├── vbrquantize.c │ │ │ ├── vbrquantize.h │ │ │ ├── version.c │ │ │ └── version.h │ ├── java │ │ └── com │ │ │ └── clam314 │ │ │ └── lame │ │ │ ├── DataEncodeThread.java │ │ │ ├── LameMp3Manager.java │ │ │ ├── MainActivity.java │ │ │ ├── MediaPlayUtil.java │ │ │ ├── MediaRecorderButton.java │ │ │ ├── MediaRecorderListener.java │ │ │ ├── Mp3Recorder.java │ │ │ ├── PCMFormat.java │ │ │ └── SimpleLame.java │ └── res │ │ ├── drawable │ │ ├── anim_voice_left.xml │ │ ├── button_recording.xml │ │ ├── button_recordnormal.xml │ │ ├── voice_left_1.png │ │ ├── voice_left_2.png │ │ └── voice_left_3.png │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── clam314 │ └── lame │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | 47 | 48 | 49 | 50 | Android API 19 Platform 51 | 52 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LameMp3ForAndroid 2 | ![image](https://github.com/clam314/Image/blob/master/lameforandroid.png?raw=true)
3 |
4 | 本次demo使用AndroidStudio+Cmake+NDK进行开发
5 | 利用Android SDK提供的AndroidRecorder进行录音,得到PCM数据,并使用jni调用Lame这个C库将PCM数据转换为MP3文件。并使用MediaPlayer对录音的MP3文件进行播放。
6 |
7 | #### 主要类的介绍 8 | - Mp3Recorder—— 是负责调用AudioRecorder进行录音的类
9 | - SimpleLame——是负责将MP3Recorder录制出的PCM数据转换成MP3文件
10 | - DataEncodeThread——是负责执行PCM转MP3的线程
11 | - LameMp3Manager——是对Mp3Recorder的多一次封装,增加了取消后删除之前录制的数据的逻辑
12 | - MediaPlayerUtil——是对系统的MediaPlay进行简单的封装,使其只需要三步就可以播放音频文件
13 | - MediaRecorderButton ——是一个仿微信录音按键的控件,按下录制,松开结束,录制时上滑则取消录制
14 | #### 录制的流程 15 | 1. Mp3Recorder调用startRecording()开始录制并初始化DataEncoderThread线程,并定期将录制的PCM数据,传入DataEncoderThread中。 16 | 2. 在DataEncoderThread里,SimpleLame将Mp3Recorder传入的PCM数据转换成MP3格式并写入文件,其中SimpleLame通过jni对Lame库进行调用 17 | 3. Mp3Recorder调用stopRecording()停止录制,并通知DataEncoderThread线程录制结束,DataEncoderThread将剩余的数据转换完毕。 18 | #### 编译过程 19 | - http://www.jianshu.com/p/065bfe6d3ec2# 20 | #### 详细点的讲解 21 | - http://www.jianshu.com/p/4a3e24e45ce9 22 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | cmake_minimum_required(VERSION 3.4.1) 3 | 4 | #设置变量SRC_DIR为lamemp3的所在路径 5 | set(SRC_DIR src/main/cpp/lamemp3) 6 | 7 | #指定头文件所在,可以多次调用,指定多个路径 8 | include_directories(src/main/cpp/lamemp3) 9 | 10 | #添加自自定义的so库时,有两种方式,一种添加一个目录,一种一个个文件添加 11 | 12 | #设定一个目录 13 | aux_source_directory(src/main/cpp/lamemp3 SRC_LIST) 14 | 15 | #将前面目录下所有的文件都添加进去 16 | add_library(lamemp3 SHARED src/main/cpp/SimpleLame.cpp ${SRC_LIST}) 17 | 18 | #一个个文件的加 19 | #add_library(lame-mp3 20 | # SHARED 21 | # ${SRC_DIR}/bitstream.c 22 | # ${SRC_DIR}/encoder.c 23 | # ${SRC_DIR}/fft.c 24 | # ${SRC_DIR}/gain_analysis.c 25 | # ${SRC_DIR}/id3tag.c 26 | # ${SRC_DIR}/lame.c 27 | # ${SRC_DIR}/mpglib_interface.c 28 | # ${SRC_DIR}/newmdct.c 29 | # ${SRC_DIR}/presets.c 30 | # ${SRC_DIR}/psymodel.c 31 | # ${SRC_DIR}/quantize.c 32 | # ${SRC_DIR}/quantize_pvt.c 33 | # ${SRC_DIR}/reservoir.c 34 | # ${SRC_DIR}/set_get.c 35 | # ${SRC_DIR}/tables.c 36 | # ${SRC_DIR}/takehiro.c 37 | # ${SRC_DIR}/util.c 38 | # ${SRC_DIR}/vbrquantize.c 39 | # ${SRC_DIR}/VbrTag.c 40 | # ${SRC_DIR}/version.c 41 | # ) 42 | 43 | find_library(log-lib log ) 44 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.2" 6 | defaultConfig { 7 | applicationId "com.clam314.lame" 8 | minSdkVersion 16 9 | targetSdkVersion 25 10 | versionCode 1 11 | versionName "1.0" 12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 13 | externalNativeBuild { 14 | cmake { 15 | cppFlags "" 16 | abiFilters 'armeabi' 17 | } 18 | } 19 | } 20 | buildTypes { 21 | release { 22 | minifyEnabled false 23 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 24 | } 25 | } 26 | externalNativeBuild { 27 | cmake { 28 | path "CMakeLists.txt" 29 | } 30 | } 31 | } 32 | 33 | dependencies { 34 | compile fileTree(dir: 'libs', include: ['*.jar']) 35 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 36 | exclude group: 'com.android.support', module: 'support-annotations' 37 | }) 38 | compile 'com.android.support:appcompat-v7:25.3.1' 39 | testCompile 'junit:junit:4.12' 40 | } 41 | -------------------------------------------------------------------------------- /app/lame/armeabi/liblamemp3.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clam314/LameMp3ForAndroid/1f69761a7ec3c91dedda3afe55ef8a111638ad50/app/lame/armeabi/liblamemp3.so -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Users\clam314\Desktop\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/clam314/lame/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.clam314.lame; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.clam314.lame", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/cpp/SimpleLame.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by clam314 on 2017/3/26. 3 | // 4 | 5 | #include 6 | #include "SimpleLame.h" 7 | #include "lamemp3/lame.h" 8 | 9 | static lame_global_flags *glf = NULL; 10 | 11 | void Java_com_clam314_lame_SimpleLame_close(JNIEnv *env, jclass type){ 12 | lame_close(glf); 13 | glf = NULL; 14 | } 15 | 16 | jint Java_com_clam314_lame_SimpleLame_encode(JNIEnv *env, jclass type, jshortArray buffer_l_, 17 | jshortArray buffer_r_, jint samples, jbyteArray mp3buf_) { 18 | jshort *buffer_l = env->GetShortArrayElements(buffer_l_, NULL); 19 | jshort *buffer_r = env->GetShortArrayElements(buffer_r_, NULL); 20 | jbyte *mp3buf = env->GetByteArrayElements(mp3buf_, NULL); 21 | 22 | const jsize mp3buf_size = env->GetArrayLength(mp3buf_); 23 | 24 | int result =lame_encode_buffer(glf, buffer_l, buffer_r, samples, (u_char*)mp3buf, mp3buf_size); 25 | 26 | env->ReleaseShortArrayElements(buffer_l_, buffer_l, 0); 27 | env->ReleaseShortArrayElements(buffer_r_, buffer_r, 0); 28 | env->ReleaseByteArrayElements(mp3buf_, mp3buf, 0); 29 | 30 | return result; 31 | } 32 | 33 | jint Java_com_clam314_lame_SimpleLame_flush(JNIEnv *env, jclass type, jbyteArray mp3buf_) { 34 | jbyte *mp3buf = env->GetByteArrayElements(mp3buf_, NULL); 35 | 36 | const jsize mp3buf_size = env->GetArrayLength(mp3buf_); 37 | 38 | int result = lame_encode_flush(glf, (u_char*)mp3buf, mp3buf_size); 39 | 40 | env->ReleaseByteArrayElements(mp3buf_, mp3buf, 0); 41 | 42 | return result; 43 | } 44 | 45 | void Java_com_clam314_lame_SimpleLame_init__IIIII(JNIEnv *env, jclass type, jint inSampleRate, jint outChannel, 46 | jint outSampleRate, jint outBitrate, jint quality) { 47 | if(glf != NULL){ 48 | lame_close(glf); 49 | glf = NULL; 50 | } 51 | glf = lame_init(); 52 | lame_set_in_samplerate(glf, inSampleRate); 53 | lame_set_num_channels(glf, outChannel); 54 | lame_set_out_samplerate(glf, outSampleRate); 55 | lame_set_brate(glf, outBitrate); 56 | lame_set_quality(glf, quality); 57 | lame_init_params(glf); 58 | } -------------------------------------------------------------------------------- /app/src/main/cpp/SimpleLame.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by clam314 on 2017/3/26. 3 | // 4 | 5 | #include 6 | 7 | extern "C" 8 | { 9 | void Java_com_clam314_lame_SimpleLame_close(JNIEnv *env, jclass type); 10 | 11 | jint Java_com_clam314_lame_SimpleLame_encode(JNIEnv *env, jclass type, jshortArray buffer_l_, 12 | jshortArray buffer_r_, jint samples, jbyteArray mp3buf_); 13 | 14 | jint Java_com_clam314_lame_SimpleLame_flush(JNIEnv *env, jclass type, jbyteArray mp3buf_); 15 | 16 | void Java_com_clam314_lame_SimpleLame_init__IIIII(JNIEnv *env, jclass type, jint inSampleRate, 17 | jint outChannel, jint outSampleRate, jint outBitrate, jint quality); 18 | } -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/VbrTag.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Xing VBR tagging for LAME. 3 | * 4 | * Copyright (c) 1999 A.L. Faber 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Library General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Library General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Library General Public 17 | * License along with this library; if not, write to the 18 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 | * Boston, MA 02111-1307, USA. 20 | */ 21 | 22 | #ifndef LAME_VRBTAG_H 23 | #define LAME_VRBTAG_H 24 | 25 | 26 | /* ----------------------------------------------------------- 27 | * A Vbr header may be present in the ancillary 28 | * data field of the first frame of an mp3 bitstream 29 | * The Vbr header (optionally) contains 30 | * frames total number of audio frames in the bitstream 31 | * bytes total number of bytes in the bitstream 32 | * toc table of contents 33 | 34 | * toc (table of contents) gives seek points 35 | * for random access 36 | * the ith entry determines the seek point for 37 | * i-percent duration 38 | * seek point in bytes = (toc[i]/256.0) * total_bitstream_bytes 39 | * e.g. half duration seek point = (toc[50]/256.0) * total_bitstream_bytes 40 | */ 41 | 42 | 43 | #define FRAMES_FLAG 0x0001 44 | #define BYTES_FLAG 0x0002 45 | #define TOC_FLAG 0x0004 46 | #define VBR_SCALE_FLAG 0x0008 47 | 48 | #define NUMTOCENTRIES 100 49 | 50 | #ifndef lame_internal_flags_defined 51 | #define lame_internal_flags_defined 52 | struct lame_internal_flags; 53 | typedef struct lame_internal_flags lame_internal_flags; 54 | #endif 55 | 56 | 57 | /*structure to receive extracted header */ 58 | /* toc may be NULL*/ 59 | typedef struct { 60 | int h_id; /* from MPEG header, 0=MPEG2, 1=MPEG1 */ 61 | int samprate; /* determined from MPEG header */ 62 | int flags; /* from Vbr header data */ 63 | int frames; /* total bit stream frames from Vbr header data */ 64 | int bytes; /* total bit stream bytes from Vbr header data */ 65 | int vbr_scale; /* encoded vbr scale from Vbr header data */ 66 | unsigned char toc[NUMTOCENTRIES]; /* may be NULL if toc not desired */ 67 | int headersize; /* size of VBR header, in bytes */ 68 | int enc_delay; /* encoder delay */ 69 | int enc_padding; /* encoder paddign added at end of stream */ 70 | } VBRTAGDATA; 71 | 72 | int GetVbrTag(VBRTAGDATA * pTagData, const unsigned char *buf); 73 | 74 | int InitVbrTag(lame_global_flags * gfp); 75 | int PutVbrTag(lame_global_flags const *gfp, FILE * fid); 76 | void AddVbrFrame(lame_internal_flags * gfc); 77 | void UpdateMusicCRC(uint16_t * crc, const unsigned char *buffer, int size); 78 | 79 | #endif 80 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/bitstream.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MP3 bitstream Output interface for LAME 3 | * 4 | * Copyright (c) 1999 Takehiro TOMINAGA 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Library General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Library General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Library General Public 17 | * License along with this library; if not, write to the 18 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 | * Boston, MA 02111-1307, USA. 20 | */ 21 | 22 | #ifndef LAME_BITSTREAM_H 23 | #define LAME_BITSTREAM_H 24 | 25 | int getframebits(const lame_internal_flags * gfc); 26 | 27 | int format_bitstream(lame_internal_flags * gfc); 28 | 29 | void flush_bitstream(lame_internal_flags * gfc); 30 | void add_dummy_byte(lame_internal_flags * gfc, unsigned char val, unsigned int n); 31 | 32 | int copy_buffer(lame_internal_flags * gfc, unsigned char *buffer, int buffer_size, 33 | int update_crc); 34 | void init_bit_stream_w(lame_internal_flags * gfc); 35 | void CRC_writeheader(lame_internal_flags const *gfc, char *buffer); 36 | int compute_flushbits(const lame_internal_flags * gfp, int *nbytes); 37 | 38 | int get_max_frame_buffer_size_by_constraint(SessionConfig_t const * cfg, int constraint); 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/encoder.c: -------------------------------------------------------------------------------- 1 | /* 2 | * LAME MP3 encoding engine 3 | * 4 | * Copyright (c) 1999 Mark Taylor 5 | * Copyright (c) 2000-2002 Takehiro Tominaga 6 | * Copyright (c) 2000-2011 Robert Hegemann 7 | * Copyright (c) 2001 Gabriel Bouvigne 8 | * Copyright (c) 2001 John Dahlstrom 9 | * 10 | * This library is free software; you can redistribute it and/or 11 | * modify it under the terms of the GNU Library General Public 12 | * License as published by the Free Software Foundation; either 13 | * version 2 of the License, or (at your option) any later version. 14 | * 15 | * This library is distributed in the hope that it will be useful, 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 | * Library General Public License for more details. 19 | * 20 | * You should have received a copy of the GNU Library General Public 21 | * License along with this library; if not, write to the 22 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 23 | * Boston, MA 02111-1307, USA. 24 | */ 25 | 26 | /* $Id: encoder.c,v 1.111 2011/05/07 16:05:17 rbrito Exp $ */ 27 | 28 | #ifdef HAVE_CONFIG_H 29 | #include 30 | #endif 31 | 32 | 33 | #include "lame.h" 34 | #include "machine.h" 35 | #include "encoder.h" 36 | #include "util.h" 37 | #include "lame_global_flags.h" 38 | #include "newmdct.h" 39 | #include "psymodel.h" 40 | #include "lame-analysis.h" 41 | #include "bitstream.h" 42 | #include "VbrTag.h" 43 | #include "quantize_pvt.h" 44 | 45 | 46 | 47 | /* 48 | * auto-adjust of ATH, useful for low volume 49 | * Gabriel Bouvigne 3 feb 2001 50 | * 51 | * modifies some values in 52 | * gfp->internal_flags->ATH 53 | * (gfc->ATH) 54 | */ 55 | static void 56 | adjust_ATH(lame_internal_flags const *const gfc) 57 | { 58 | SessionConfig_t const *const cfg = &gfc->cfg; 59 | FLOAT gr2_max, max_pow; 60 | 61 | if (gfc->ATH->use_adjust == 0) { 62 | gfc->ATH->adjust_factor = 1.0; /* no adjustment */ 63 | return; 64 | } 65 | 66 | /* jd - 2001 mar 12, 27, jun 30 */ 67 | /* loudness based on equal loudness curve; */ 68 | /* use granule with maximum combined loudness */ 69 | max_pow = gfc->ov_psy.loudness_sq[0][0]; 70 | gr2_max = gfc->ov_psy.loudness_sq[1][0]; 71 | if (cfg->channels_out == 2) { 72 | max_pow += gfc->ov_psy.loudness_sq[0][1]; 73 | gr2_max += gfc->ov_psy.loudness_sq[1][1]; 74 | } 75 | else { 76 | max_pow += max_pow; 77 | gr2_max += gr2_max; 78 | } 79 | if (cfg->mode_gr == 2) { 80 | max_pow = Max(max_pow, gr2_max); 81 | } 82 | max_pow *= 0.5; /* max_pow approaches 1.0 for full band noise */ 83 | 84 | /* jd - 2001 mar 31, jun 30 */ 85 | /* user tuning of ATH adjustment region */ 86 | max_pow *= gfc->ATH->aa_sensitivity_p; 87 | 88 | /* adjust ATH depending on range of maximum value 89 | */ 90 | 91 | /* jd - 2001 feb27, mar12,20, jun30, jul22 */ 92 | /* continuous curves based on approximation */ 93 | /* to GB's original values. */ 94 | /* For an increase in approximate loudness, */ 95 | /* set ATH adjust to adjust_limit immediately */ 96 | /* after a delay of one frame. */ 97 | /* For a loudness decrease, reduce ATH adjust */ 98 | /* towards adjust_limit gradually. */ 99 | /* max_pow is a loudness squared or a power. */ 100 | if (max_pow > 0.03125) { /* ((1 - 0.000625)/ 31.98) from curve below */ 101 | if (gfc->ATH->adjust_factor >= 1.0) { 102 | gfc->ATH->adjust_factor = 1.0; 103 | } 104 | else { 105 | /* preceding frame has lower ATH adjust; */ 106 | /* ascend only to the preceding adjust_limit */ 107 | /* in case there is leading low volume */ 108 | if (gfc->ATH->adjust_factor < gfc->ATH->adjust_limit) { 109 | gfc->ATH->adjust_factor = gfc->ATH->adjust_limit; 110 | } 111 | } 112 | gfc->ATH->adjust_limit = 1.0; 113 | } 114 | else { /* adjustment curve */ 115 | /* about 32 dB maximum adjust (0.000625) */ 116 | FLOAT const adj_lim_new = 31.98 * max_pow + 0.000625; 117 | if (gfc->ATH->adjust_factor >= adj_lim_new) { /* descend gradually */ 118 | gfc->ATH->adjust_factor *= adj_lim_new * 0.075 + 0.925; 119 | if (gfc->ATH->adjust_factor < adj_lim_new) { /* stop descent */ 120 | gfc->ATH->adjust_factor = adj_lim_new; 121 | } 122 | } 123 | else { /* ascend */ 124 | if (gfc->ATH->adjust_limit >= adj_lim_new) { 125 | gfc->ATH->adjust_factor = adj_lim_new; 126 | } 127 | else { /* preceding frame has lower ATH adjust; */ 128 | /* ascend only to the preceding adjust_limit */ 129 | if (gfc->ATH->adjust_factor < gfc->ATH->adjust_limit) { 130 | gfc->ATH->adjust_factor = gfc->ATH->adjust_limit; 131 | } 132 | } 133 | } 134 | gfc->ATH->adjust_limit = adj_lim_new; 135 | } 136 | } 137 | 138 | /*********************************************************************** 139 | * 140 | * some simple statistics 141 | * 142 | * bitrate index 0: free bitrate -> not allowed in VBR mode 143 | * : bitrates, kbps depending on MPEG version 144 | * bitrate index 15: forbidden 145 | * 146 | * mode_ext: 147 | * 0: LR 148 | * 1: LR-i 149 | * 2: MS 150 | * 3: MS-i 151 | * 152 | ***********************************************************************/ 153 | 154 | static void 155 | updateStats(lame_internal_flags * const gfc) 156 | { 157 | SessionConfig_t const *const cfg = &gfc->cfg; 158 | EncResult_t *eov = &gfc->ov_enc; 159 | int gr, ch; 160 | assert(0 <= eov->bitrate_index && eov->bitrate_index < 16); 161 | assert(0 <= eov->mode_ext && eov->mode_ext < 4); 162 | 163 | /* count bitrate indices */ 164 | eov->bitrate_channelmode_hist[eov->bitrate_index][4]++; 165 | eov->bitrate_channelmode_hist[15][4]++; 166 | 167 | /* count 'em for every mode extension in case of 2 channel encoding */ 168 | if (cfg->channels_out == 2) { 169 | eov->bitrate_channelmode_hist[eov->bitrate_index][eov->mode_ext]++; 170 | eov->bitrate_channelmode_hist[15][eov->mode_ext]++; 171 | } 172 | for (gr = 0; gr < cfg->mode_gr; ++gr) { 173 | for (ch = 0; ch < cfg->channels_out; ++ch) { 174 | int bt = gfc->l3_side.tt[gr][ch].block_type; 175 | if (gfc->l3_side.tt[gr][ch].mixed_block_flag) 176 | bt = 4; 177 | eov->bitrate_blocktype_hist[eov->bitrate_index][bt]++; 178 | eov->bitrate_blocktype_hist[eov->bitrate_index][5]++; 179 | eov->bitrate_blocktype_hist[15][bt]++; 180 | eov->bitrate_blocktype_hist[15][5]++; 181 | } 182 | } 183 | } 184 | 185 | 186 | 187 | 188 | static void 189 | lame_encode_frame_init(lame_internal_flags * gfc, const sample_t *const inbuf[2]) 190 | { 191 | SessionConfig_t const *const cfg = &gfc->cfg; 192 | 193 | int ch, gr; 194 | 195 | if (gfc->lame_encode_frame_init == 0) { 196 | sample_t primebuff0[286 + 1152 + 576]; 197 | sample_t primebuff1[286 + 1152 + 576]; 198 | int const framesize = 576 * cfg->mode_gr; 199 | /* prime the MDCT/polyphase filterbank with a short block */ 200 | int i, j; 201 | gfc->lame_encode_frame_init = 1; 202 | memset(primebuff0, 0, sizeof(primebuff0)); 203 | memset(primebuff1, 0, sizeof(primebuff1)); 204 | for (i = 0, j = 0; i < 286 + 576 * (1 + cfg->mode_gr); ++i) { 205 | if (i < framesize) { 206 | primebuff0[i] = 0; 207 | if (cfg->channels_out == 2) 208 | primebuff1[i] = 0; 209 | } 210 | else { 211 | primebuff0[i] = inbuf[0][j]; 212 | if (cfg->channels_out == 2) 213 | primebuff1[i] = inbuf[1][j]; 214 | ++j; 215 | } 216 | } 217 | /* polyphase filtering / mdct */ 218 | for (gr = 0; gr < cfg->mode_gr; gr++) { 219 | for (ch = 0; ch < cfg->channels_out; ch++) { 220 | gfc->l3_side.tt[gr][ch].block_type = SHORT_TYPE; 221 | } 222 | } 223 | mdct_sub48(gfc, primebuff0, primebuff1); 224 | 225 | /* check FFT will not use a negative starting offset */ 226 | #if 576 < FFTOFFSET 227 | # error FFTOFFSET greater than 576: FFT uses a negative offset 228 | #endif 229 | /* check if we have enough data for FFT */ 230 | assert(gfc->sv_enc.mf_size >= (BLKSIZE + framesize - FFTOFFSET)); 231 | /* check if we have enough data for polyphase filterbank */ 232 | assert(gfc->sv_enc.mf_size >= (512 + framesize - 32)); 233 | } 234 | 235 | } 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | /************************************************************************ 244 | * 245 | * encodeframe() Layer 3 246 | * 247 | * encode a single frame 248 | * 249 | ************************************************************************ 250 | lame_encode_frame() 251 | 252 | 253 | gr 0 gr 1 254 | inbuf: |--------------|--------------|--------------| 255 | 256 | 257 | Polyphase (18 windows, each shifted 32) 258 | gr 0: 259 | window1 <----512----> 260 | window18 <----512----> 261 | 262 | gr 1: 263 | window1 <----512----> 264 | window18 <----512----> 265 | 266 | 267 | 268 | MDCT output: |--------------|--------------|--------------| 269 | 270 | FFT's <---------1024----------> 271 | <---------1024--------> 272 | 273 | 274 | 275 | inbuf = buffer of PCM data size=MP3 framesize 276 | encoder acts on inbuf[ch][0], but output is delayed by MDCTDELAY 277 | so the MDCT coefficints are from inbuf[ch][-MDCTDELAY] 278 | 279 | psy-model FFT has a 1 granule delay, so we feed it data for the 280 | next granule. 281 | FFT is centered over granule: 224+576+224 282 | So FFT starts at: 576-224-MDCTDELAY 283 | 284 | MPEG2: FFT ends at: BLKSIZE+576-224-MDCTDELAY (1328) 285 | MPEG1: FFT ends at: BLKSIZE+2*576-224-MDCTDELAY (1904) 286 | 287 | MPEG2: polyphase first window: [0..511] 288 | 18th window: [544..1055] (1056) 289 | MPEG1: 36th window: [1120..1631] (1632) 290 | data needed: 512+framesize-32 291 | 292 | A close look newmdct.c shows that the polyphase filterbank 293 | only uses data from [0..510] for each window. Perhaps because the window 294 | used by the filterbank is zero for the last point, so Takehiro's 295 | code doesn't bother to compute with it. 296 | 297 | FFT starts at 576-224-MDCTDELAY (304) = 576-FFTOFFSET 298 | 299 | */ 300 | 301 | typedef FLOAT chgrdata[2][2]; 302 | 303 | 304 | int 305 | lame_encode_mp3_frame( /* Output */ 306 | lame_internal_flags * gfc, /* Context */ 307 | sample_t const *inbuf_l, /* Input */ 308 | sample_t const *inbuf_r, /* Input */ 309 | unsigned char *mp3buf, /* Output */ 310 | int mp3buf_size) 311 | { /* Output */ 312 | SessionConfig_t const *const cfg = &gfc->cfg; 313 | int mp3count; 314 | III_psy_ratio masking_LR[2][2]; /*LR masking & energy */ 315 | III_psy_ratio masking_MS[2][2]; /*MS masking & energy */ 316 | const III_psy_ratio (*masking)[2]; /*pointer to selected maskings */ 317 | const sample_t *inbuf[2]; 318 | 319 | FLOAT tot_ener[2][4]; 320 | FLOAT ms_ener_ratio[2] = { .5, .5 }; 321 | FLOAT pe[2][2] = { {0., 0.}, {0., 0.} }, pe_MS[2][2] = { { 322 | 0., 0.}, { 323 | 0., 0.}}; 324 | FLOAT (*pe_use)[2]; 325 | 326 | int ch, gr; 327 | 328 | inbuf[0] = inbuf_l; 329 | inbuf[1] = inbuf_r; 330 | 331 | if (gfc->lame_encode_frame_init == 0) { 332 | /*first run? */ 333 | lame_encode_frame_init(gfc, inbuf); 334 | 335 | } 336 | 337 | 338 | /********************** padding *****************************/ 339 | /* padding method as described in 340 | * "MPEG-Layer3 / Bitstream Syntax and Decoding" 341 | * by Martin Sieler, Ralph Sperschneider 342 | * 343 | * note: there is no padding for the very first frame 344 | * 345 | * Robert Hegemann 2000-06-22 346 | */ 347 | gfc->ov_enc.padding = FALSE; 348 | if ((gfc->sv_enc.slot_lag -= gfc->sv_enc.frac_SpF) < 0) { 349 | gfc->sv_enc.slot_lag += cfg->samplerate_out; 350 | gfc->ov_enc.padding = TRUE; 351 | } 352 | 353 | 354 | 355 | /**************************************** 356 | * Stage 1: psychoacoustic model * 357 | ****************************************/ 358 | 359 | { 360 | /* psychoacoustic model 361 | * psy model has a 1 granule (576) delay that we must compensate for 362 | * (mt 6/99). 363 | */ 364 | int ret; 365 | const sample_t *bufp[2] = {0, 0}; /* address of beginning of left & right granule */ 366 | int blocktype[2]; 367 | 368 | for (gr = 0; gr < cfg->mode_gr; gr++) { 369 | 370 | for (ch = 0; ch < cfg->channels_out; ch++) { 371 | bufp[ch] = &inbuf[ch][576 + gr * 576 - FFTOFFSET]; 372 | } 373 | ret = L3psycho_anal_vbr(gfc, bufp, gr, 374 | masking_LR, masking_MS, 375 | pe[gr], pe_MS[gr], tot_ener[gr], blocktype); 376 | if (ret != 0) 377 | return -4; 378 | 379 | if (cfg->mode == JOINT_STEREO) { 380 | ms_ener_ratio[gr] = tot_ener[gr][2] + tot_ener[gr][3]; 381 | if (ms_ener_ratio[gr] > 0) 382 | ms_ener_ratio[gr] = tot_ener[gr][3] / ms_ener_ratio[gr]; 383 | } 384 | 385 | /* block type flags */ 386 | for (ch = 0; ch < cfg->channels_out; ch++) { 387 | gr_info *const cod_info = &gfc->l3_side.tt[gr][ch]; 388 | cod_info->block_type = blocktype[ch]; 389 | cod_info->mixed_block_flag = 0; 390 | } 391 | } 392 | } 393 | 394 | 395 | /* auto-adjust of ATH, useful for low volume */ 396 | adjust_ATH(gfc); 397 | 398 | 399 | /**************************************** 400 | * Stage 2: MDCT * 401 | ****************************************/ 402 | 403 | /* polyphase filtering / mdct */ 404 | mdct_sub48(gfc, inbuf[0], inbuf[1]); 405 | 406 | 407 | /**************************************** 408 | * Stage 3: MS/LR decision * 409 | ****************************************/ 410 | 411 | /* Here will be selected MS or LR coding of the 2 stereo channels */ 412 | gfc->ov_enc.mode_ext = MPG_MD_LR_LR; 413 | 414 | if (cfg->force_ms) { 415 | gfc->ov_enc.mode_ext = MPG_MD_MS_LR; 416 | } 417 | else if (cfg->mode == JOINT_STEREO) { 418 | /* ms_ratio = is scaled, for historical reasons, to look like 419 | a ratio of side_channel / total. 420 | 0 = signal is 100% mono 421 | .5 = L & R uncorrelated 422 | */ 423 | 424 | /* [0] and [1] are the results for the two granules in MPEG-1, 425 | * in MPEG-2 it's only a faked averaging of the same value 426 | * _prev is the value of the last granule of the previous frame 427 | * _next is the value of the first granule of the next frame 428 | */ 429 | 430 | FLOAT sum_pe_MS = 0; 431 | FLOAT sum_pe_LR = 0; 432 | for (gr = 0; gr < cfg->mode_gr; gr++) { 433 | for (ch = 0; ch < cfg->channels_out; ch++) { 434 | sum_pe_MS += pe_MS[gr][ch]; 435 | sum_pe_LR += pe[gr][ch]; 436 | } 437 | } 438 | 439 | /* based on PE: M/S coding would not use much more bits than L/R */ 440 | if (sum_pe_MS <= 1.00 * sum_pe_LR) { 441 | 442 | gr_info const *const gi0 = &gfc->l3_side.tt[0][0]; 443 | gr_info const *const gi1 = &gfc->l3_side.tt[cfg->mode_gr - 1][0]; 444 | 445 | if (gi0[0].block_type == gi0[1].block_type && gi1[0].block_type == gi1[1].block_type) { 446 | 447 | gfc->ov_enc.mode_ext = MPG_MD_MS_LR; 448 | } 449 | } 450 | } 451 | 452 | /* bit and noise allocation */ 453 | if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR) { 454 | masking = (const III_psy_ratio (*)[2])masking_MS; /* use MS masking */ 455 | pe_use = pe_MS; 456 | } 457 | else { 458 | masking = (const III_psy_ratio (*)[2])masking_LR; /* use LR masking */ 459 | pe_use = pe; 460 | } 461 | 462 | 463 | /* copy data for MP3 frame analyzer */ 464 | if (cfg->analysis && gfc->pinfo != NULL) { 465 | for (gr = 0; gr < cfg->mode_gr; gr++) { 466 | for (ch = 0; ch < cfg->channels_out; ch++) { 467 | gfc->pinfo->ms_ratio[gr] = 0; 468 | gfc->pinfo->ms_ener_ratio[gr] = ms_ener_ratio[gr]; 469 | gfc->pinfo->blocktype[gr][ch] = gfc->l3_side.tt[gr][ch].block_type; 470 | gfc->pinfo->pe[gr][ch] = pe_use[gr][ch]; 471 | memcpy(gfc->pinfo->xr[gr][ch], &gfc->l3_side.tt[gr][ch].xr[0], sizeof(FLOAT) * 576); 472 | /* in psymodel, LR and MS data was stored in pinfo. 473 | switch to MS data: */ 474 | if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR) { 475 | gfc->pinfo->ers[gr][ch] = gfc->pinfo->ers[gr][ch + 2]; 476 | memcpy(gfc->pinfo->energy[gr][ch], gfc->pinfo->energy[gr][ch + 2], 477 | sizeof(gfc->pinfo->energy[gr][ch])); 478 | } 479 | } 480 | } 481 | } 482 | 483 | 484 | /**************************************** 485 | * Stage 4: quantization loop * 486 | ****************************************/ 487 | 488 | if (cfg->vbr == vbr_off || cfg->vbr == vbr_abr) { 489 | static FLOAT const fircoef[9] = { 490 | -0.0207887 * 5, -0.0378413 * 5, -0.0432472 * 5, -0.031183 * 5, 491 | 7.79609e-18 * 5, 0.0467745 * 5, 0.10091 * 5, 0.151365 * 5, 492 | 0.187098 * 5 493 | }; 494 | 495 | int i; 496 | FLOAT f; 497 | 498 | for (i = 0; i < 18; i++) 499 | gfc->sv_enc.pefirbuf[i] = gfc->sv_enc.pefirbuf[i + 1]; 500 | 501 | f = 0.0; 502 | for (gr = 0; gr < cfg->mode_gr; gr++) 503 | for (ch = 0; ch < cfg->channels_out; ch++) 504 | f += pe_use[gr][ch]; 505 | gfc->sv_enc.pefirbuf[18] = f; 506 | 507 | f = gfc->sv_enc.pefirbuf[9]; 508 | for (i = 0; i < 9; i++) 509 | f += (gfc->sv_enc.pefirbuf[i] + gfc->sv_enc.pefirbuf[18 - i]) * fircoef[i]; 510 | 511 | f = (670 * 5 * cfg->mode_gr * cfg->channels_out) / f; 512 | for (gr = 0; gr < cfg->mode_gr; gr++) { 513 | for (ch = 0; ch < cfg->channels_out; ch++) { 514 | pe_use[gr][ch] *= f; 515 | } 516 | } 517 | } 518 | gfc->iteration_loop(gfc, (const FLOAT (*)[2])pe_use, ms_ener_ratio, masking); 519 | 520 | 521 | /**************************************** 522 | * Stage 5: bitstream formatting * 523 | ****************************************/ 524 | 525 | 526 | /* write the frame to the bitstream */ 527 | (void) format_bitstream(gfc); 528 | 529 | /* copy mp3 bit buffer into array */ 530 | mp3count = copy_buffer(gfc, mp3buf, mp3buf_size, 1); 531 | 532 | 533 | if (cfg->write_lame_tag) { 534 | AddVbrFrame(gfc); 535 | } 536 | 537 | if (cfg->analysis && gfc->pinfo != NULL) { 538 | int framesize = 576 * cfg->mode_gr; 539 | for (ch = 0; ch < cfg->channels_out; ch++) { 540 | int j; 541 | for (j = 0; j < FFTOFFSET; j++) 542 | gfc->pinfo->pcmdata[ch][j] = gfc->pinfo->pcmdata[ch][j + framesize]; 543 | for (j = FFTOFFSET; j < 1600; j++) { 544 | gfc->pinfo->pcmdata[ch][j] = inbuf[ch][j - FFTOFFSET]; 545 | } 546 | } 547 | gfc->sv_qnt.masking_lower = 1.0; 548 | 549 | set_frame_pinfo(gfc, masking); 550 | } 551 | 552 | ++gfc->ov_enc.frame_number; 553 | 554 | updateStats(gfc); 555 | 556 | return mp3count; 557 | } 558 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/encoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * encoder.h include file 3 | * 4 | * Copyright (c) 2000 Mark Taylor 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Library General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Library General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Library General Public 17 | * License along with this library; if not, write to the 18 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 | * Boston, MA 02111-1307, USA. 20 | */ 21 | 22 | 23 | #ifndef LAME_ENCODER_H 24 | #define LAME_ENCODER_H 25 | 26 | /*********************************************************************** 27 | * 28 | * encoder and decoder delays 29 | * 30 | ***********************************************************************/ 31 | 32 | /* 33 | * layer III enc->dec delay: 1056 (1057?) (observed) 34 | * layer II enc->dec delay: 480 (481?) (observed) 35 | * 36 | * polyphase 256-16 (dec or enc) = 240 37 | * mdct 256+32 (9*32) (dec or enc) = 288 38 | * total: 512+16 39 | * 40 | * My guess is that delay of polyphase filterbank is actualy 240.5 41 | * (there are technical reasons for this, see postings in mp3encoder). 42 | * So total Encode+Decode delay = ENCDELAY + 528 + 1 43 | */ 44 | 45 | /* 46 | * ENCDELAY The encoder delay. 47 | * 48 | * Minimum allowed is MDCTDELAY (see below) 49 | * 50 | * The first 96 samples will be attenuated, so using a value less than 96 51 | * will result in corrupt data for the first 96-ENCDELAY samples. 52 | * 53 | * suggested: 576 54 | * set to 1160 to sync with FhG. 55 | */ 56 | 57 | #define ENCDELAY 576 58 | 59 | 60 | 61 | /* 62 | * make sure there is at least one complete frame after the 63 | * last frame containing real data 64 | * 65 | * Using a value of 288 would be sufficient for a 66 | * a very sophisticated decoder that can decode granule-by-granule instead 67 | * of frame by frame. But lets not assume this, and assume the decoder 68 | * will not decode frame N unless it also has data for frame N+1 69 | * 70 | */ 71 | /*#define POSTDELAY 288*/ 72 | #define POSTDELAY 1152 73 | 74 | 75 | 76 | /* 77 | * delay of the MDCT used in mdct.c 78 | * original ISO routines had a delay of 528! 79 | * Takehiro's routines: 80 | */ 81 | 82 | #define MDCTDELAY 48 83 | #define FFTOFFSET (224+MDCTDELAY) 84 | 85 | /* 86 | * Most decoders, including the one we use, have a delay of 528 samples. 87 | */ 88 | 89 | #define DECDELAY 528 90 | 91 | 92 | /* number of subbands */ 93 | #define SBLIMIT 32 94 | 95 | /* parition bands bands */ 96 | #define CBANDS 64 97 | 98 | /* number of critical bands/scale factor bands where masking is computed*/ 99 | #define SBPSY_l 21 100 | #define SBPSY_s 12 101 | 102 | /* total number of scalefactor bands encoded */ 103 | #define SBMAX_l 22 104 | #define SBMAX_s 13 105 | #define PSFB21 6 106 | #define PSFB12 6 107 | 108 | 109 | 110 | /* FFT sizes */ 111 | #define BLKSIZE 1024 112 | #define HBLKSIZE (BLKSIZE/2 + 1) 113 | #define BLKSIZE_s 256 114 | #define HBLKSIZE_s (BLKSIZE_s/2 + 1) 115 | 116 | 117 | /* #define switch_pe 1800 */ 118 | #define NORM_TYPE 0 119 | #define START_TYPE 1 120 | #define SHORT_TYPE 2 121 | #define STOP_TYPE 3 122 | 123 | /* 124 | * Mode Extention: 125 | * When we are in stereo mode, there are 4 possible methods to store these 126 | * two channels. The stereo modes -m? are using a subset of them. 127 | * 128 | * -ms: MPG_MD_LR_LR 129 | * -mj: MPG_MD_LR_LR and MPG_MD_MS_LR 130 | * -mf: MPG_MD_MS_LR 131 | * -mi: all 132 | */ 133 | #if 0 134 | #define MPG_MD_LR_LR 0 135 | #define MPG_MD_LR_I 1 136 | #define MPG_MD_MS_LR 2 137 | #define MPG_MD_MS_I 3 138 | #endif 139 | enum MPEGChannelMode 140 | { MPG_MD_LR_LR = 0 141 | , MPG_MD_LR_I = 1 142 | , MPG_MD_MS_LR = 2 143 | , MPG_MD_MS_I = 3 144 | }; 145 | 146 | #ifndef lame_internal_flags_defined 147 | #define lame_internal_flags_defined 148 | struct lame_internal_flags; 149 | typedef struct lame_internal_flags lame_internal_flags; 150 | #endif 151 | 152 | int lame_encode_mp3_frame(lame_internal_flags * gfc, 153 | sample_t const *inbuf_l, 154 | sample_t const *inbuf_r, unsigned char *mp3buf, int mp3buf_size); 155 | 156 | #endif /* LAME_ENCODER_H */ 157 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/fft.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** FFT and FHT routines 3 | ** Copyright 1988, 1993; Ron Mayer 4 | ** Copyright (c) 1999-2000 Takehiro Tominaga 5 | ** 6 | ** fht(fz,n); 7 | ** Does a hartley transform of "n" points in the array "fz". 8 | ** 9 | ** NOTE: This routine uses at least 2 patented algorithms, and may be 10 | ** under the restrictions of a bunch of different organizations. 11 | ** Although I wrote it completely myself; it is kind of a derivative 12 | ** of a routine I once authored and released under the GPL, so it 13 | ** may fall under the free software foundation's restrictions; 14 | ** it was worked on as a Stanford Univ project, so they claim 15 | ** some rights to it; it was further optimized at work here, so 16 | ** I think this company claims parts of it. The patents are 17 | ** held by R. Bracewell (the FHT algorithm) and O. Buneman (the 18 | ** trig generator), both at Stanford Univ. 19 | ** If it were up to me, I'd say go do whatever you want with it; 20 | ** but it would be polite to give credit to the following people 21 | ** if you use this anywhere: 22 | ** Euler - probable inventor of the fourier transform. 23 | ** Gauss - probable inventor of the FFT. 24 | ** Hartley - probable inventor of the hartley transform. 25 | ** Buneman - for a really cool trig generator 26 | ** Mayer(me) - for authoring this particular version and 27 | ** including all the optimizations in one package. 28 | ** Thanks, 29 | ** Ron Mayer; mayer@acuson.com 30 | ** and added some optimization by 31 | ** Mather - idea of using lookup table 32 | ** Takehiro - some dirty hack for speed up 33 | */ 34 | 35 | /* $Id: fft.c,v 1.38 2009/04/20 21:48:00 robert Exp $ */ 36 | 37 | #ifdef HAVE_CONFIG_H 38 | # include 39 | #endif 40 | 41 | #include "lame.h" 42 | #include "machine.h" 43 | #include "encoder.h" 44 | #include "util.h" 45 | #include "fft.h" 46 | 47 | //#include "vector/lame_intrin.h" 48 | 49 | 50 | 51 | #define TRI_SIZE (5-1) /* 1024 = 4**5 */ 52 | 53 | /* fft.c */ 54 | static FLOAT window[BLKSIZE], window_s[BLKSIZE_s / 2]; 55 | 56 | static const FLOAT costab[TRI_SIZE * 2] = { 57 | 9.238795325112867e-01, 3.826834323650898e-01, 58 | 9.951847266721969e-01, 9.801714032956060e-02, 59 | 9.996988186962042e-01, 2.454122852291229e-02, 60 | 9.999811752826011e-01, 6.135884649154475e-03 61 | }; 62 | 63 | static void 64 | fht(FLOAT * fz, int n) 65 | { 66 | const FLOAT *tri = costab; 67 | int k4; 68 | FLOAT *fi, *gi; 69 | FLOAT const *fn; 70 | 71 | n <<= 1; /* to get BLKSIZE, because of 3DNow! ASM routine */ 72 | fn = fz + n; 73 | k4 = 4; 74 | do { 75 | FLOAT s1, c1; 76 | int i, k1, k2, k3, kx; 77 | kx = k4 >> 1; 78 | k1 = k4; 79 | k2 = k4 << 1; 80 | k3 = k2 + k1; 81 | k4 = k2 << 1; 82 | fi = fz; 83 | gi = fi + kx; 84 | do { 85 | FLOAT f0, f1, f2, f3; 86 | f1 = fi[0] - fi[k1]; 87 | f0 = fi[0] + fi[k1]; 88 | f3 = fi[k2] - fi[k3]; 89 | f2 = fi[k2] + fi[k3]; 90 | fi[k2] = f0 - f2; 91 | fi[0] = f0 + f2; 92 | fi[k3] = f1 - f3; 93 | fi[k1] = f1 + f3; 94 | f1 = gi[0] - gi[k1]; 95 | f0 = gi[0] + gi[k1]; 96 | f3 = SQRT2 * gi[k3]; 97 | f2 = SQRT2 * gi[k2]; 98 | gi[k2] = f0 - f2; 99 | gi[0] = f0 + f2; 100 | gi[k3] = f1 - f3; 101 | gi[k1] = f1 + f3; 102 | gi += k4; 103 | fi += k4; 104 | } while (fi < fn); 105 | c1 = tri[0]; 106 | s1 = tri[1]; 107 | for (i = 1; i < kx; i++) { 108 | FLOAT c2, s2; 109 | c2 = 1 - (2 * s1) * s1; 110 | s2 = (2 * s1) * c1; 111 | fi = fz + i; 112 | gi = fz + k1 - i; 113 | do { 114 | FLOAT a, b, g0, f0, f1, g1, f2, g2, f3, g3; 115 | b = s2 * fi[k1] - c2 * gi[k1]; 116 | a = c2 * fi[k1] + s2 * gi[k1]; 117 | f1 = fi[0] - a; 118 | f0 = fi[0] + a; 119 | g1 = gi[0] - b; 120 | g0 = gi[0] + b; 121 | b = s2 * fi[k3] - c2 * gi[k3]; 122 | a = c2 * fi[k3] + s2 * gi[k3]; 123 | f3 = fi[k2] - a; 124 | f2 = fi[k2] + a; 125 | g3 = gi[k2] - b; 126 | g2 = gi[k2] + b; 127 | b = s1 * f2 - c1 * g3; 128 | a = c1 * f2 + s1 * g3; 129 | fi[k2] = f0 - a; 130 | fi[0] = f0 + a; 131 | gi[k3] = g1 - b; 132 | gi[k1] = g1 + b; 133 | b = c1 * g2 - s1 * f3; 134 | a = s1 * g2 + c1 * f3; 135 | gi[k2] = g0 - a; 136 | gi[0] = g0 + a; 137 | fi[k3] = f1 - b; 138 | fi[k1] = f1 + b; 139 | gi += k4; 140 | fi += k4; 141 | } while (fi < fn); 142 | c2 = c1; 143 | c1 = c2 * tri[0] - s1 * tri[1]; 144 | s1 = c2 * tri[1] + s1 * tri[0]; 145 | } 146 | tri += 2; 147 | } while (k4 < n); 148 | } 149 | 150 | 151 | static const unsigned char rv_tbl[] = { 152 | 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 153 | 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, 154 | 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 155 | 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 156 | 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 157 | 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 158 | 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 159 | 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 160 | 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 161 | 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 162 | 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, 163 | 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 164 | 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 165 | 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, 166 | 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 167 | 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe 168 | }; 169 | 170 | #define ch01(index) (buffer[chn][index]) 171 | 172 | #define ml00(f) (window[i ] * f(i)) 173 | #define ml10(f) (window[i + 0x200] * f(i + 0x200)) 174 | #define ml20(f) (window[i + 0x100] * f(i + 0x100)) 175 | #define ml30(f) (window[i + 0x300] * f(i + 0x300)) 176 | 177 | #define ml01(f) (window[i + 0x001] * f(i + 0x001)) 178 | #define ml11(f) (window[i + 0x201] * f(i + 0x201)) 179 | #define ml21(f) (window[i + 0x101] * f(i + 0x101)) 180 | #define ml31(f) (window[i + 0x301] * f(i + 0x301)) 181 | 182 | #define ms00(f) (window_s[i ] * f(i + k)) 183 | #define ms10(f) (window_s[0x7f - i] * f(i + k + 0x80)) 184 | #define ms20(f) (window_s[i + 0x40] * f(i + k + 0x40)) 185 | #define ms30(f) (window_s[0x3f - i] * f(i + k + 0xc0)) 186 | 187 | #define ms01(f) (window_s[i + 0x01] * f(i + k + 0x01)) 188 | #define ms11(f) (window_s[0x7e - i] * f(i + k + 0x81)) 189 | #define ms21(f) (window_s[i + 0x41] * f(i + k + 0x41)) 190 | #define ms31(f) (window_s[0x3e - i] * f(i + k + 0xc1)) 191 | 192 | 193 | void 194 | fft_short(lame_internal_flags const *const gfc, 195 | FLOAT x_real[3][BLKSIZE_s], int chn, const sample_t *const buffer[2]) 196 | { 197 | int i; 198 | int j; 199 | int b; 200 | 201 | for (b = 0; b < 3; b++) { 202 | FLOAT *x = &x_real[b][BLKSIZE_s / 2]; 203 | short const k = (576 / 3) * (b + 1); 204 | j = BLKSIZE_s / 8 - 1; 205 | do { 206 | FLOAT f0, f1, f2, f3, w; 207 | 208 | i = rv_tbl[j << 2]; 209 | 210 | f0 = ms00(ch01); 211 | w = ms10(ch01); 212 | f1 = f0 - w; 213 | f0 = f0 + w; 214 | f2 = ms20(ch01); 215 | w = ms30(ch01); 216 | f3 = f2 - w; 217 | f2 = f2 + w; 218 | 219 | x -= 4; 220 | x[0] = f0 + f2; 221 | x[2] = f0 - f2; 222 | x[1] = f1 + f3; 223 | x[3] = f1 - f3; 224 | 225 | f0 = ms01(ch01); 226 | w = ms11(ch01); 227 | f1 = f0 - w; 228 | f0 = f0 + w; 229 | f2 = ms21(ch01); 230 | w = ms31(ch01); 231 | f3 = f2 - w; 232 | f2 = f2 + w; 233 | 234 | x[BLKSIZE_s / 2 + 0] = f0 + f2; 235 | x[BLKSIZE_s / 2 + 2] = f0 - f2; 236 | x[BLKSIZE_s / 2 + 1] = f1 + f3; 237 | x[BLKSIZE_s / 2 + 3] = f1 - f3; 238 | } while (--j >= 0); 239 | 240 | gfc->fft_fht(x, BLKSIZE_s / 2); 241 | /* BLKSIZE_s/2 because of 3DNow! ASM routine */ 242 | } 243 | } 244 | 245 | void 246 | fft_long(lame_internal_flags const *const gfc, 247 | FLOAT x[BLKSIZE], int chn, const sample_t *const buffer[2]) 248 | { 249 | int i; 250 | int jj = BLKSIZE / 8 - 1; 251 | x += BLKSIZE / 2; 252 | 253 | do { 254 | FLOAT f0, f1, f2, f3, w; 255 | 256 | i = rv_tbl[jj]; 257 | f0 = ml00(ch01); 258 | w = ml10(ch01); 259 | f1 = f0 - w; 260 | f0 = f0 + w; 261 | f2 = ml20(ch01); 262 | w = ml30(ch01); 263 | f3 = f2 - w; 264 | f2 = f2 + w; 265 | 266 | x -= 4; 267 | x[0] = f0 + f2; 268 | x[2] = f0 - f2; 269 | x[1] = f1 + f3; 270 | x[3] = f1 - f3; 271 | 272 | f0 = ml01(ch01); 273 | w = ml11(ch01); 274 | f1 = f0 - w; 275 | f0 = f0 + w; 276 | f2 = ml21(ch01); 277 | w = ml31(ch01); 278 | f3 = f2 - w; 279 | f2 = f2 + w; 280 | 281 | x[BLKSIZE / 2 + 0] = f0 + f2; 282 | x[BLKSIZE / 2 + 2] = f0 - f2; 283 | x[BLKSIZE / 2 + 1] = f1 + f3; 284 | x[BLKSIZE / 2 + 3] = f1 - f3; 285 | } while (--jj >= 0); 286 | 287 | gfc->fft_fht(x, BLKSIZE / 2); 288 | /* BLKSIZE/2 because of 3DNow! ASM routine */ 289 | } 290 | 291 | #ifdef HAVE_NASM 292 | extern void fht_3DN(FLOAT * fz, int n); 293 | extern void fht_SSE(FLOAT * fz, int n); 294 | #endif 295 | 296 | void 297 | init_fft(lame_internal_flags * const gfc) 298 | { 299 | int i; 300 | 301 | /* The type of window used here will make no real difference, but */ 302 | /* in the interest of merging nspsytune stuff - switch to blackman window */ 303 | for (i = 0; i < BLKSIZE; i++) 304 | /* blackman window */ 305 | window[i] = 0.42 - 0.5 * cos(2 * PI * (i + .5) / BLKSIZE) + 306 | 0.08 * cos(4 * PI * (i + .5) / BLKSIZE); 307 | 308 | for (i = 0; i < BLKSIZE_s / 2; i++) 309 | window_s[i] = 0.5 * (1.0 - cos(2.0 * PI * (i + 0.5) / BLKSIZE_s)); 310 | 311 | gfc->fft_fht = fht; 312 | #ifdef HAVE_NASM 313 | if (gfc->CPU_features.AMD_3DNow) { 314 | gfc->fft_fht = fht_3DN; 315 | } 316 | else if (gfc->CPU_features.SSE) { 317 | gfc->fft_fht = fht_SSE; 318 | } 319 | else { 320 | gfc->fft_fht = fht; 321 | } 322 | #else 323 | #ifdef HAVE_XMMINTRIN_H 324 | #ifdef MIN_ARCH_SSE 325 | gfc->fft_fht = fht_SSE2; 326 | #endif 327 | #endif 328 | #endif 329 | } 330 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/fft.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Fast Fourier Transform include file 3 | * 4 | * Copyright (c) 2000 Mark Taylor 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Library General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Library General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Library General Public 17 | * License along with this library; if not, write to the 18 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 | * Boston, MA 02111-1307, USA. 20 | */ 21 | 22 | #ifndef LAME_FFT_H 23 | #define LAME_FFT_H 24 | 25 | void fft_long(lame_internal_flags const *const gfc, FLOAT x_real[BLKSIZE], 26 | int chn, const sample_t *const data[2]); 27 | 28 | void fft_short(lame_internal_flags const *const gfc, FLOAT x_real[3][BLKSIZE_s], 29 | int chn, const sample_t *const data[2]); 30 | 31 | void init_fft(lame_internal_flags * const gfc); 32 | 33 | #endif 34 | 35 | /* End of fft.h */ 36 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/gain_analysis.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ReplayGainAnalysis - analyzes input samples and give the recommended dB change 3 | * Copyright (C) 2001 David Robinson and Glen Sawyer 4 | * 5 | * This library is free software; you can redistribute it and/or 6 | * modify it under the terms of the GNU Lesser General Public 7 | * License as published by the Free Software Foundation; either 8 | * version 2.1 of the License, or (at your option) any later version. 9 | * 10 | * This library is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * Lesser General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public 16 | * License along with this library; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | * 19 | * concept and filter values by David Robinson (David@Robinson.org) 20 | * -- blame him if you think the idea is flawed 21 | * coding by Glen Sawyer (mp3gain@hotmail.com) 735 W 255 N, Orem, UT 84057-4505 USA 22 | * -- blame him if you think this runs too slowly, or the coding is otherwise flawed 23 | * 24 | * For an explanation of the concepts and the basic algorithms involved, go to: 25 | * http://www.replaygain.org/ 26 | */ 27 | 28 | #ifndef GAIN_ANALYSIS_H 29 | #define GAIN_ANALYSIS_H 30 | 31 | #ifdef HAVE_INTTYPES_H 32 | # include 33 | #else 34 | # ifdef HAVE_STDINT_H 35 | # include 36 | # endif 37 | #endif 38 | 39 | #ifdef __cplusplus 40 | extern "C" { 41 | #endif 42 | 43 | 44 | typedef sample_t Float_t; /* Type used for filtering */ 45 | 46 | 47 | #define PINK_REF 64.82 /* 298640883795 */ /* calibration value for 89dB */ 48 | 49 | 50 | #define YULE_ORDER 10 51 | #define BUTTER_ORDER 2 52 | #define YULE_FILTER filterYule 53 | #define BUTTER_FILTER filterButter 54 | #define RMS_PERCENTILE 0.95 /* percentile which is louder than the proposed level */ 55 | #define MAX_SAMP_FREQ 48000L /* maximum allowed sample frequency [Hz] */ 56 | #define RMS_WINDOW_TIME_NUMERATOR 1L 57 | #define RMS_WINDOW_TIME_DENOMINATOR 20L /* numerator / denominator = time slice size [s] */ 58 | #define STEPS_per_dB 100 /* Table entries per dB */ 59 | #define MAX_dB 120 /* Table entries for 0...MAX_dB (normal max. values are 70...80 dB) */ 60 | 61 | enum { GAIN_NOT_ENOUGH_SAMPLES = -24601, GAIN_ANALYSIS_ERROR = 0, GAIN_ANALYSIS_OK = 62 | 1, INIT_GAIN_ANALYSIS_ERROR = 0, INIT_GAIN_ANALYSIS_OK = 1 63 | }; 64 | 65 | enum { MAX_ORDER = (BUTTER_ORDER > YULE_ORDER ? BUTTER_ORDER : YULE_ORDER) 66 | , MAX_SAMPLES_PER_WINDOW = ((MAX_SAMP_FREQ * RMS_WINDOW_TIME_NUMERATOR) / RMS_WINDOW_TIME_DENOMINATOR + 1) /* max. Samples per Time slice */ 67 | }; 68 | 69 | struct replaygain_data { 70 | Float_t linprebuf[MAX_ORDER * 2]; 71 | Float_t *linpre; /* left input samples, with pre-buffer */ 72 | Float_t lstepbuf[MAX_SAMPLES_PER_WINDOW + MAX_ORDER]; 73 | Float_t *lstep; /* left "first step" (i.e. post first filter) samples */ 74 | Float_t loutbuf[MAX_SAMPLES_PER_WINDOW + MAX_ORDER]; 75 | Float_t *lout; /* left "out" (i.e. post second filter) samples */ 76 | Float_t rinprebuf[MAX_ORDER * 2]; 77 | Float_t *rinpre; /* right input samples ... */ 78 | Float_t rstepbuf[MAX_SAMPLES_PER_WINDOW + MAX_ORDER]; 79 | Float_t *rstep; 80 | Float_t routbuf[MAX_SAMPLES_PER_WINDOW + MAX_ORDER]; 81 | Float_t *rout; 82 | long sampleWindow; /* number of samples required to reach number of milliseconds required for RMS window */ 83 | long totsamp; 84 | double lsum; 85 | double rsum; 86 | int freqindex; 87 | int first; 88 | uint32_t A[STEPS_per_dB * MAX_dB]; 89 | uint32_t B[STEPS_per_dB * MAX_dB]; 90 | 91 | }; 92 | #ifndef replaygain_data_defined 93 | #define replaygain_data_defined 94 | typedef struct replaygain_data replaygain_t; 95 | #endif 96 | 97 | 98 | 99 | 100 | int InitGainAnalysis(replaygain_t * rgData, long samplefreq); 101 | int AnalyzeSamples(replaygain_t * rgData, const Float_t * left_samples, 102 | const Float_t * right_samples, size_t num_samples, int num_channels); 103 | Float_t GetTitleGain(replaygain_t * rgData); 104 | 105 | 106 | #ifdef __cplusplus 107 | } 108 | #endif 109 | #endif /* GAIN_ANALYSIS_H */ 110 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/id3tag.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef LAME_ID3_H 3 | #define LAME_ID3_H 4 | 5 | 6 | #define CHANGED_FLAG (1U << 0) 7 | #define ADD_V2_FLAG (1U << 1) 8 | #define V1_ONLY_FLAG (1U << 2) 9 | #define V2_ONLY_FLAG (1U << 3) 10 | #define SPACE_V1_FLAG (1U << 4) 11 | #define PAD_V2_FLAG (1U << 5) 12 | 13 | enum { 14 | MIMETYPE_NONE = 0, 15 | MIMETYPE_JPEG, 16 | MIMETYPE_PNG, 17 | MIMETYPE_GIF, 18 | }; 19 | 20 | typedef struct FrameDataNode { 21 | struct FrameDataNode *nxt; 22 | uint32_t fid; /* Frame Identifier */ 23 | char lng[4]; /* 3-character language descriptor */ 24 | struct { 25 | union { 26 | char *l; /* ptr to Latin-1 chars */ 27 | unsigned short *u; /* ptr to UCS-2 text */ 28 | unsigned char *b; /* ptr to raw bytes */ 29 | } ptr; 30 | size_t dim; 31 | int enc; /* 0:Latin-1, 1:UCS-2, 2:RAW */ 32 | } dsc , txt; 33 | } FrameDataNode; 34 | 35 | 36 | typedef struct id3tag_spec { 37 | /* private data members */ 38 | unsigned int flags; 39 | int year; 40 | char *title; 41 | char *artist; 42 | char *album; 43 | char *comment; 44 | int track_id3v1; 45 | int genre_id3v1; 46 | unsigned char *albumart; 47 | unsigned int albumart_size; 48 | unsigned int padding_size; 49 | int albumart_mimetype; 50 | FrameDataNode *v2_head, *v2_tail; 51 | } id3tag_spec; 52 | 53 | 54 | /* write tag into stream at current position */ 55 | extern int id3tag_write_v2(lame_global_flags * gfp); 56 | extern int id3tag_write_v1(lame_global_flags * gfp); 57 | /* 58 | * NOTE: A version 2 tag will NOT be added unless one of the text fields won't 59 | * fit in a version 1 tag (e.g. the title string is longer than 30 characters), 60 | * or the "id3tag_add_v2" or "id3tag_v2_only" functions are used. 61 | */ 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/l3side.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Layer 3 side include file 3 | * 4 | * Copyright (c) 1999 Mark Taylor 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Library General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Library General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Library General Public 17 | * License along with this library; if not, write to the 18 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 | * Boston, MA 02111-1307, USA. 20 | */ 21 | 22 | #ifndef LAME_L3SIDE_H 23 | #define LAME_L3SIDE_H 24 | 25 | /* max scalefactor band, max(SBMAX_l, SBMAX_s*3, (SBMAX_s-3)*3+8) */ 26 | #define SFBMAX (SBMAX_s*3) 27 | 28 | /* Layer III side information. */ 29 | typedef struct { 30 | int l[1 + SBMAX_l]; 31 | int s[1 + SBMAX_s]; 32 | int psfb21[1 + PSFB21]; 33 | int psfb12[1 + PSFB12]; 34 | } scalefac_struct; 35 | 36 | 37 | typedef struct { 38 | FLOAT l[SBMAX_l]; 39 | FLOAT s[SBMAX_s][3]; 40 | } III_psy_xmin; 41 | 42 | typedef struct { 43 | III_psy_xmin thm; 44 | III_psy_xmin en; 45 | } III_psy_ratio; 46 | 47 | typedef struct { 48 | FLOAT xr[576]; 49 | int l3_enc[576]; 50 | int scalefac[SFBMAX]; 51 | FLOAT xrpow_max; 52 | 53 | int part2_3_length; 54 | int big_values; 55 | int count1; 56 | int global_gain; 57 | int scalefac_compress; 58 | int block_type; 59 | int mixed_block_flag; 60 | int table_select[3]; 61 | int subblock_gain[3 + 1]; 62 | int region0_count; 63 | int region1_count; 64 | int preflag; 65 | int scalefac_scale; 66 | int count1table_select; 67 | 68 | int part2_length; 69 | int sfb_lmax; 70 | int sfb_smin; 71 | int psy_lmax; 72 | int sfbmax; 73 | int psymax; 74 | int sfbdivide; 75 | int width[SFBMAX]; 76 | int window[SFBMAX]; 77 | int count1bits; 78 | /* added for LSF */ 79 | const int *sfb_partition_table; 80 | int slen[4]; 81 | 82 | int max_nonzero_coeff; 83 | char energy_above_cutoff[SFBMAX]; 84 | } gr_info; 85 | 86 | typedef struct { 87 | gr_info tt[2][2]; 88 | int main_data_begin; 89 | int private_bits; 90 | int resvDrain_pre; 91 | int resvDrain_post; 92 | int scfsi[2][4]; 93 | } III_side_info_t; 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/lame-analysis.h: -------------------------------------------------------------------------------- 1 | /* 2 | * GTK plotting routines source file 3 | * 4 | * Copyright (c) 1999 Mark Taylor 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Library General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Library General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Library General Public 17 | * License along with this library; if not, write to the 18 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 | * Boston, MA 02111-1307, USA. 20 | */ 21 | 22 | #ifndef LAME_GTKANAL_H 23 | #define LAME_GTKANAL_H 24 | 25 | 26 | #define READ_AHEAD 40 /* number of frames to read ahead */ 27 | #define MAXMPGLAG READ_AHEAD /* if the mpg123 lag becomes bigger than this 28 | we have to stop */ 29 | #define NUMBACK 6 /* number of frames we can back up */ 30 | #define NUMPINFO (NUMBACK+READ_AHEAD+1) 31 | 32 | 33 | 34 | struct plotting_data { 35 | int frameNum; /* current frame number */ 36 | int frameNum123; 37 | int num_samples; /* number of pcm samples read for this frame */ 38 | double frametime; /* starting time of frame, in seconds */ 39 | double pcmdata[2][1600]; 40 | double pcmdata2[2][1152 + 1152 - DECDELAY]; 41 | double xr[2][2][576]; 42 | double mpg123xr[2][2][576]; 43 | double ms_ratio[2]; 44 | double ms_ener_ratio[2]; 45 | 46 | /* L,R, M and S values */ 47 | double energy_save[4][BLKSIZE]; /* psymodel is one ahead */ 48 | double energy[2][4][BLKSIZE]; 49 | double pe[2][4]; 50 | double thr[2][4][SBMAX_l]; 51 | double en[2][4][SBMAX_l]; 52 | double thr_s[2][4][3 * SBMAX_s]; 53 | double en_s[2][4][3 * SBMAX_s]; 54 | double ers_save[4]; /* psymodel is one ahead */ 55 | double ers[2][4]; 56 | 57 | double sfb[2][2][SBMAX_l]; 58 | double sfb_s[2][2][3 * SBMAX_s]; 59 | double LAMEsfb[2][2][SBMAX_l]; 60 | double LAMEsfb_s[2][2][3 * SBMAX_s]; 61 | 62 | int LAMEqss[2][2]; 63 | int qss[2][2]; 64 | int big_values[2][2]; 65 | int sub_gain[2][2][3]; 66 | 67 | double xfsf[2][2][SBMAX_l]; 68 | double xfsf_s[2][2][3 * SBMAX_s]; 69 | 70 | int over[2][2]; 71 | double tot_noise[2][2]; 72 | double max_noise[2][2]; 73 | double over_noise[2][2]; 74 | int over_SSD[2][2]; 75 | int blocktype[2][2]; 76 | int scalefac_scale[2][2]; 77 | int preflag[2][2]; 78 | int mpg123blocktype[2][2]; 79 | int mixed[2][2]; 80 | int mainbits[2][2]; 81 | int sfbits[2][2]; 82 | int LAMEmainbits[2][2]; 83 | int LAMEsfbits[2][2]; 84 | int framesize, stereo, js, ms_stereo, i_stereo, emph, bitrate, sampfreq, maindata; 85 | int crc, padding; 86 | int scfsi[2], mean_bits, resvsize; 87 | int totbits; 88 | }; 89 | #ifndef plotting_data_defined 90 | #define plotting_data_defined 91 | typedef struct plotting_data plotting_data; 92 | #endif 93 | #if 0 94 | extern plotting_data *pinfo; 95 | #endif 96 | #endif 97 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/lame_global_flags.h: -------------------------------------------------------------------------------- 1 | #ifndef LAME_GLOBAL_FLAGS_H 2 | #define LAME_GLOBAL_FLAGS_H 3 | 4 | #ifndef lame_internal_flags_defined 5 | #define lame_internal_flags_defined 6 | struct lame_internal_flags; 7 | typedef struct lame_internal_flags lame_internal_flags; 8 | #endif 9 | 10 | 11 | typedef enum short_block_e { 12 | short_block_not_set = -1, /* allow LAME to decide */ 13 | short_block_allowed = 0, /* LAME may use them, even different block types for L/R */ 14 | short_block_coupled, /* LAME may use them, but always same block types in L/R */ 15 | short_block_dispensed, /* LAME will not use short blocks, long blocks only */ 16 | short_block_forced /* LAME will not use long blocks, short blocks only */ 17 | } short_block_t; 18 | 19 | /*********************************************************************** 20 | * 21 | * Control Parameters set by User. These parameters are here for 22 | * backwards compatibility with the old, non-shared lib API. 23 | * Please use the lame_set_variablename() functions below 24 | * 25 | * 26 | ***********************************************************************/ 27 | struct lame_global_struct { 28 | unsigned int class_id; 29 | 30 | /* input description */ 31 | unsigned long num_samples; /* number of samples. default=2^32-1 */ 32 | int num_channels; /* input number of channels. default=2 */ 33 | int samplerate_in; /* input_samp_rate in Hz. default=44.1 kHz */ 34 | int samplerate_out; /* output_samp_rate. 35 | default: LAME picks best value 36 | at least not used for MP3 decoding: 37 | Remember 44.1 kHz MP3s and AC97 */ 38 | float scale; /* scale input by this amount before encoding 39 | at least not used for MP3 decoding */ 40 | float scale_left; /* scale input of channel 0 (left) by this 41 | amount before encoding */ 42 | float scale_right; /* scale input of channel 1 (right) by this 43 | amount before encoding */ 44 | 45 | /* general control params */ 46 | int analysis; /* collect data for a MP3 frame analyzer? */ 47 | int write_lame_tag; /* add Xing VBR tag? */ 48 | int decode_only; /* use lame/mpglib to convert mp3 to wav */ 49 | int quality; /* quality setting 0=best, 9=worst default=5 */ 50 | MPEG_mode mode; /* see enum in lame.h 51 | default = LAME picks best value */ 52 | int force_ms; /* force M/S mode. requires mode=1 */ 53 | int free_format; /* use free format? default=0 */ 54 | int findReplayGain; /* find the RG value? default=0 */ 55 | int decode_on_the_fly; /* decode on the fly? default=0 */ 56 | int write_id3tag_automatic; /* 1 (default) writes ID3 tags, 0 not */ 57 | 58 | int nogap_total; 59 | int nogap_current; 60 | 61 | int substep_shaping; 62 | int noise_shaping; 63 | int subblock_gain; /* 0 = no, 1 = yes */ 64 | int use_best_huffman; /* 0 = no. 1=outside loop 2=inside loop(slow) */ 65 | 66 | /* 67 | * set either brate>0 or compression_ratio>0, LAME will compute 68 | * the value of the variable not set. 69 | * Default is compression_ratio = 11.025 70 | */ 71 | int brate; /* bitrate */ 72 | float compression_ratio; /* sizeof(wav file)/sizeof(mp3 file) */ 73 | 74 | 75 | /* frame params */ 76 | int copyright; /* mark as copyright. default=0 */ 77 | int original; /* mark as original. default=1 */ 78 | int extension; /* the MP3 'private extension' bit. 79 | Meaningless */ 80 | int emphasis; /* Input PCM is emphased PCM (for 81 | instance from one of the rarely 82 | emphased CDs), it is STRONGLY not 83 | recommended to use this, because 84 | psycho does not take it into account, 85 | and last but not least many decoders 86 | don't care about these bits */ 87 | int error_protection; /* use 2 bytes per frame for a CRC 88 | checksum. default=0 */ 89 | int strict_ISO; /* enforce ISO spec as much as possible */ 90 | 91 | int disable_reservoir; /* use bit reservoir? */ 92 | 93 | /* quantization/noise shaping */ 94 | int quant_comp; 95 | int quant_comp_short; 96 | int experimentalY; 97 | int experimentalZ; 98 | int exp_nspsytune; 99 | 100 | int preset; 101 | 102 | /* VBR control */ 103 | vbr_mode VBR; 104 | float VBR_q_frac; /* Range [0,...,1[ */ 105 | int VBR_q; /* Range [0,...,9] */ 106 | int VBR_mean_bitrate_kbps; 107 | int VBR_min_bitrate_kbps; 108 | int VBR_max_bitrate_kbps; 109 | int VBR_hard_min; /* strictly enforce VBR_min_bitrate 110 | normaly, it will be violated for analog 111 | silence */ 112 | 113 | 114 | /* resampling and filtering */ 115 | int lowpassfreq; /* freq in Hz. 0=lame choses. 116 | -1=no filter */ 117 | int highpassfreq; /* freq in Hz. 0=lame choses. 118 | -1=no filter */ 119 | int lowpasswidth; /* freq width of filter, in Hz 120 | (default=15%) */ 121 | int highpasswidth; /* freq width of filter, in Hz 122 | (default=15%) */ 123 | 124 | 125 | 126 | /* 127 | * psycho acoustics and other arguments which you should not change 128 | * unless you know what you are doing 129 | */ 130 | float maskingadjust; 131 | float maskingadjust_short; 132 | int ATHonly; /* only use ATH */ 133 | int ATHshort; /* only use ATH for short blocks */ 134 | int noATH; /* disable ATH */ 135 | int ATHtype; /* select ATH formula */ 136 | float ATHcurve; /* change ATH formula 4 shape */ 137 | float ATH_lower_db; /* lower ATH by this many db */ 138 | int athaa_type; /* select ATH auto-adjust scheme */ 139 | float athaa_sensitivity; /* dB, tune active region of auto-level */ 140 | short_block_t short_blocks; 141 | int useTemporal; /* use temporal masking effect */ 142 | float interChRatio; 143 | float msfix; /* Naoki's adjustment of Mid/Side maskings */ 144 | 145 | int tune; /* 0 off, 1 on */ 146 | float tune_value_a; /* used to pass values for debugging and stuff */ 147 | 148 | float attackthre; /* attack threshold for L/R/M channel */ 149 | float attackthre_s; /* attack threshold for S channel */ 150 | 151 | 152 | struct { 153 | void (*msgf) (const char *format, va_list ap); 154 | void (*debugf) (const char *format, va_list ap); 155 | void (*errorf) (const char *format, va_list ap); 156 | } report; 157 | 158 | /************************************************************************/ 159 | /* internal variables, do not set... */ 160 | /* provided because they may be of use to calling application */ 161 | /************************************************************************/ 162 | 163 | int lame_allocated_gfp; /* is this struct owned by calling 164 | program or lame? */ 165 | 166 | 167 | 168 | /**************************************************************************/ 169 | /* more internal variables are stored in this structure: */ 170 | /**************************************************************************/ 171 | lame_internal_flags *internal_flags; 172 | 173 | 174 | struct { 175 | int mmx; 176 | int amd3dnow; 177 | int sse; 178 | 179 | } asm_optimizations; 180 | }; 181 | 182 | int is_lame_global_flags_valid(const lame_global_flags * gfp); 183 | 184 | #endif /* LAME_GLOBAL_FLAGS_H */ 185 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/lameerror.h: -------------------------------------------------------------------------------- 1 | /* 2 | * A collection of LAME Error Codes 3 | * 4 | * Please use the constants defined here instead of some arbitrary 5 | * values. Currently the values starting at -10 to avoid intersection 6 | * with the -1, -2, -3 and -4 used in the current code. 7 | * 8 | * May be this should be a part of the include/lame.h. 9 | */ 10 | 11 | typedef enum { 12 | LAME_OKAY = 0, 13 | LAME_NOERROR = 0, 14 | LAME_GENERICERROR = -1, 15 | LAME_NOMEM = -10, 16 | LAME_BADBITRATE = -11, 17 | LAME_BADSAMPFREQ = -12, 18 | LAME_INTERNALERROR = -13, 19 | 20 | FRONTEND_READERROR = -80, 21 | FRONTEND_WRITEERROR = -81, 22 | FRONTEND_FILETOOLARGE = -82, 23 | 24 | } lame_errorcodes_t; 25 | 26 | /* end of lameerror.h */ 27 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/machine.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Machine dependent defines/includes for LAME. 3 | * 4 | * Copyright (c) 1999 A.L. Faber 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Library General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Library General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Library General Public 17 | * License along with this library; if not, write to the 18 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 | * Boston, MA 02111-1307, USA. 20 | */ 21 | 22 | #ifndef LAME_MACHINE_H 23 | #define LAME_MACHINE_H 24 | 25 | #include "version.h" 26 | 27 | #if (LAME_RELEASE_VERSION == 0) 28 | #undef NDEBUG 29 | #endif 30 | 31 | #include 32 | #include 33 | 34 | #ifdef STDC_HEADERS 35 | # include 36 | # include 37 | #else 38 | /*# ifndef HAVE_STRCHR 39 | # define strchr index 40 | # define strrchr rindex 41 | # endif*/ 42 | char *strchr(), *strrchr(); 43 | /*# ifndef HAVE_MEMCPY 44 | # define memcpy(d, s, n) bcopy ((s), (d), (n)) 45 | # define memmove(d, s, n) bcopy ((s), (d), (n)) 46 | # endif*/ 47 | #endif 48 | 49 | #if defined(__riscos__) && defined(FPA10) 50 | # include "ymath.h" 51 | #else 52 | # include 53 | #endif 54 | #include 55 | 56 | #include 57 | 58 | #ifdef HAVE_ERRNO_H 59 | # include 60 | #endif 61 | #ifdef HAVE_FCNTL_H 62 | # include 63 | #endif 64 | 65 | #if defined(macintosh) 66 | # include 67 | # include 68 | #else 69 | # include 70 | # include 71 | #endif 72 | 73 | #ifdef HAVE_INTTYPES_H 74 | # include 75 | #else 76 | # ifdef HAVE_STDINT_H 77 | # include 78 | # endif 79 | #endif 80 | 81 | #ifdef WITH_DMALLOC 82 | #include 83 | #endif 84 | 85 | /* 86 | * 3 different types of pow() functions: 87 | * - table lookup 88 | * - pow() 89 | * - exp() on some machines this is claimed to be faster than pow() 90 | */ 91 | 92 | #define POW20(x) (assert(0 <= (x+Q_MAX2) && x < Q_MAX), pow20[x+Q_MAX2]) 93 | /*#define POW20(x) pow(2.0,((double)(x)-210)*.25) */ 94 | /*#define POW20(x) exp( ((double)(x)-210)*(.25*LOG2) ) */ 95 | 96 | #define IPOW20(x) (assert(0 <= x && x < Q_MAX), ipow20[x]) 97 | /*#define IPOW20(x) exp( -((double)(x)-210)*.1875*LOG2 ) */ 98 | /*#define IPOW20(x) pow(2.0,-((double)(x)-210)*.1875) */ 99 | 100 | /* in case this is used without configure */ 101 | #ifndef inline 102 | # define inline 103 | #endif 104 | 105 | #if defined(_MSC_VER) 106 | # undef inline 107 | # define inline _inline 108 | #elif defined(__SASC) || defined(__GNUC__) || defined(__ICC) || defined(__ECC) 109 | /* if __GNUC__ we always want to inline, not only if the user requests it */ 110 | # undef inline 111 | # define inline __inline 112 | #endif 113 | 114 | #if defined(_MSC_VER) 115 | # pragma warning( disable : 4244 ) 116 | /*# pragma warning( disable : 4305 ) */ 117 | #endif 118 | 119 | /* 120 | * FLOAT for variables which require at least 32 bits 121 | * FLOAT8 for variables which require at least 64 bits 122 | * 123 | * On some machines, 64 bit will be faster than 32 bit. Also, some math 124 | * routines require 64 bit float, so setting FLOAT=float will result in a 125 | * lot of conversions. 126 | */ 127 | 128 | #if ( defined(_MSC_VER) || defined(__BORLANDC__) || defined(__MINGW32__) ) 129 | # define WIN32_LEAN_AND_MEAN 130 | # include 131 | # include 132 | # define FLOAT_MAX FLT_MAX 133 | #else 134 | # ifndef FLOAT 135 | typedef float FLOAT; 136 | # ifdef FLT_MAX 137 | # define FLOAT_MAX FLT_MAX 138 | # else 139 | # define FLOAT_MAX 1e37 /* approx */ 140 | # endif 141 | # endif 142 | #endif 143 | 144 | #ifndef FLOAT8 145 | typedef double FLOAT8; 146 | # ifdef DBL_MAX 147 | # define FLOAT8_MAX DBL_MAX 148 | # else 149 | # define FLOAT8_MAX 1e99 /* approx */ 150 | # endif 151 | #else 152 | # ifdef FLT_MAX 153 | # define FLOAT8_MAX FLT_MAX 154 | # else 155 | # define FLOAT8_MAX 1e37 /* approx */ 156 | # endif 157 | #endif 158 | 159 | /* sample_t must be floating point, at least 32 bits */ 160 | typedef FLOAT sample_t; 161 | 162 | #define dimension_of(array) (sizeof(array)/sizeof(array[0])) 163 | #define beyond(array) (array+dimension_of(array)) 164 | #define compiletime_assert(expression) extern char static_assert_##FILE##_##LINE[expression?1:0] 165 | 166 | #if 1 167 | #define EQ(a,b) (\ 168 | (fabs(a) > fabs(b)) \ 169 | ? (fabs((a)-(b)) <= (fabs(a) * 1e-6f)) \ 170 | : (fabs((a)-(b)) <= (fabs(b) * 1e-6f))) 171 | #else 172 | #define EQ(a,b) (fabs((a)-(b))<1E-37) 173 | #endif 174 | 175 | #define NEQ(a,b) (!EQ(a,b)) 176 | 177 | #endif 178 | 179 | #ifdef _MSC_VER 180 | # if _MSC_VER < 1400 181 | # define fabsf fabs 182 | # define powf pow 183 | # define log10f log10 184 | # endif 185 | #endif 186 | 187 | 188 | /* end of machine.h */ 189 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/mpglib_interface.c: -------------------------------------------------------------------------------- 1 | /* -*- mode: C; mode: fold -*- */ 2 | /* 3 | * LAME MP3 encoding engine 4 | * 5 | * Copyright (c) 1999-2000 Mark Taylor 6 | * Copyright (c) 2003 Olcios 7 | * Copyright (c) 2008 Robert Hegemann 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Library General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Library General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Library General Public 20 | * License along with this library; if not, write to the 21 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 22 | * Boston, MA 02111-1307, USA. 23 | */ 24 | 25 | /* $Id: mpglib_interface.c,v 1.42 2011/05/07 16:05:17 rbrito Exp $ */ 26 | 27 | #ifdef HAVE_CONFIG_H 28 | # include 29 | #endif 30 | 31 | #ifdef HAVE_MPGLIB 32 | #define hip_global_struct mpstr_tag 33 | #include "lame.h" 34 | #include "machine.h" 35 | #include "encoder.h" 36 | #include "interface.h" 37 | 38 | #include "util.h" 39 | 40 | 41 | 42 | #if DEPRECATED_OR_OBSOLETE_CODE_REMOVED 43 | /* 44 | * OBSOLETE: 45 | * - kept to let it link 46 | * - forward declaration to silence compiler 47 | */ 48 | int CDECL lame_decode_init(void); 49 | int CDECL lame_decode( 50 | unsigned char * mp3buf, 51 | int len, 52 | short pcm_l[], 53 | short pcm_r[] ); 54 | int CDECL lame_decode_headers( 55 | unsigned char* mp3buf, 56 | int len, 57 | short pcm_l[], 58 | short pcm_r[], 59 | mp3data_struct* mp3data ); 60 | int CDECL lame_decode1( 61 | unsigned char* mp3buf, 62 | int len, 63 | short pcm_l[], 64 | short pcm_r[] ); 65 | int CDECL lame_decode1_headers( 66 | unsigned char* mp3buf, 67 | int len, 68 | short pcm_l[], 69 | short pcm_r[], 70 | mp3data_struct* mp3data ); 71 | int CDECL lame_decode1_headersB( 72 | unsigned char* mp3buf, 73 | int len, 74 | short pcm_l[], 75 | short pcm_r[], 76 | mp3data_struct* mp3data, 77 | int *enc_delay, 78 | int *enc_padding ); 79 | int CDECL lame_decode_exit(void); 80 | #endif 81 | 82 | 83 | static MPSTR mp; 84 | 85 | int 86 | lame_decode_exit(void) 87 | { 88 | ExitMP3(&mp); 89 | return 0; 90 | } 91 | 92 | 93 | int 94 | lame_decode_init(void) 95 | { 96 | (void) InitMP3(&mp); 97 | return 0; 98 | } 99 | 100 | 101 | 102 | 103 | /* copy mono samples */ 104 | #define COPY_MONO(DST_TYPE, SRC_TYPE) \ 105 | DST_TYPE *pcm_l = (DST_TYPE *)pcm_l_raw; \ 106 | SRC_TYPE const *p_samples = (SRC_TYPE const *)p; \ 107 | for (i = 0; i < processed_samples; i++) \ 108 | *pcm_l++ = (DST_TYPE)(*p_samples++); 109 | 110 | /* copy stereo samples */ 111 | #define COPY_STEREO(DST_TYPE, SRC_TYPE) \ 112 | DST_TYPE *pcm_l = (DST_TYPE *)pcm_l_raw, *pcm_r = (DST_TYPE *)pcm_r_raw; \ 113 | SRC_TYPE const *p_samples = (SRC_TYPE const *)p; \ 114 | for (i = 0; i < processed_samples; i++) { \ 115 | *pcm_l++ = (DST_TYPE)(*p_samples++); \ 116 | *pcm_r++ = (DST_TYPE)(*p_samples++); \ 117 | } 118 | 119 | 120 | 121 | /* 122 | * For lame_decode: return code 123 | * -1 error 124 | * 0 ok, but need more data before outputing any samples 125 | * n number of samples output. either 576 or 1152 depending on MP3 file. 126 | */ 127 | 128 | static int 129 | decode1_headersB_clipchoice(PMPSTR pmp, unsigned char *buffer, int len, 130 | char pcm_l_raw[], char pcm_r_raw[], mp3data_struct * mp3data, 131 | int *enc_delay, int *enc_padding, 132 | char *p, size_t psize, int decoded_sample_size, 133 | int (*decodeMP3_ptr) (PMPSTR, unsigned char *, int, char *, int, 134 | int *)) 135 | { 136 | static const int smpls[2][4] = { 137 | /* Layer I II III */ 138 | {0, 384, 1152, 1152}, /* MPEG-1 */ 139 | {0, 384, 1152, 576} /* MPEG-2(.5) */ 140 | }; 141 | 142 | int processed_bytes; 143 | int processed_samples; /* processed samples per channel */ 144 | int ret; 145 | int i; 146 | 147 | mp3data->header_parsed = 0; 148 | 149 | ret = (*decodeMP3_ptr) (pmp, buffer, len, p, (int) psize, &processed_bytes); 150 | /* three cases: 151 | * 1. headers parsed, but data not complete 152 | * pmp->header_parsed==1 153 | * pmp->framesize=0 154 | * pmp->fsizeold=size of last frame, or 0 if this is first frame 155 | * 156 | * 2. headers, data parsed, but ancillary data not complete 157 | * pmp->header_parsed==1 158 | * pmp->framesize=size of frame 159 | * pmp->fsizeold=size of last frame, or 0 if this is first frame 160 | * 161 | * 3. frame fully decoded: 162 | * pmp->header_parsed==0 163 | * pmp->framesize=0 164 | * pmp->fsizeold=size of frame (which is now the last frame) 165 | * 166 | */ 167 | if (pmp->header_parsed || pmp->fsizeold > 0 || pmp->framesize > 0) { 168 | mp3data->header_parsed = 1; 169 | mp3data->stereo = pmp->fr.stereo; 170 | mp3data->samplerate = freqs[pmp->fr.sampling_frequency]; 171 | mp3data->mode = pmp->fr.mode; 172 | mp3data->mode_ext = pmp->fr.mode_ext; 173 | mp3data->framesize = smpls[pmp->fr.lsf][pmp->fr.lay]; 174 | 175 | /* free format, we need the entire frame before we can determine 176 | * the bitrate. If we haven't gotten the entire frame, bitrate=0 */ 177 | if (pmp->fsizeold > 0) /* works for free format and fixed, no overrun, temporal results are < 400.e6 */ 178 | mp3data->bitrate = 8 * (4 + pmp->fsizeold) * mp3data->samplerate / 179 | (1.e3 * mp3data->framesize) + 0.5; 180 | else if (pmp->framesize > 0) 181 | mp3data->bitrate = 8 * (4 + pmp->framesize) * mp3data->samplerate / 182 | (1.e3 * mp3data->framesize) + 0.5; 183 | else 184 | mp3data->bitrate = tabsel_123[pmp->fr.lsf][pmp->fr.lay - 1][pmp->fr.bitrate_index]; 185 | 186 | 187 | 188 | if (pmp->num_frames > 0) { 189 | /* Xing VBR header found and num_frames was set */ 190 | mp3data->totalframes = pmp->num_frames; 191 | mp3data->nsamp = mp3data->framesize * pmp->num_frames; 192 | *enc_delay = pmp->enc_delay; 193 | *enc_padding = pmp->enc_padding; 194 | } 195 | } 196 | 197 | switch (ret) { 198 | case MP3_OK: 199 | switch (pmp->fr.stereo) { 200 | case 1: 201 | processed_samples = processed_bytes / decoded_sample_size; 202 | if (decoded_sample_size == sizeof(short)) { 203 | COPY_MONO(short, short) 204 | } 205 | else { 206 | COPY_MONO(sample_t, FLOAT) 207 | } 208 | break; 209 | case 2: 210 | processed_samples = (processed_bytes / decoded_sample_size) >> 1; 211 | if (decoded_sample_size == sizeof(short)) { 212 | COPY_STEREO(short, short) 213 | } 214 | else { 215 | COPY_STEREO(sample_t, FLOAT) 216 | } 217 | break; 218 | default: 219 | processed_samples = -1; 220 | assert(0); 221 | break; 222 | } 223 | break; 224 | 225 | case MP3_NEED_MORE: 226 | processed_samples = 0; 227 | break; 228 | 229 | case MP3_ERR: 230 | processed_samples = -1; 231 | break; 232 | 233 | default: 234 | processed_samples = -1; 235 | assert(0); 236 | break; 237 | } 238 | 239 | /*fprintf(stderr,"ok, more, err: %i %i %i\n", MP3_OK, MP3_NEED_MORE, MP3_ERR ); */ 240 | /*fprintf(stderr,"ret = %i out=%i\n", ret, processed_samples ); */ 241 | return processed_samples; 242 | } 243 | 244 | 245 | #define OUTSIZE_CLIPPED (4096*sizeof(short)) 246 | 247 | int 248 | lame_decode1_headersB(unsigned char *buffer, 249 | int len, 250 | short pcm_l[], short pcm_r[], mp3data_struct * mp3data, 251 | int *enc_delay, int *enc_padding) 252 | { 253 | static char out[OUTSIZE_CLIPPED]; 254 | 255 | return decode1_headersB_clipchoice(&mp, buffer, len, (char *) pcm_l, (char *) pcm_r, mp3data, 256 | enc_delay, enc_padding, out, OUTSIZE_CLIPPED, 257 | sizeof(short), decodeMP3); 258 | } 259 | 260 | 261 | 262 | 263 | 264 | /* 265 | * For lame_decode: return code 266 | * -1 error 267 | * 0 ok, but need more data before outputing any samples 268 | * n number of samples output. Will be at most one frame of 269 | * MPEG data. 270 | */ 271 | 272 | int 273 | lame_decode1_headers(unsigned char *buffer, 274 | int len, short pcm_l[], short pcm_r[], mp3data_struct * mp3data) 275 | { 276 | int enc_delay, enc_padding; 277 | return lame_decode1_headersB(buffer, len, pcm_l, pcm_r, mp3data, &enc_delay, &enc_padding); 278 | } 279 | 280 | 281 | int 282 | lame_decode1(unsigned char *buffer, int len, short pcm_l[], short pcm_r[]) 283 | { 284 | mp3data_struct mp3data; 285 | 286 | return lame_decode1_headers(buffer, len, pcm_l, pcm_r, &mp3data); 287 | } 288 | 289 | 290 | /* 291 | * For lame_decode: return code 292 | * -1 error 293 | * 0 ok, but need more data before outputing any samples 294 | * n number of samples output. a multiple of 576 or 1152 depending on MP3 file. 295 | */ 296 | 297 | int 298 | lame_decode_headers(unsigned char *buffer, 299 | int len, short pcm_l[], short pcm_r[], mp3data_struct * mp3data) 300 | { 301 | int ret; 302 | int totsize = 0; /* number of decoded samples per channel */ 303 | 304 | for (;;) { 305 | switch (ret = lame_decode1_headers(buffer, len, pcm_l + totsize, pcm_r + totsize, mp3data)) { 306 | case -1: 307 | return ret; 308 | case 0: 309 | return totsize; 310 | default: 311 | totsize += ret; 312 | len = 0; /* future calls to decodeMP3 are just to flush buffers */ 313 | break; 314 | } 315 | } 316 | } 317 | 318 | 319 | int 320 | lame_decode(unsigned char *buffer, int len, short pcm_l[], short pcm_r[]) 321 | { 322 | mp3data_struct mp3data; 323 | 324 | return lame_decode_headers(buffer, len, pcm_l, pcm_r, &mp3data); 325 | } 326 | 327 | 328 | 329 | 330 | hip_t hip_decode_init(void) 331 | { 332 | hip_t hip = calloc(1, sizeof(hip_global_flags)); 333 | InitMP3(hip); 334 | return hip; 335 | } 336 | 337 | 338 | int hip_decode_exit(hip_t hip) 339 | { 340 | if (hip) { 341 | ExitMP3(hip); 342 | free(hip); 343 | } 344 | return 0; 345 | } 346 | 347 | 348 | /* we forbid input with more than 1152 samples per channel for output in the unclipped mode */ 349 | #define OUTSIZE_UNCLIPPED (1152*2*sizeof(FLOAT)) 350 | 351 | int 352 | hip_decode1_unclipped(hip_t hip, unsigned char *buffer, size_t len, sample_t pcm_l[], sample_t pcm_r[]) 353 | { 354 | static char out[OUTSIZE_UNCLIPPED]; 355 | mp3data_struct mp3data; 356 | int enc_delay, enc_padding; 357 | 358 | if (hip) { 359 | return decode1_headersB_clipchoice(hip, buffer, len, (char *) pcm_l, (char *) pcm_r, &mp3data, 360 | &enc_delay, &enc_padding, out, OUTSIZE_UNCLIPPED, 361 | sizeof(FLOAT), decodeMP3_unclipped); 362 | } 363 | return 0; 364 | } 365 | 366 | /* 367 | * For hip_decode: return code 368 | * -1 error 369 | * 0 ok, but need more data before outputing any samples 370 | * n number of samples output. Will be at most one frame of 371 | * MPEG data. 372 | */ 373 | 374 | int 375 | hip_decode1_headers(hip_t hip, unsigned char *buffer, 376 | size_t len, short pcm_l[], short pcm_r[], mp3data_struct * mp3data) 377 | { 378 | int enc_delay, enc_padding; 379 | return hip_decode1_headersB(hip, buffer, len, pcm_l, pcm_r, mp3data, &enc_delay, &enc_padding); 380 | } 381 | 382 | 383 | int 384 | hip_decode1(hip_t hip, unsigned char *buffer, size_t len, short pcm_l[], short pcm_r[]) 385 | { 386 | mp3data_struct mp3data; 387 | return hip_decode1_headers(hip, buffer, len, pcm_l, pcm_r, &mp3data); 388 | } 389 | 390 | 391 | /* 392 | * For hip_decode: return code 393 | * -1 error 394 | * 0 ok, but need more data before outputing any samples 395 | * n number of samples output. a multiple of 576 or 1152 depending on MP3 file. 396 | */ 397 | 398 | int 399 | hip_decode_headers(hip_t hip, unsigned char *buffer, 400 | size_t len, short pcm_l[], short pcm_r[], mp3data_struct * mp3data) 401 | { 402 | int ret; 403 | int totsize = 0; /* number of decoded samples per channel */ 404 | 405 | for (;;) { 406 | switch (ret = hip_decode1_headers(hip, buffer, len, pcm_l + totsize, pcm_r + totsize, mp3data)) { 407 | case -1: 408 | return ret; 409 | case 0: 410 | return totsize; 411 | default: 412 | totsize += ret; 413 | len = 0; /* future calls to decodeMP3 are just to flush buffers */ 414 | break; 415 | } 416 | } 417 | } 418 | 419 | 420 | int 421 | hip_decode(hip_t hip, unsigned char *buffer, size_t len, short pcm_l[], short pcm_r[]) 422 | { 423 | mp3data_struct mp3data; 424 | return hip_decode_headers(hip, buffer, len, pcm_l, pcm_r, &mp3data); 425 | } 426 | 427 | 428 | int 429 | hip_decode1_headersB(hip_t hip, unsigned char *buffer, 430 | size_t len, 431 | short pcm_l[], short pcm_r[], mp3data_struct * mp3data, 432 | int *enc_delay, int *enc_padding) 433 | { 434 | static char out[OUTSIZE_CLIPPED]; 435 | if (hip) { 436 | return decode1_headersB_clipchoice(hip, buffer, len, (char *) pcm_l, (char *) pcm_r, mp3data, 437 | enc_delay, enc_padding, out, OUTSIZE_CLIPPED, 438 | sizeof(short), decodeMP3); 439 | } 440 | return -1; 441 | } 442 | 443 | 444 | void hip_set_pinfo(hip_t hip, plotting_data* pinfo) 445 | { 446 | if (hip) { 447 | hip->pinfo = pinfo; 448 | } 449 | } 450 | 451 | 452 | 453 | void hip_set_errorf(hip_t hip, lame_report_function func) 454 | { 455 | if (hip) { 456 | hip->report_err = func; 457 | } 458 | } 459 | 460 | void hip_set_debugf(hip_t hip, lame_report_function func) 461 | { 462 | if (hip) { 463 | hip->report_dbg = func; 464 | } 465 | } 466 | 467 | void hip_set_msgf (hip_t hip, lame_report_function func) 468 | { 469 | if (hip) { 470 | hip->report_msg = func; 471 | } 472 | } 473 | 474 | #endif 475 | 476 | /* end of mpglib_interface.c */ 477 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/newmdct.h: -------------------------------------------------------------------------------- 1 | /* 2 | * New Modified DCT include file 3 | * 4 | * Copyright (c) 1999 Takehiro TOMINAGA 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Library General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Library General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Library General Public 17 | * License along with this library; if not, write to the 18 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 | * Boston, MA 02111-1307, USA. 20 | */ 21 | 22 | #ifndef LAME_NEWMDCT_H 23 | #define LAME_NEWMDCT_H 24 | 25 | void mdct_sub48(lame_internal_flags * gfc, const sample_t * w0, const sample_t * w1); 26 | 27 | #endif /* LAME_NEWMDCT_H */ 28 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/presets.c: -------------------------------------------------------------------------------- 1 | /* 2 | * presets.c -- Apply presets 3 | * 4 | * Copyright (c) 2002-2008 Gabriel Bouvigne 5 | * Copyright (c) 2007-2011 Robert Hegemann 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Library General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Library General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Library General Public 18 | * License along with this library; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 20 | */ 21 | 22 | 23 | #ifdef HAVE_CONFIG_H 24 | # include 25 | #endif 26 | 27 | #include "lame.h" 28 | #include "machine.h" 29 | #include "set_get.h" 30 | #include "encoder.h" 31 | #include "util.h" 32 | #include "lame_global_flags.h" 33 | 34 | #define SET_OPTION(opt, val, def) if (enforce) \ 35 | (void) lame_set_##opt(gfp, val); \ 36 | else if (!(fabs(lame_get_##opt(gfp) - def) > 0)) \ 37 | (void) lame_set_##opt(gfp, val); 38 | 39 | #define SET__OPTION(opt, val, def) if (enforce) \ 40 | lame_set_##opt(gfp, val); \ 41 | else if (!(fabs(lame_get_##opt(gfp) - def) > 0)) \ 42 | lame_set_##opt(gfp, val); 43 | 44 | #undef Min 45 | #undef Max 46 | 47 | static inline int 48 | min_int(int a, int b) 49 | { 50 | if (a < b) { 51 | return a; 52 | } 53 | return b; 54 | } 55 | 56 | static inline int 57 | max_int(int a, int b) 58 | { 59 | if (a > b) { 60 | return a; 61 | } 62 | return b; 63 | } 64 | 65 | 66 | 67 | typedef struct { 68 | int vbr_q; 69 | int quant_comp; 70 | int quant_comp_s; 71 | int expY; 72 | FLOAT st_lrm; /*short threshold */ 73 | FLOAT st_s; 74 | FLOAT masking_adj; 75 | FLOAT masking_adj_short; 76 | FLOAT ath_lower; 77 | FLOAT ath_curve; 78 | FLOAT ath_sensitivity; 79 | FLOAT interch; 80 | int safejoint; 81 | int sfb21mod; 82 | FLOAT msfix; 83 | FLOAT minval; 84 | FLOAT ath_fixpoint; 85 | } vbr_presets_t; 86 | 87 | /* *INDENT-OFF* */ 88 | 89 | /* Switch mappings for VBR mode VBR_RH */ 90 | static const vbr_presets_t vbr_old_switch_map[] = { 91 | /*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 */ 92 | {0, 9, 9, 0, 5.20, 125.0, -4.2, -6.3, 4.8, 1, 0, 0, 2, 21, 0.97, 5, 100}, 93 | {1, 9, 9, 0, 5.30, 125.0, -3.6, -5.6, 4.5, 1.5, 0, 0, 2, 21, 1.35, 5, 100}, 94 | {2, 9, 9, 0, 5.60, 125.0, -2.2, -3.5, 2.8, 2, 0, 0, 2, 21, 1.49, 5, 100}, 95 | {3, 9, 9, 1, 5.80, 130.0, -1.8, -2.8, 2.6, 3, -4, 0, 2, 20, 1.64, 5, 100}, 96 | {4, 9, 9, 1, 6.00, 135.0, -0.7, -1.1, 1.1, 3.5, -8, 0, 2, 0, 1.79, 5, 100}, 97 | {5, 9, 9, 1, 6.40, 140.0, 0.5, 0.4, -7.5, 4, -12, 0.0002, 0, 0, 1.95, 5, 100}, 98 | {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}, 99 | {7, 9, 9, 1, 6.60, 145.0, 0.8, 0.75, -19.7, 8, -22, 0.0006, 0, 0, 2.70, 5, 100}, 100 | {8, 9, 9, 1, 6.60, 145.0, 1.2, 1.15, -27.5, 10, -23, 0.0007, 0, 0, 0, 5, 100}, 101 | {9, 9, 9, 1, 6.60, 145.0, 1.6, 1.6, -36, 11, -25, 0.0008, 0, 0, 0, 5, 100}, 102 | {10, 9, 9, 1, 6.60, 145.0, 2.0, 2.0, -36, 12, -25, 0.0008, 0, 0, 0, 5, 100} 103 | }; 104 | 105 | static const vbr_presets_t vbr_mt_psy_switch_map[] = { 106 | /*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 */ 107 | {0, 9, 9, 0, 4.20, 25.0, -6.8, -6.8, 7.1, 1, 0, 0, 2, 31, 1.000, 5, 100}, 108 | {1, 9, 9, 0, 4.20, 25.0, -4.8, -4.8, 5.4, 1.4, -1, 0, 2, 27, 1.122, 5, 98}, 109 | {2, 9, 9, 0, 4.20, 25.0, -2.6, -2.6, 3.7, 2.0, -3, 0, 2, 23, 1.288, 5, 97}, 110 | {3, 9, 9, 1, 4.20, 25.0, -1.6, -1.6, 2.0, 2.0, -5, 0, 2, 18, 1.479, 5, 96}, 111 | {4, 9, 9, 1, 4.20, 25.0, -0.0, -0.0, 0.0, 2.0, -8, 0, 2, 12, 1.698, 5, 95}, 112 | {5, 9, 9, 1, 4.20, 25.0, 1.3, 1.3, -6, 3.5, -11, 0, 2, 8, 1.950, 5, 94.2}, 113 | #if 0 114 | {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}, 115 | {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}, 116 | #else 117 | {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}, 118 | {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}, 119 | #endif 120 | {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}, 121 | {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}, 122 | {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} 123 | }; 124 | 125 | /* *INDENT-ON* */ 126 | 127 | static vbr_presets_t const* 128 | get_vbr_preset(int v) 129 | { 130 | switch (v) { 131 | case vbr_mtrh: 132 | case vbr_mt: 133 | return &vbr_mt_psy_switch_map[0]; 134 | default: 135 | return &vbr_old_switch_map[0]; 136 | } 137 | } 138 | 139 | #define NOOP(m) (void)p.m 140 | #define LERP(m) (p.m = p.m + x * (q.m - p.m)) 141 | 142 | static void 143 | apply_vbr_preset(lame_global_flags * gfp, int a, int enforce) 144 | { 145 | vbr_presets_t const *vbr_preset = get_vbr_preset(lame_get_VBR(gfp)); 146 | float x = gfp->VBR_q_frac; 147 | vbr_presets_t p = vbr_preset[a]; 148 | vbr_presets_t q = vbr_preset[a + 1]; 149 | vbr_presets_t const *set = &p; 150 | 151 | NOOP(vbr_q); 152 | NOOP(quant_comp); 153 | NOOP(quant_comp_s); 154 | NOOP(expY); 155 | LERP(st_lrm); 156 | LERP(st_s); 157 | LERP(masking_adj); 158 | LERP(masking_adj_short); 159 | LERP(ath_lower); 160 | LERP(ath_curve); 161 | LERP(ath_sensitivity); 162 | LERP(interch); 163 | NOOP(safejoint); 164 | LERP(sfb21mod); 165 | LERP(msfix); 166 | LERP(minval); 167 | LERP(ath_fixpoint); 168 | 169 | (void) lame_set_VBR_q(gfp, set->vbr_q); 170 | SET_OPTION(quant_comp, set->quant_comp, -1); 171 | SET_OPTION(quant_comp_short, set->quant_comp_s, -1); 172 | if (set->expY) { 173 | (void) lame_set_experimentalY(gfp, set->expY); 174 | } 175 | SET_OPTION(short_threshold_lrm, set->st_lrm, -1); 176 | SET_OPTION(short_threshold_s, set->st_s, -1); 177 | SET_OPTION(maskingadjust, set->masking_adj, 0); 178 | SET_OPTION(maskingadjust_short, set->masking_adj_short, 0); 179 | if (lame_get_VBR(gfp) == vbr_mt || lame_get_VBR(gfp) == vbr_mtrh) { 180 | lame_set_ATHtype(gfp, 5); 181 | } 182 | SET_OPTION(ATHlower, set->ath_lower, 0); 183 | SET_OPTION(ATHcurve, set->ath_curve, -1); 184 | SET_OPTION(athaa_sensitivity, set->ath_sensitivity, 0); 185 | if (set->interch > 0) { 186 | SET_OPTION(interChRatio, set->interch, -1); 187 | } 188 | 189 | /* parameters for which there is no proper set/get interface */ 190 | if (set->safejoint > 0) { 191 | (void) lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 2); 192 | } 193 | if (set->sfb21mod > 0) { 194 | int const nsp = lame_get_exp_nspsytune(gfp); 195 | int const val = (nsp >> 20) & 63; 196 | if (val == 0) { 197 | int const sf21mod = (set->sfb21mod << 20) | nsp; 198 | (void) lame_set_exp_nspsytune(gfp, sf21mod); 199 | } 200 | } 201 | SET__OPTION(msfix, set->msfix, -1); 202 | 203 | if (enforce == 0) { 204 | gfp->VBR_q = a; 205 | gfp->VBR_q_frac = x; 206 | } 207 | gfp->internal_flags->cfg.minval = set->minval; 208 | gfp->internal_flags->cfg.ATHfixpoint = set->ath_fixpoint; 209 | } 210 | 211 | static int 212 | apply_abr_preset(lame_global_flags * gfp, int preset, int enforce) 213 | { 214 | typedef struct { 215 | int abr_kbps; 216 | int quant_comp; 217 | int quant_comp_s; 218 | int safejoint; 219 | FLOAT nsmsfix; 220 | FLOAT st_lrm; /*short threshold */ 221 | FLOAT st_s; 222 | FLOAT scale; 223 | FLOAT masking_adj; 224 | FLOAT ath_lower; 225 | FLOAT ath_curve; 226 | FLOAT interch; 227 | int sfscale; 228 | } abr_presets_t; 229 | 230 | 231 | /* *INDENT-OFF* */ 232 | 233 | /* 234 | * Switch mappings for ABR mode 235 | */ 236 | const abr_presets_t abr_switch_map[] = { 237 | /* kbps quant q_s safejoint nsmsfix st_lrm st_s scale msk ath_lwr ath_curve interch , sfscale */ 238 | { 8, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -30.0, 11, 0.0012, 1}, /* 8, impossible to use in stereo */ 239 | { 16, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -25.0, 11, 0.0010, 1}, /* 16 */ 240 | { 24, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -20.0, 11, 0.0010, 1}, /* 24 */ 241 | { 32, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -15.0, 11, 0.0010, 1}, /* 32 */ 242 | { 40, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -10.0, 11, 0.0009, 1}, /* 40 */ 243 | { 48, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -10.0, 11, 0.0009, 1}, /* 48 */ 244 | { 56, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -6.0, 11, 0.0008, 1}, /* 56 */ 245 | { 64, 9, 9, 0, 0, 6.60, 145, 0.95, 0, -2.0, 11, 0.0008, 1}, /* 64 */ 246 | { 80, 9, 9, 0, 0, 6.60, 145, 0.95, 0, .0, 8, 0.0007, 1}, /* 80 */ 247 | { 96, 9, 9, 0, 2.50, 6.60, 145, 0.95, 0, 1.0, 5.5, 0.0006, 1}, /* 96 */ 248 | {112, 9, 9, 0, 2.25, 6.60, 145, 0.95, 0, 2.0, 4.5, 0.0005, 1}, /* 112 */ 249 | {128, 9, 9, 0, 1.95, 6.40, 140, 0.95, 0, 3.0, 4, 0.0002, 1}, /* 128 */ 250 | {160, 9, 9, 1, 1.79, 6.00, 135, 0.95, -2, 5.0, 3.5, 0, 1}, /* 160 */ 251 | {192, 9, 9, 1, 1.49, 5.60, 125, 0.97, -4, 7.0, 3, 0, 0}, /* 192 */ 252 | {224, 9, 9, 1, 1.25, 5.20, 125, 0.98, -6, 9.0, 2, 0, 0}, /* 224 */ 253 | {256, 9, 9, 1, 0.97, 5.20, 125, 1.00, -8, 10.0, 1, 0, 0}, /* 256 */ 254 | {320, 9, 9, 1, 0.90, 5.20, 125, 1.00, -10, 12.0, 0, 0, 0} /* 320 */ 255 | }; 256 | 257 | /* *INDENT-ON* */ 258 | 259 | /* Variables for the ABR stuff */ 260 | int r; 261 | int actual_bitrate = preset; 262 | 263 | r = nearestBitrateFullIndex(preset); 264 | 265 | (void) lame_set_VBR(gfp, vbr_abr); 266 | (void) lame_set_VBR_mean_bitrate_kbps(gfp, (actual_bitrate)); 267 | (void) lame_set_VBR_mean_bitrate_kbps(gfp, min_int(lame_get_VBR_mean_bitrate_kbps(gfp), 320)); 268 | (void) lame_set_VBR_mean_bitrate_kbps(gfp, max_int(lame_get_VBR_mean_bitrate_kbps(gfp), 8)); 269 | (void) lame_set_brate(gfp, lame_get_VBR_mean_bitrate_kbps(gfp)); 270 | 271 | 272 | /* parameters for which there is no proper set/get interface */ 273 | if (abr_switch_map[r].safejoint > 0) 274 | (void) lame_set_exp_nspsytune(gfp, lame_get_exp_nspsytune(gfp) | 2); /* safejoint */ 275 | 276 | if (abr_switch_map[r].sfscale > 0) 277 | (void) lame_set_sfscale(gfp, 1); 278 | 279 | 280 | SET_OPTION(quant_comp, abr_switch_map[r].quant_comp, -1); 281 | SET_OPTION(quant_comp_short, abr_switch_map[r].quant_comp_s, -1); 282 | 283 | SET__OPTION(msfix, abr_switch_map[r].nsmsfix, -1); 284 | 285 | SET_OPTION(short_threshold_lrm, abr_switch_map[r].st_lrm, -1); 286 | SET_OPTION(short_threshold_s, abr_switch_map[r].st_s, -1); 287 | 288 | /* ABR seems to have big problems with clipping, especially at low bitrates */ 289 | /* so we compensate for that here by using a scale value depending on bitrate */ 290 | lame_set_scale(gfp, lame_get_scale(gfp) * abr_switch_map[r].scale); 291 | 292 | SET_OPTION(maskingadjust, abr_switch_map[r].masking_adj, 0); 293 | if (abr_switch_map[r].masking_adj > 0) { 294 | SET_OPTION(maskingadjust_short, abr_switch_map[r].masking_adj * .9, 0); 295 | } 296 | else { 297 | SET_OPTION(maskingadjust_short, abr_switch_map[r].masking_adj * 1.1, 0); 298 | } 299 | 300 | 301 | SET_OPTION(ATHlower, abr_switch_map[r].ath_lower, 0); 302 | SET_OPTION(ATHcurve, abr_switch_map[r].ath_curve, -1); 303 | 304 | SET_OPTION(interChRatio, abr_switch_map[r].interch, -1); 305 | 306 | (void) abr_switch_map[r].abr_kbps; 307 | 308 | gfp->internal_flags->cfg.minval = 5. * (abr_switch_map[r].abr_kbps / 320.); 309 | 310 | return preset; 311 | } 312 | 313 | 314 | 315 | int 316 | apply_preset(lame_global_flags * gfp, int preset, int enforce) 317 | { 318 | /*translate legacy presets */ 319 | switch (preset) { 320 | case R3MIX: 321 | { 322 | preset = V3; 323 | (void) lame_set_VBR(gfp, vbr_mtrh); 324 | break; 325 | } 326 | case MEDIUM: 327 | case MEDIUM_FAST: 328 | { 329 | preset = V4; 330 | (void) lame_set_VBR(gfp, vbr_mtrh); 331 | break; 332 | } 333 | case STANDARD: 334 | case STANDARD_FAST: 335 | { 336 | preset = V2; 337 | (void) lame_set_VBR(gfp, vbr_mtrh); 338 | break; 339 | } 340 | case EXTREME: 341 | case EXTREME_FAST: 342 | { 343 | preset = V0; 344 | (void) lame_set_VBR(gfp, vbr_mtrh); 345 | break; 346 | } 347 | case INSANE: 348 | { 349 | preset = 320; 350 | gfp->preset = preset; 351 | (void) apply_abr_preset(gfp, preset, enforce); 352 | lame_set_VBR(gfp, vbr_off); 353 | return preset; 354 | } 355 | } 356 | 357 | gfp->preset = preset; 358 | { 359 | switch (preset) { 360 | case V9: 361 | apply_vbr_preset(gfp, 9, enforce); 362 | return preset; 363 | case V8: 364 | apply_vbr_preset(gfp, 8, enforce); 365 | return preset; 366 | case V7: 367 | apply_vbr_preset(gfp, 7, enforce); 368 | return preset; 369 | case V6: 370 | apply_vbr_preset(gfp, 6, enforce); 371 | return preset; 372 | case V5: 373 | apply_vbr_preset(gfp, 5, enforce); 374 | return preset; 375 | case V4: 376 | apply_vbr_preset(gfp, 4, enforce); 377 | return preset; 378 | case V3: 379 | apply_vbr_preset(gfp, 3, enforce); 380 | return preset; 381 | case V2: 382 | apply_vbr_preset(gfp, 2, enforce); 383 | return preset; 384 | case V1: 385 | apply_vbr_preset(gfp, 1, enforce); 386 | return preset; 387 | case V0: 388 | apply_vbr_preset(gfp, 0, enforce); 389 | return preset; 390 | default: 391 | break; 392 | } 393 | } 394 | if (8 <= preset && preset <= 320) { 395 | return apply_abr_preset(gfp, preset, enforce); 396 | } 397 | 398 | gfp->preset = 0; /*no corresponding preset found */ 399 | return preset; 400 | } 401 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/psymodel.h: -------------------------------------------------------------------------------- 1 | /* 2 | * psymodel.h 3 | * 4 | * Copyright (c) 1999 Mark Taylor 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Library General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Library General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Library General Public 17 | * License along with this library; if not, write to the 18 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 | * Boston, MA 02111-1307, USA. 20 | */ 21 | 22 | #ifndef LAME_PSYMODEL_H 23 | #define LAME_PSYMODEL_H 24 | 25 | 26 | int L3psycho_anal_ns(lame_internal_flags * gfc, 27 | const sample_t *const buffer[2], int gr, 28 | III_psy_ratio ratio[2][2], 29 | III_psy_ratio MS_ratio[2][2], 30 | FLOAT pe[2], FLOAT pe_MS[2], FLOAT ener[2], int blocktype_d[2]); 31 | 32 | int L3psycho_anal_vbr(lame_internal_flags * gfc, 33 | const sample_t *const buffer[2], int gr, 34 | III_psy_ratio ratio[2][2], 35 | III_psy_ratio MS_ratio[2][2], 36 | FLOAT pe[2], FLOAT pe_MS[2], FLOAT ener[2], int blocktype_d[2]); 37 | 38 | 39 | int psymodel_init(lame_global_flags const* gfp); 40 | 41 | 42 | #define rpelev 2 43 | #define rpelev2 16 44 | #define rpelev_s 2 45 | #define rpelev2_s 16 46 | 47 | /* size of each partition band, in barks: */ 48 | #define DELBARK .34 49 | 50 | 51 | /* tuned for output level (sensitive to energy scale) */ 52 | #define VO_SCALE (1./( 14752*14752 )/(BLKSIZE/2)) 53 | 54 | #define temporalmask_sustain_sec 0.01 55 | 56 | #define NS_PREECHO_ATT0 0.8 57 | #define NS_PREECHO_ATT1 0.6 58 | #define NS_PREECHO_ATT2 0.3 59 | 60 | #define NS_MSFIX 3.5 61 | #define NSATTACKTHRE 4.4 62 | #define NSATTACKTHRE_S 25 63 | 64 | #endif /* LAME_PSYMODEL_H */ 65 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/quantize.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MP3 quantization 3 | * 4 | * Copyright (c) 1999 Mark Taylor 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Library General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Library General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Library General Public 17 | * License along with this library; if not, write to the 18 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 | * Boston, MA 02111-1307, USA. 20 | */ 21 | 22 | #ifndef LAME_QUANTIZE_H 23 | #define LAME_QUANTIZE_H 24 | 25 | void CBR_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2], 26 | const FLOAT ms_ratio[2], const III_psy_ratio ratio[2][2]); 27 | 28 | void VBR_old_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2], 29 | const FLOAT ms_ratio[2], const III_psy_ratio ratio[2][2]); 30 | 31 | void VBR_new_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2], 32 | const FLOAT ms_ratio[2], const III_psy_ratio ratio[2][2]); 33 | 34 | void ABR_iteration_loop(lame_internal_flags * gfc, const FLOAT pe[2][2], 35 | const FLOAT ms_ratio[2], const III_psy_ratio ratio[2][2]); 36 | 37 | 38 | #endif /* LAME_QUANTIZE_H */ 39 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/quantize_pvt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * quantize_pvt include file 3 | * 4 | * Copyright (c) 1999 Takehiro TOMINAGA 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Library General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Library General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Library General Public 17 | * License along with this library; if not, write to the 18 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 | * Boston, MA 02111-1307, USA. 20 | */ 21 | 22 | #ifndef LAME_QUANTIZE_PVT_H 23 | #define LAME_QUANTIZE_PVT_H 24 | 25 | #define IXMAX_VAL 8206 /* ix always <= 8191+15. see count_bits() */ 26 | 27 | /* buggy Winamp decoder cannot handle values > 8191 */ 28 | /* #define IXMAX_VAL 8191 */ 29 | 30 | #define PRECALC_SIZE (IXMAX_VAL+2) 31 | 32 | 33 | extern const int nr_of_sfb_block[6][3][4]; 34 | extern const int pretab[SBMAX_l]; 35 | extern const int slen1_tab[16]; 36 | extern const int slen2_tab[16]; 37 | 38 | extern const scalefac_struct sfBandIndex[9]; 39 | 40 | extern FLOAT pow43[PRECALC_SIZE]; 41 | #ifdef TAKEHIRO_IEEE754_HACK 42 | extern FLOAT adj43asm[PRECALC_SIZE]; 43 | #else 44 | extern FLOAT adj43[PRECALC_SIZE]; 45 | #endif 46 | 47 | #define Q_MAX (256+1) 48 | #define Q_MAX2 116 /* minimum possible number of 49 | -cod_info->global_gain 50 | + ((scalefac[] + (cod_info->preflag ? pretab[sfb] : 0)) 51 | << (cod_info->scalefac_scale + 1)) 52 | + cod_info->subblock_gain[cod_info->window[sfb]] * 8; 53 | 54 | for long block, 0+((15+3)<<2) = 18*4 = 72 55 | for short block, 0+(15<<2)+7*8 = 15*4+56 = 116 56 | */ 57 | 58 | extern FLOAT pow20[Q_MAX + Q_MAX2 + 1]; 59 | extern FLOAT ipow20[Q_MAX]; 60 | 61 | typedef struct calc_noise_result_t { 62 | FLOAT over_noise; /* sum of quantization noise > masking */ 63 | FLOAT tot_noise; /* sum of all quantization noise */ 64 | FLOAT max_noise; /* max quantization noise */ 65 | int over_count; /* number of quantization noise > masking */ 66 | int over_SSD; /* SSD-like cost of distorted bands */ 67 | int bits; 68 | } calc_noise_result; 69 | 70 | 71 | /** 72 | * allows re-use of previously 73 | * computed noise values 74 | */ 75 | typedef struct calc_noise_data_t { 76 | int global_gain; 77 | int sfb_count1; 78 | int step[39]; 79 | FLOAT noise[39]; 80 | FLOAT noise_log[39]; 81 | } calc_noise_data; 82 | 83 | 84 | int on_pe(lame_internal_flags * gfc, const FLOAT pe[2][2], 85 | int targ_bits[2], int mean_bits, int gr, int cbr); 86 | 87 | void reduce_side(int targ_bits[2], FLOAT ms_ener_ratio, int mean_bits, int max_bits); 88 | 89 | 90 | void iteration_init(lame_internal_flags * gfc); 91 | 92 | 93 | int calc_xmin(lame_internal_flags const *gfc, 94 | III_psy_ratio const *const ratio, gr_info * const cod_info, FLOAT * l3_xmin); 95 | 96 | int calc_noise(const gr_info * const cod_info, 97 | const FLOAT * l3_xmin, 98 | FLOAT * distort, calc_noise_result * const res, calc_noise_data * prev_noise); 99 | 100 | void set_frame_pinfo(lame_internal_flags * gfc, const III_psy_ratio ratio[2][2]); 101 | 102 | 103 | 104 | 105 | /* takehiro.c */ 106 | 107 | int count_bits(lame_internal_flags const *const gfc, const FLOAT * const xr, 108 | gr_info * const cod_info, calc_noise_data * prev_noise); 109 | int noquant_count_bits(lame_internal_flags const *const gfc, 110 | gr_info * const cod_info, calc_noise_data * prev_noise); 111 | 112 | 113 | void best_huffman_divide(const lame_internal_flags * const gfc, gr_info * const cod_info); 114 | 115 | void best_scalefac_store(const lame_internal_flags * gfc, const int gr, const int ch, 116 | III_side_info_t * const l3_side); 117 | 118 | int scale_bitcount(const lame_internal_flags * gfc, gr_info * cod_info); 119 | 120 | void huffman_init(lame_internal_flags * const gfc); 121 | 122 | void init_xrpow_core_init(lame_internal_flags * const gfc); 123 | 124 | FLOAT athAdjust(FLOAT a, FLOAT x, FLOAT athFloor, float ATHfixpoint); 125 | 126 | #define LARGE_BITS 100000 127 | 128 | #endif /* LAME_QUANTIZE_PVT_H */ 129 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/reservoir.c: -------------------------------------------------------------------------------- 1 | /* 2 | * bit reservoir source file 3 | * 4 | * Copyright (c) 1999-2000 Mark Taylor 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Library General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Library General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Library General Public 17 | * License along with this library; if not, write to the 18 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 | * Boston, MA 02111-1307, USA. 20 | */ 21 | 22 | /* $Id: reservoir.c,v 1.45 2011/05/07 16:05:17 rbrito Exp $ */ 23 | 24 | #ifdef HAVE_CONFIG_H 25 | # include 26 | #endif 27 | 28 | 29 | #include "lame.h" 30 | #include "machine.h" 31 | #include "encoder.h" 32 | #include "util.h" 33 | #include "reservoir.h" 34 | 35 | #include "bitstream.h" 36 | #include "lame-analysis.h" 37 | #include "lame_global_flags.h" 38 | 39 | 40 | /* 41 | ResvFrameBegin: 42 | Called (repeatedly) at the beginning of a frame. Updates the maximum 43 | size of the reservoir, and checks to make sure main_data_begin 44 | was set properly by the formatter 45 | */ 46 | 47 | /* 48 | * Background information: 49 | * 50 | * This is the original text from the ISO standard. Because of 51 | * sooo many bugs and irritations correcting comments are added 52 | * in brackets []. A '^W' means you should remove the last word. 53 | * 54 | * 1) The following rule can be used to calculate the maximum 55 | * number of bits used for one granule [^W frame]: 56 | * At the highest possible bitrate of Layer III (320 kbps 57 | * per stereo signal [^W^W^W], 48 kHz) the frames must be of 58 | * [^W^W^W are designed to have] constant length, i.e. 59 | * one buffer [^W^W the frame] length is: 60 | * 61 | * 320 kbps * 1152/48 kHz = 7680 bit = 960 byte 62 | * 63 | * This value is used as the maximum buffer per channel [^W^W] at 64 | * lower bitrates [than 320 kbps]. At 64 kbps mono or 128 kbps 65 | * stereo the main granule length is 64 kbps * 576/48 kHz = 768 bit 66 | * [per granule and channel] at 48 kHz sampling frequency. 67 | * This means that there is a maximum deviation (short time buffer 68 | * [= reservoir]) of 7680 - 2*2*768 = 4608 bits is allowed at 64 kbps. 69 | * The actual deviation is equal to the number of bytes [with the 70 | * meaning of octets] denoted by the main_data_end offset pointer. 71 | * The actual maximum deviation is (2^9-1)*8 bit = 4088 bits 72 | * [for MPEG-1 and (2^8-1)*8 bit for MPEG-2, both are hard limits]. 73 | * ... The xchange of buffer bits between the left and right channel 74 | * is allowed without restrictions [exception: dual channel]. 75 | * Because of the [constructed] constraint on the buffer size 76 | * main_data_end is always set to 0 in the case of bit_rate_index==14, 77 | * i.e. data rate 320 kbps per stereo signal [^W^W^W]. In this case 78 | * all data are allocated between adjacent header [^W sync] words 79 | * [, i.e. there is no buffering at all]. 80 | */ 81 | 82 | int 83 | ResvFrameBegin(lame_internal_flags * gfc, int *mean_bits) 84 | { 85 | SessionConfig_t const *const cfg = &gfc->cfg; 86 | EncStateVar_t *const esv = &gfc->sv_enc; 87 | int fullFrameBits; 88 | int resvLimit; 89 | int maxmp3buf; 90 | III_side_info_t *const l3_side = &gfc->l3_side; 91 | int frameLength; 92 | int meanBits; 93 | 94 | frameLength = getframebits(gfc); 95 | meanBits = (frameLength - cfg->sideinfo_len * 8) / cfg->mode_gr; 96 | 97 | /* 98 | * Meaning of the variables: 99 | * resvLimit: (0, 8, ..., 8*255 (MPEG-2), 8*511 (MPEG-1)) 100 | * Number of bits can be stored in previous frame(s) due to 101 | * counter size constaints 102 | * maxmp3buf: ( ??? ... 8*1951 (MPEG-1 and 2), 8*2047 (MPEG-2.5)) 103 | * Number of bits allowed to encode one frame (you can take 8*511 bit 104 | * from the bit reservoir and at most 8*1440 bit from the current 105 | * frame (320 kbps, 32 kHz), so 8*1951 bit is the largest possible 106 | * value for MPEG-1 and -2) 107 | * 108 | * maximum allowed granule/channel size times 4 = 8*2047 bits., 109 | * so this is the absolute maximum supported by the format. 110 | * 111 | * 112 | * fullFrameBits: maximum number of bits available for encoding 113 | * the current frame. 114 | * 115 | * mean_bits: target number of bits per granule. 116 | * 117 | * frameLength: 118 | * 119 | * gfc->ResvMax: maximum allowed reservoir 120 | * 121 | * gfc->ResvSize: current reservoir size 122 | * 123 | * l3_side->resvDrain_pre: 124 | * ancillary data to be added to previous frame: 125 | * (only usefull in VBR modes if it is possible to have 126 | * maxmp3buf < fullFrameBits)). Currently disabled, 127 | * see #define NEW_DRAIN 128 | * 2010-02-13: RH now enabled, it seems to be needed for CBR too, 129 | * as there exists one example, where the FhG decoder 130 | * can't decode a -b320 CBR file anymore. 131 | * 132 | * l3_side->resvDrain_post: 133 | * ancillary data to be added to this frame: 134 | * 135 | */ 136 | 137 | /* main_data_begin has 9 bits in MPEG-1, 8 bits MPEG-2 */ 138 | resvLimit = (8 * 256) * cfg->mode_gr - 8; 139 | 140 | /* maximum allowed frame size. dont use more than this number of 141 | bits, even if the frame has the space for them: */ 142 | maxmp3buf = cfg->buffer_constraint; 143 | esv->ResvMax = maxmp3buf - frameLength; 144 | if (esv->ResvMax > resvLimit) 145 | esv->ResvMax = resvLimit; 146 | if (esv->ResvMax < 0 || cfg->disable_reservoir) 147 | esv->ResvMax = 0; 148 | 149 | fullFrameBits = meanBits * cfg->mode_gr + Min(esv->ResvSize, esv->ResvMax); 150 | 151 | if (fullFrameBits > maxmp3buf) 152 | fullFrameBits = maxmp3buf; 153 | 154 | assert(0 == esv->ResvMax % 8); 155 | assert(esv->ResvMax >= 0); 156 | 157 | l3_side->resvDrain_pre = 0; 158 | 159 | if (gfc->pinfo != NULL) { 160 | gfc->pinfo->mean_bits = meanBits / 2; /* expected bits per channel per granule [is this also right for mono/stereo, MPEG-1/2 ?] */ 161 | gfc->pinfo->resvsize = esv->ResvSize; 162 | } 163 | *mean_bits = meanBits; 164 | return fullFrameBits; 165 | } 166 | 167 | 168 | /* 169 | ResvMaxBits 170 | returns targ_bits: target number of bits to use for 1 granule 171 | extra_bits: amount extra available from reservoir 172 | Mark Taylor 4/99 173 | */ 174 | void 175 | ResvMaxBits(lame_internal_flags * gfc, int mean_bits, int *targ_bits, int *extra_bits, int cbr) 176 | { 177 | SessionConfig_t const *const cfg = &gfc->cfg; 178 | EncStateVar_t *const esv = &gfc->sv_enc; 179 | int add_bits, targBits, extraBits; 180 | int ResvSize = esv->ResvSize, ResvMax = esv->ResvMax; 181 | 182 | /* conpensate the saved bits used in the 1st granule */ 183 | if (cbr) 184 | ResvSize += mean_bits; 185 | 186 | if (gfc->sv_qnt.substep_shaping & 1) 187 | ResvMax *= 0.9; 188 | 189 | targBits = mean_bits; 190 | 191 | /* extra bits if the reservoir is almost full */ 192 | if (ResvSize * 10 > ResvMax * 9) { 193 | add_bits = ResvSize - (ResvMax * 9) / 10; 194 | targBits += add_bits; 195 | gfc->sv_qnt.substep_shaping |= 0x80; 196 | } 197 | else { 198 | add_bits = 0; 199 | gfc->sv_qnt.substep_shaping &= 0x7f; 200 | /* build up reservoir. this builds the reservoir a little slower 201 | * than FhG. It could simple be mean_bits/15, but this was rigged 202 | * to always produce 100 (the old value) at 128kbs */ 203 | /* *targ_bits -= (int) (mean_bits/15.2); */ 204 | if (!cfg->disable_reservoir && !(gfc->sv_qnt.substep_shaping & 1)) 205 | targBits -= .1 * mean_bits; 206 | } 207 | 208 | 209 | /* amount from the reservoir we are allowed to use. ISO says 6/10 */ 210 | extraBits = (ResvSize < (esv->ResvMax * 6) / 10 ? ResvSize : (esv->ResvMax * 6) / 10); 211 | extraBits -= add_bits; 212 | 213 | if (extraBits < 0) 214 | extraBits = 0; 215 | 216 | *targ_bits = targBits; 217 | *extra_bits = extraBits; 218 | } 219 | 220 | /* 221 | ResvAdjust: 222 | Called after a granule's bit allocation. Readjusts the size of 223 | the reservoir to reflect the granule's usage. 224 | */ 225 | void 226 | ResvAdjust(lame_internal_flags * gfc, gr_info const *gi) 227 | { 228 | gfc->sv_enc.ResvSize -= gi->part2_3_length + gi->part2_length; 229 | } 230 | 231 | 232 | /* 233 | ResvFrameEnd: 234 | Called after all granules in a frame have been allocated. Makes sure 235 | that the reservoir size is within limits, possibly by adding stuffing 236 | bits. 237 | */ 238 | void 239 | ResvFrameEnd(lame_internal_flags * gfc, int mean_bits) 240 | { 241 | SessionConfig_t const *const cfg = &gfc->cfg; 242 | EncStateVar_t *const esv = &gfc->sv_enc; 243 | III_side_info_t *const l3_side = &gfc->l3_side; 244 | int stuffingBits; 245 | int over_bits; 246 | 247 | esv->ResvSize += mean_bits * cfg->mode_gr; 248 | stuffingBits = 0; 249 | l3_side->resvDrain_post = 0; 250 | l3_side->resvDrain_pre = 0; 251 | 252 | /* we must be byte aligned */ 253 | if ((over_bits = esv->ResvSize % 8) != 0) 254 | stuffingBits += over_bits; 255 | 256 | 257 | over_bits = (esv->ResvSize - stuffingBits) - esv->ResvMax; 258 | if (over_bits > 0) { 259 | assert(0 == over_bits % 8); 260 | assert(over_bits >= 0); 261 | stuffingBits += over_bits; 262 | } 263 | 264 | 265 | /* NOTE: enabling the NEW_DRAIN code fixes some problems with FhG decoder 266 | shipped with MS Windows operating systems. Using this, it is even 267 | possible to use Gabriel's lax buffer consideration again, which 268 | assumes, any decoder should have a buffer large enough 269 | for a 320 kbps frame at 32 kHz sample rate. 270 | 271 | old drain code: 272 | lame -b320 BlackBird.wav ---> does not play with GraphEdit.exe using FhG decoder V1.5 Build 50 273 | 274 | new drain code: 275 | lame -b320 BlackBird.wav ---> plays fine with GraphEdit.exe using FhG decoder V1.5 Build 50 276 | 277 | Robert Hegemann, 2010-02-13. 278 | */ 279 | /* drain as many bits as possible into previous frame ancillary data 280 | * In particular, in VBR mode ResvMax may have changed, and we have 281 | * to make sure main_data_begin does not create a reservoir bigger 282 | * than ResvMax mt 4/00*/ 283 | { 284 | int mdb_bytes = Min(l3_side->main_data_begin * 8, stuffingBits) / 8; 285 | l3_side->resvDrain_pre += 8 * mdb_bytes; 286 | stuffingBits -= 8 * mdb_bytes; 287 | esv->ResvSize -= 8 * mdb_bytes; 288 | l3_side->main_data_begin -= mdb_bytes; 289 | } 290 | /* drain the rest into this frames ancillary data */ 291 | l3_side->resvDrain_post += stuffingBits; 292 | esv->ResvSize -= stuffingBits; 293 | } 294 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/reservoir.h: -------------------------------------------------------------------------------- 1 | /* 2 | * bit reservoir include file 3 | * 4 | * Copyright (c) 1999 Mark Taylor 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Library General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Library General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Library General Public 17 | * License along with this library; if not, write to the 18 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 | * Boston, MA 02111-1307, USA. 20 | */ 21 | 22 | #ifndef LAME_RESERVOIR_H 23 | #define LAME_RESERVOIR_H 24 | 25 | int ResvFrameBegin(lame_internal_flags * gfc, int *mean_bits); 26 | void ResvMaxBits(lame_internal_flags * gfc, int mean_bits, int *targ_bits, int *max_bits, 27 | int cbr); 28 | void ResvAdjust(lame_internal_flags * gfc, gr_info const *gi); 29 | void ResvFrameEnd(lame_internal_flags * gfc, int mean_bits); 30 | 31 | #endif /* LAME_RESERVOIR_H */ 32 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/set_get.h: -------------------------------------------------------------------------------- 1 | /* 2 | * set_get.h -- Internal set/get definitions 3 | * 4 | * Copyright (C) 2003 Gabriel Bouvigne / Lame project 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Library General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Library General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Library General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 19 | */ 20 | 21 | #ifndef __SET_GET_H__ 22 | #define __SET_GET_H__ 23 | 24 | #include "lame.h" 25 | 26 | #if defined(__cplusplus) 27 | extern "C" { 28 | #endif 29 | 30 | /* select psychoacoustic model */ 31 | 32 | /* manage short blocks */ 33 | int CDECL lame_set_short_threshold(lame_global_flags *, float, float); 34 | int CDECL lame_set_short_threshold_lrm(lame_global_flags *, float); 35 | float CDECL lame_get_short_threshold_lrm(const lame_global_flags *); 36 | int CDECL lame_set_short_threshold_s(lame_global_flags *, float); 37 | float CDECL lame_get_short_threshold_s(const lame_global_flags *); 38 | 39 | 40 | int CDECL lame_set_maskingadjust(lame_global_flags *, float); 41 | float CDECL lame_get_maskingadjust(const lame_global_flags *); 42 | 43 | int CDECL lame_set_maskingadjust_short(lame_global_flags *, float); 44 | float CDECL lame_get_maskingadjust_short(const lame_global_flags *); 45 | 46 | /* select ATH formula 4 shape */ 47 | int CDECL lame_set_ATHcurve(lame_global_flags *, float); 48 | float CDECL lame_get_ATHcurve(const lame_global_flags *); 49 | 50 | int CDECL lame_set_preset_notune(lame_global_flags *, int); 51 | 52 | /* substep shaping method */ 53 | int CDECL lame_set_substep(lame_global_flags *, int); 54 | int CDECL lame_get_substep(const lame_global_flags *); 55 | 56 | /* scalefactors scale */ 57 | int CDECL lame_set_sfscale(lame_global_flags *, int); 58 | int CDECL lame_get_sfscale(const lame_global_flags *); 59 | 60 | /* subblock gain */ 61 | int CDECL lame_set_subblock_gain(lame_global_flags *, int); 62 | int CDECL lame_get_subblock_gain(const lame_global_flags *); 63 | 64 | 65 | 66 | /*presets*/ 67 | int apply_preset(lame_global_flags *, int preset, int enforce); 68 | 69 | void CDECL lame_set_tune(lame_t, float); /* FOR INTERNAL USE ONLY */ 70 | void CDECL lame_set_msfix(lame_t gfp, double msfix); 71 | 72 | 73 | #if defined(__cplusplus) 74 | } 75 | #endif 76 | #endif 77 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/tables.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MPEG layer 3 tables include file 3 | * 4 | * Copyright (c) 1999 Albert L Faber 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Library General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Library General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Library General Public 17 | * License along with this library; if not, write to the 18 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 | * Boston, MA 02111-1307, USA. 20 | */ 21 | 22 | #ifndef LAME_TABLES_H 23 | #define LAME_TABLES_H 24 | 25 | #if 0 26 | typedef struct { 27 | unsigned char no; 28 | unsigned char width; 29 | unsigned char minval_2; 30 | float quiet_thr; 31 | float norm; 32 | float bark; 33 | } type1_t; 34 | 35 | typedef struct { 36 | unsigned char no; 37 | unsigned char width; 38 | float quiet_thr; 39 | float norm; 40 | float SNR; 41 | float bark; 42 | } type2_t; 43 | 44 | typedef struct { 45 | unsigned int no:5; 46 | unsigned int cbw:3; 47 | unsigned int bu:6; 48 | unsigned int bo:6; 49 | unsigned int w1_576:10; 50 | unsigned int w2_576:10; 51 | } type34_t; 52 | 53 | typedef struct { 54 | size_t len1; 55 | const type1_t *const tab1; 56 | size_t len2; 57 | const type2_t *const tab2; 58 | size_t len3; 59 | const type34_t *const tab3; 60 | size_t len4; 61 | const type34_t *const tab4; 62 | } type5_t; 63 | 64 | extern const type5_t table5[6]; 65 | 66 | #endif 67 | 68 | #define HTN 34 69 | 70 | struct huffcodetab { 71 | const unsigned int xlen; /* max. x-index+ */ 72 | const unsigned int linmax; /* max number to be stored in linbits */ 73 | const uint16_t *table; /* pointer to array[xlen][ylen] */ 74 | const uint8_t *hlen; /* pointer to array[xlen][ylen] */ 75 | }; 76 | 77 | extern const struct huffcodetab ht[HTN]; 78 | /* global memory block */ 79 | /* array of all huffcodtable headers */ 80 | /* 0..31 Huffman code table 0..31 */ 81 | /* 32,33 count1-tables */ 82 | 83 | extern const uint8_t t32l[]; 84 | extern const uint8_t t33l[]; 85 | 86 | extern const uint32_t largetbl[16 * 16]; 87 | extern const uint32_t table23[3 * 3]; 88 | extern const uint32_t table56[4 * 4]; 89 | 90 | extern const int scfsi_band[5]; 91 | 92 | extern const int bitrate_table [3][16]; 93 | extern const int samplerate_table [3][ 4]; 94 | 95 | #endif /* LAME_TABLES_H */ 96 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/vbrquantize.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MP3 VBR quantization 3 | * 4 | * Copyright (c) 1999 Mark Taylor 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Library General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Library General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Library General Public 17 | * License along with this library; if not, write to the 18 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 | * Boston, MA 02111-1307, USA. 20 | */ 21 | 22 | #ifndef LAME_VBRQUANTIZE_H 23 | #define LAME_VBRQUANTIZE_H 24 | 25 | int VBR_encode_frame(lame_internal_flags * gfc, const FLOAT xr34orig[2][2][576], 26 | const FLOAT l3_xmin[2][2][SFBMAX], const int maxbits[2][2]); 27 | 28 | #endif /* LAME_VBRQUANTIZE_H */ 29 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/version.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Version numbering for LAME. 3 | * 4 | * Copyright (c) 1999 A.L. Faber 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Library General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Library General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Library General Public 17 | * License along with this library; if not, write to the 18 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 | * Boston, MA 02111-1307, USA. 20 | */ 21 | 22 | /*! 23 | \file version.c 24 | \brief Version numbering for LAME. 25 | 26 | Contains functions which describe the version of LAME. 27 | 28 | \author A.L. Faber 29 | \version \$Id: version.c,v 1.32.2.2 2011/11/18 09:18:28 robert Exp $ 30 | \ingroup libmp3lame 31 | */ 32 | 33 | 34 | #ifdef HAVE_CONFIG_H 35 | # include 36 | #endif 37 | 38 | 39 | #include "lame.h" 40 | #include "machine.h" 41 | 42 | #include "version.h" /* macros of version numbers */ 43 | 44 | 45 | 46 | 47 | 48 | /*! Get the LAME version string. */ 49 | /*! 50 | \param void 51 | \return a pointer to a string which describes the version of LAME. 52 | */ 53 | const char * 54 | get_lame_version(void) 55 | { /* primary to write screen reports */ 56 | /* Here we can also add informations about compile time configurations */ 57 | 58 | #if LAME_ALPHA_VERSION 59 | static /*@observer@ */ const char *const str = 60 | STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) " " 61 | "(alpha " STR(LAME_PATCH_VERSION) ", " __DATE__ " " __TIME__ ")"; 62 | #elif LAME_BETA_VERSION 63 | static /*@observer@ */ const char *const str = 64 | STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) " " 65 | "(beta " STR(LAME_PATCH_VERSION) ", " __DATE__ ")"; 66 | #elif LAME_RELEASE_VERSION && (LAME_PATCH_VERSION > 0) 67 | static /*@observer@ */ const char *const str = 68 | STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) "." STR(LAME_PATCH_VERSION); 69 | #else 70 | static /*@observer@ */ const char *const str = 71 | STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION); 72 | #endif 73 | 74 | return str; 75 | } 76 | 77 | 78 | /*! Get the short LAME version string. */ 79 | /*! 80 | It's mainly for inclusion into the MP3 stream. 81 | 82 | \param void 83 | \return a pointer to the short version of the LAME version string. 84 | */ 85 | const char * 86 | get_lame_short_version(void) 87 | { 88 | /* adding date and time to version string makes it harder for output 89 | validation */ 90 | 91 | #if LAME_ALPHA_VERSION 92 | static /*@observer@ */ const char *const str = 93 | STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) " (alpha " STR(LAME_PATCH_VERSION) ")"; 94 | #elif LAME_BETA_VERSION 95 | static /*@observer@ */ const char *const str = 96 | STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) " (beta " STR(LAME_PATCH_VERSION) ")"; 97 | #elif LAME_RELEASE_VERSION && (LAME_PATCH_VERSION > 0) 98 | static /*@observer@ */ const char *const str = 99 | STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) "." STR(LAME_PATCH_VERSION); 100 | #else 101 | static /*@observer@ */ const char *const str = 102 | STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION); 103 | #endif 104 | 105 | return str; 106 | } 107 | 108 | /*! Get the _very_ short LAME version string. */ 109 | /*! 110 | It's used in the LAME VBR tag only. 111 | 112 | \param void 113 | \return a pointer to the short version of the LAME version string. 114 | */ 115 | const char * 116 | get_lame_very_short_version(void) 117 | { 118 | /* adding date and time to version string makes it harder for output 119 | validation */ 120 | #if LAME_ALPHA_VERSION 121 | #define P "a" 122 | #elif LAME_BETA_VERSION 123 | #define P "b" 124 | #elif LAME_RELEASE_VERSION && (LAME_PATCH_VERSION > 0) 125 | #define P "r" 126 | #else 127 | #define P "" 128 | #endif 129 | static /*@observer@ */ const char *const str = 130 | #if (LAME_PATCH_VERSION > 0) 131 | "LAME" STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) P STR(LAME_PATCH_VERSION) 132 | #else 133 | "LAME" STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) P 134 | #endif 135 | ; 136 | return str; 137 | } 138 | 139 | /*! Get the _very_ short LAME version string. */ 140 | /*! 141 | It's used in the LAME VBR tag only, limited to 9 characters max. 142 | Due to some 3rd party HW/SW decoders, it has to start with LAME. 143 | 144 | \param void 145 | \return a pointer to the short version of the LAME version string. 146 | */ 147 | const char* 148 | get_lame_tag_encoder_short_version(void) 149 | { 150 | static /*@observer@ */ const char *const str = 151 | /* FIXME: new scheme / new version counting / drop versioning here ? */ 152 | "LAME" STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) P 153 | ; 154 | return str; 155 | } 156 | 157 | /*! Get the version string for GPSYCHO. */ 158 | /*! 159 | \param void 160 | \return a pointer to a string which describes the version of GPSYCHO. 161 | */ 162 | const char * 163 | get_psy_version(void) 164 | { 165 | #if PSY_ALPHA_VERSION > 0 166 | static /*@observer@ */ const char *const str = 167 | STR(PSY_MAJOR_VERSION) "." STR(PSY_MINOR_VERSION) 168 | " (alpha " STR(PSY_ALPHA_VERSION) ", " __DATE__ " " __TIME__ ")"; 169 | #elif PSY_BETA_VERSION > 0 170 | static /*@observer@ */ const char *const str = 171 | STR(PSY_MAJOR_VERSION) "." STR(PSY_MINOR_VERSION) 172 | " (beta " STR(PSY_BETA_VERSION) ", " __DATE__ ")"; 173 | #else 174 | static /*@observer@ */ const char *const str = 175 | STR(PSY_MAJOR_VERSION) "." STR(PSY_MINOR_VERSION); 176 | #endif 177 | 178 | return str; 179 | } 180 | 181 | 182 | /*! Get the URL for the LAME website. */ 183 | /*! 184 | \param void 185 | \return a pointer to a string which is a URL for the LAME website. 186 | */ 187 | const char * 188 | get_lame_url(void) 189 | { 190 | static /*@observer@ */ const char *const str = LAME_URL; 191 | 192 | return str; 193 | } 194 | 195 | 196 | /*! Get the numerical representation of the version. */ 197 | /*! 198 | Writes the numerical representation of the version of LAME and 199 | GPSYCHO into lvp. 200 | 201 | \param lvp 202 | */ 203 | void 204 | get_lame_version_numerical(lame_version_t * lvp) 205 | { 206 | static /*@observer@ */ const char *const features = ""; /* obsolete */ 207 | 208 | /* generic version */ 209 | lvp->major = LAME_MAJOR_VERSION; 210 | lvp->minor = LAME_MINOR_VERSION; 211 | #if LAME_ALPHA_VERSION 212 | lvp->alpha = LAME_PATCH_VERSION; 213 | lvp->beta = 0; 214 | #elif LAME_BETA_VERSION 215 | lvp->alpha = 0; 216 | lvp->beta = LAME_PATCH_VERSION; 217 | #else 218 | lvp->alpha = 0; 219 | lvp->beta = 0; 220 | #endif 221 | 222 | /* psy version */ 223 | lvp->psy_major = PSY_MAJOR_VERSION; 224 | lvp->psy_minor = PSY_MINOR_VERSION; 225 | lvp->psy_alpha = PSY_ALPHA_VERSION; 226 | lvp->psy_beta = PSY_BETA_VERSION; 227 | 228 | /* compile time features */ 229 | /*@-mustfree@ */ 230 | lvp->features = features; 231 | /*@=mustfree@ */ 232 | } 233 | 234 | 235 | const char * 236 | get_lame_os_bitness(void) 237 | { 238 | static /*@observer@ */ const char *const strXX = ""; 239 | static /*@observer@ */ const char *const str32 = "32bits"; 240 | static /*@observer@ */ const char *const str64 = "64bits"; 241 | 242 | switch (sizeof(void *)) { 243 | case 4: 244 | return str32; 245 | 246 | case 8: 247 | return str64; 248 | 249 | default: 250 | return strXX; 251 | } 252 | } 253 | 254 | /* end of version.c */ 255 | -------------------------------------------------------------------------------- /app/src/main/cpp/lamemp3/version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Version numbering for LAME. 3 | * 4 | * Copyright (c) 1999 A.L. Faber 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Library General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2 of the License, or (at your option) any later version. 10 | * 11 | * This library is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Library General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Library General Public 17 | * License along with this library; if not, write to the 18 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 19 | * Boston, MA 02111-1307, USA. 20 | */ 21 | 22 | #ifndef LAME_VERSION_H 23 | #define LAME_VERSION_H 24 | 25 | 26 | /* 27 | * To make a string from a token, use the # operator: 28 | */ 29 | #ifndef STR 30 | # define __STR(x) #x 31 | # define STR(x) __STR(x) 32 | #endif 33 | 34 | # define LAME_URL "http://lame.sf.net" 35 | 36 | 37 | # define LAME_MAJOR_VERSION 3 /* Major version number */ 38 | # define LAME_MINOR_VERSION 99 /* Minor version number */ 39 | # define LAME_TYPE_VERSION 2 /* 0:alpha 1:beta 2:release */ 40 | # define LAME_PATCH_VERSION 5 /* Patch level */ 41 | # define LAME_ALPHA_VERSION (LAME_TYPE_VERSION==0) 42 | # define LAME_BETA_VERSION (LAME_TYPE_VERSION==1) 43 | # define LAME_RELEASE_VERSION (LAME_TYPE_VERSION==2) 44 | 45 | # define PSY_MAJOR_VERSION 1 /* Major version number */ 46 | # define PSY_MINOR_VERSION 0 /* Minor version number */ 47 | # define PSY_ALPHA_VERSION 0 /* Set number if this is an alpha version, otherwise zero */ 48 | # define PSY_BETA_VERSION 0 /* Set number if this is a beta version, otherwise zero */ 49 | 50 | #if LAME_ALPHA_VERSION 51 | #define LAME_PATCH_LEVEL_STRING " alpha " STR(LAME_PATCH_VERSION) 52 | #endif 53 | #if LAME_BETA_VERSION 54 | #define LAME_PATCH_LEVEL_STRING " beta " STR(LAME_PATCH_VERSION) 55 | #endif 56 | #if LAME_RELEASE_VERSION 57 | #if LAME_PATCH_VERSION 58 | #define LAME_PATCH_LEVEL_STRING " release " STR(LAME_PATCH_VERSION) 59 | #else 60 | #define LAME_PATCH_LEVEL_STRING "" 61 | #endif 62 | #endif 63 | 64 | # define LAME_VERSION_STRING STR(LAME_MAJOR_VERSION) "." STR(LAME_MINOR_VERSION) LAME_PATCH_LEVEL_STRING 65 | 66 | #endif /* LAME_VERSION_H */ 67 | 68 | /* End of version.h */ 69 | -------------------------------------------------------------------------------- /app/src/main/java/com/clam314/lame/DataEncodeThread.java: -------------------------------------------------------------------------------- 1 | package com.clam314.lame; 2 | 3 | 4 | import java.io.FileOutputStream; 5 | import java.io.IOException; 6 | import java.lang.ref.WeakReference; 7 | import java.nio.ByteBuffer; 8 | import java.nio.ByteOrder; 9 | import java.util.Collections; 10 | import java.util.LinkedList; 11 | import java.util.List; 12 | import java.util.concurrent.CountDownLatch; 13 | 14 | import android.media.AudioRecord; 15 | import android.os.Handler; 16 | import android.os.Looper; 17 | import android.os.Message; 18 | import android.util.Log; 19 | 20 | /** 21 | * Created by clam314 on 2017/3/26. 22 | */ 23 | 24 | 25 | public class DataEncodeThread extends Thread implements AudioRecord.OnRecordPositionUpdateListener { 26 | 27 | private static final String TAG = DataEncodeThread.class.getSimpleName(); 28 | 29 | public static final int PROCESS_STOP = 1; 30 | 31 | private StopHandler handler; 32 | 33 | 34 | private byte[] mp3Buffer; 35 | 36 | //用于存取待转换的PCM数据 37 | private List mChangeBuffers = Collections.synchronizedList(new LinkedList()); 38 | 39 | private FileOutputStream os; 40 | 41 | private CountDownLatch handlerInitLatch = new CountDownLatch(1); 42 | 43 | 44 | private static class StopHandler extends Handler { 45 | 46 | WeakReference encodeThread; 47 | 48 | public StopHandler(DataEncodeThread encodeThread) { 49 | this.encodeThread = new WeakReference<>(encodeThread); 50 | } 51 | 52 | @Override 53 | public void handleMessage(Message msg) { 54 | if (msg.what == PROCESS_STOP) { 55 | DataEncodeThread threadRef = encodeThread.get(); 56 | 57 | //录音停止后,将剩余的PCM数据转换完毕 58 | for (;threadRef.processData() > 0;); 59 | 60 | removeCallbacksAndMessages(null); 61 | threadRef.flushAndRelease(); 62 | getLooper().quit(); 63 | } 64 | super.handleMessage(msg); 65 | } 66 | } 67 | 68 | 69 | public DataEncodeThread(FileOutputStream os, int bufferSize) { 70 | this.os = os; 71 | mp3Buffer = new byte[(int) (7200 + (bufferSize * 2 * 1.25))]; 72 | } 73 | 74 | @Override 75 | public void run() { 76 | Looper.prepare(); 77 | handler = new StopHandler(this); 78 | handlerInitLatch.countDown(); 79 | Looper.loop(); 80 | } 81 | 82 | 83 | public Handler getHandler() { 84 | try { 85 | handlerInitLatch.await(); 86 | } catch (InterruptedException e) { 87 | e.printStackTrace(); 88 | Log.e(TAG, "Error when waiting handle to init"); 89 | } 90 | return handler; 91 | } 92 | 93 | @Override 94 | public void onMarkerReached(AudioRecord recorder) { 95 | // Do nothing 96 | } 97 | 98 | @Override 99 | public void onPeriodicNotification(AudioRecord recorder) { 100 | //由AudioRecord进行回调,满足帧数,通知数据转换 101 | processData(); 102 | } 103 | 104 | 105 | //从缓存区ChangeBuffers里获取待转换的PCM数据,转换为MP3数据,并写入文件 106 | private int processData() { 107 | if(mChangeBuffers != null && mChangeBuffers.size() > 0) { 108 | ChangeBuffer changeBuffer = mChangeBuffers.remove(0); 109 | short[] buffer = changeBuffer.getData(); 110 | int readSize = changeBuffer.getReadSize(); 111 | Log.d(TAG, "Read size: " + readSize); 112 | if (readSize > 0) { 113 | int encodedSize = SimpleLame.encode(buffer, buffer, readSize, mp3Buffer); 114 | if (encodedSize < 0) { 115 | Log.e(TAG, "Lame encoded size: " + encodedSize); 116 | } 117 | try { 118 | os.write(mp3Buffer, 0, encodedSize); 119 | } catch (IOException e) { 120 | e.printStackTrace(); 121 | Log.e(TAG, "Unable to write to file"); 122 | } 123 | return readSize; 124 | } 125 | } 126 | return 0; 127 | } 128 | 129 | 130 | private void flushAndRelease() { 131 | final int flushResult = SimpleLame.flush(mp3Buffer); 132 | 133 | if (flushResult > 0) { 134 | try { 135 | os.write(mp3Buffer, 0, flushResult); 136 | } catch (final IOException e) { 137 | e.printStackTrace(); 138 | } 139 | } 140 | } 141 | 142 | public void addChangeBuffer(short[] rawData, int readSize){ 143 | mChangeBuffers.add(new ChangeBuffer(rawData, readSize)); 144 | } 145 | 146 | private class ChangeBuffer{ 147 | 148 | private short[] rawData; 149 | private int readSize; 150 | 151 | public ChangeBuffer(short[] rawData, int readSize){ 152 | this.rawData = rawData.clone(); 153 | this.readSize = readSize; 154 | } 155 | public short[] getData(){ 156 | return rawData; 157 | } 158 | public int getReadSize(){ 159 | return readSize; 160 | } 161 | } 162 | } -------------------------------------------------------------------------------- /app/src/main/java/com/clam314/lame/LameMp3Manager.java: -------------------------------------------------------------------------------- 1 | package com.clam314.lame; 2 | 3 | 4 | import android.util.Log; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | 9 | /** 10 | * Created by clam314 on 2016/8/24 11 | * 12 | * 对Mp3Recorder进行多一次封装,增加录音取消相应的逻辑 13 | */ 14 | public enum LameMp3Manager implements Mp3Recorder.OnFinishListener { 15 | instance; 16 | 17 | private static final String TAG = LameMp3Manager.class.getSimpleName(); 18 | private Mp3Recorder mp3Recorder; 19 | private boolean cancel = false; 20 | private boolean stop = false; 21 | private MediaRecorderListener mediaRecorderListener; 22 | 23 | LameMp3Manager(){ 24 | mp3Recorder = new Mp3Recorder(); 25 | mp3Recorder.setFinishListener(this); 26 | } 27 | 28 | public void setMediaRecorderListener(MediaRecorderListener listener){ 29 | mediaRecorderListener = listener; 30 | } 31 | 32 | public void startRecorder(String saveMp3FullName){ 33 | cancel = stop = false; 34 | try { 35 | mp3Recorder.startRecording(createMp3SaveFile(saveMp3FullName)); 36 | }catch (IOException e){ 37 | e.printStackTrace(); 38 | } 39 | } 40 | 41 | public void cancelRecorder(){ 42 | try { 43 | mp3Recorder.stopRecording(); 44 | cancel = true; 45 | }catch (IOException e){ 46 | e.printStackTrace(); 47 | } 48 | } 49 | 50 | public void stopRecorder(){ 51 | try { 52 | mp3Recorder.stopRecording(); 53 | stop = true; 54 | }catch (IOException e){ 55 | e.printStackTrace(); 56 | } 57 | } 58 | 59 | private File createMp3SaveFile(String saveMp3FullName){ 60 | File mp3 = new File(saveMp3FullName); 61 | Log.d(TAG,"create mp3 file for the recorder"); 62 | return mp3; 63 | } 64 | 65 | 66 | @Override 67 | public void onFinish(String mp3FilePath) { 68 | if(cancel){ 69 | //录音取消的话,将之前的录音数据清掉 70 | File mp3 = new File(mp3FilePath); 71 | if(mp3.exists()){ 72 | mp3.delete(); 73 | } 74 | cancel = false; 75 | }else if(stop){ 76 | stop = false; 77 | if(mediaRecorderListener != null){ 78 | mediaRecorderListener.onRecorderFinish(209,mp3FilePath); 79 | } 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /app/src/main/java/com/clam314/lame/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.clam314.lame; 2 | 3 | import android.graphics.drawable.AnimationDrawable; 4 | import android.media.MediaPlayer; 5 | import android.os.Bundle; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.text.TextUtils; 8 | import android.view.View; 9 | import android.view.Window; 10 | import android.widget.ImageView; 11 | import android.widget.Toast; 12 | 13 | import static android.R.attr.path; 14 | 15 | public class MainActivity extends AppCompatActivity { 16 | private MediaRecorderButton btRecorder; 17 | private ImageView btPlayer; 18 | private String filePath; 19 | 20 | @Override 21 | protected void onCreate(Bundle savedInstanceState) { 22 | super.onCreate(savedInstanceState); 23 | setContentView(R.layout.activity_main); 24 | 25 | //创建播放时用的动画 26 | AnimationDrawable frameDrawable = (AnimationDrawable) getResources().getDrawable(R.drawable.anim_voice_left); 27 | btPlayer = (ImageView)findViewById(R.id.bt_player); 28 | btPlayer.setImageDrawable(frameDrawable); 29 | //动画显示在第一帧 30 | frameDrawable.selectDrawable(0); 31 | btPlayer.setOnClickListener(new View.OnClickListener() { 32 | @Override 33 | public void onClick(final View v) { 34 | if(TextUtils.isEmpty(filePath)){ 35 | Toast.makeText(v.getContext(),"文件路径错误",Toast.LENGTH_SHORT).show(); 36 | }else { 37 | if(v.getTag() != null){ 38 | String tag = (String) v.getTag(); 39 | //语音正在播放,此时单击停止播放 40 | if("showing".equals(tag)){ 41 | //释放资源 42 | MediaPlayUtil.release(); 43 | ((AnimationDrawable)((ImageView)v).getDrawable()).stop(); 44 | ((AnimationDrawable)((ImageView)v).getDrawable()).selectDrawable(0); 45 | v.setTag("showed"); 46 | return; 47 | } 48 | } 49 | 50 | //开始播放语音,并开始动画 51 | ((AnimationDrawable)((ImageView)v).getDrawable()).start(); 52 | v.setTag("showing"); 53 | MediaPlayUtil.init(getApplicationContext()); 54 | MediaPlayUtil.playSound(filePath, new MediaPlayer.OnCompletionListener() { 55 | @Override 56 | public void onCompletion(MediaPlayer mp) { 57 | ((AnimationDrawable)((ImageView)v).getDrawable()).stop(); 58 | ((AnimationDrawable)((ImageView)v).getDrawable()).selectDrawable(0); 59 | v.setTag("showed"); 60 | MediaPlayUtil.release(); 61 | } 62 | }); 63 | } 64 | } 65 | }); 66 | 67 | 68 | btRecorder = (MediaRecorderButton)findViewById(R.id.bt_media_recorder); 69 | btRecorder.setFinishListener(new MediaRecorderButton.RecorderFinishListener() { 70 | @Override 71 | public void onRecorderFinish(int status, String path, String second) { 72 | if(status == MediaRecorderButton.RECORDER_SUCCESS){ 73 | filePath = path; 74 | } 75 | } 76 | }); 77 | btRecorder.setRecorderStatusListener(new MediaRecorderButton.RecorderStatusListener() { 78 | @Override 79 | public void onStart(int status) { 80 | Toast.makeText(MainActivity.this,"开始录音",Toast.LENGTH_SHORT).show(); 81 | } 82 | 83 | @Override 84 | public void onEnd(int status) { 85 | //status除了是状态还有录音的秒数 86 | switch (status){ 87 | case MediaRecorderButton.END_RECORDER_TOO_SHORT: 88 | Toast.makeText(MainActivity.this,"讲话时间太短啦!",Toast.LENGTH_SHORT).show(); 89 | break; 90 | case 10: 91 | Toast.makeText(MainActivity.this,"录音50秒啦,10秒后自动发送",Toast.LENGTH_SHORT).show(); 92 | break; 93 | case MediaRecorderButton.END_RECORDER_60S: 94 | Toast.makeText(MainActivity.this,"录音已经自动发送",Toast.LENGTH_SHORT).show(); 95 | break; 96 | } 97 | } 98 | }); 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /app/src/main/java/com/clam314/lame/MediaPlayUtil.java: -------------------------------------------------------------------------------- 1 | package com.clam314.lame; 2 | 3 | import android.content.Context; 4 | import android.media.MediaPlayer; 5 | import android.os.Handler; 6 | 7 | import java.io.File; 8 | import java.io.FileInputStream; 9 | import java.io.IOException; 10 | import java.lang.reflect.Constructor; 11 | import java.lang.reflect.Field; 12 | import java.lang.reflect.Method; 13 | 14 | /** 15 | * Created by clam314 on 2016/7/20 16 | * 17 | * 对系统的MediaPlay进行简单的封装,使其只需要三步就可以播放音频文件 18 | */ 19 | public class MediaPlayUtil { 20 | 21 | private static MediaPlayer mediaPlayer; 22 | 23 | //播放前需要初始化 24 | public static void init(Context context){ 25 | if(mediaPlayer == null){ 26 | synchronized (MediaPlayUtil.class){ 27 | mediaPlayer = getMediaPlayer(context); 28 | } 29 | } 30 | } 31 | 32 | //播放音频 33 | public static void playSound(String path, MediaPlayer.OnCompletionListener listener) { 34 | if(mediaPlayer == null){ 35 | throw new RuntimeException("MediaPlayer no init,please call init() before"); 36 | } 37 | try { 38 | mediaPlayer.setAudioStreamType(android.media.AudioManager.STREAM_MUSIC); 39 | File file = new File(path); 40 | FileInputStream fis = new FileInputStream(file); 41 | mediaPlayer.setDataSource(fis.getFD()); 42 | mediaPlayer.prepare(); 43 | mediaPlayer.setOnCompletionListener(listener); 44 | mediaPlayer.start(); 45 | }catch (IllegalArgumentException e) { 46 | e.printStackTrace(); 47 | mediaPlayer.reset(); 48 | } catch (SecurityException e) { 49 | e.printStackTrace(); 50 | mediaPlayer.reset(); 51 | } catch (IllegalStateException e) { 52 | e.printStackTrace(); 53 | mediaPlayer.reset(); 54 | } catch (IOException e) { 55 | e.printStackTrace(); 56 | mediaPlayer.reset(); 57 | } 58 | } 59 | 60 | //播放完毕需要释放MediaPlayer的资源 61 | public static void release(){ 62 | if(mediaPlayer != null){ 63 | mediaPlayer.reset(); 64 | mediaPlayer.release(); 65 | mediaPlayer = null; 66 | } 67 | } 68 | 69 | //初始化MediaPlayer 70 | private static MediaPlayer getMediaPlayer(Context context){ 71 | MediaPlayer mediaplayer = new MediaPlayer(); 72 | if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.KITKAT) { 73 | return mediaplayer; 74 | } 75 | 76 | try { 77 | Class cMediaTimeProvider = Class.forName( "android.media.MediaTimeProvider" ); 78 | Class cSubtitleController = Class.forName( "android.media.SubtitleController" ); 79 | Class iSubtitleControllerAnchor = Class.forName( "android.media.SubtitleController$Anchor" ); 80 | Class iSubtitleControllerListener = Class.forName( "android.media.SubtitleController$Listener" ); 81 | 82 | Constructor constructor = cSubtitleController.getConstructor(new Class[]{Context.class, cMediaTimeProvider, iSubtitleControllerListener}); 83 | 84 | Object subtitleInstance = constructor.newInstance(context, null, null); 85 | 86 | Field f = cSubtitleController.getDeclaredField("mHandler"); 87 | 88 | f.setAccessible(true); 89 | try { 90 | f.set(subtitleInstance, new Handler()); 91 | } 92 | catch (IllegalAccessException e) {return mediaplayer;} 93 | finally { 94 | f.setAccessible(false); 95 | } 96 | Method setsubtitleanchor = mediaplayer.getClass().getMethod("setSubtitleAnchor", cSubtitleController, iSubtitleControllerAnchor); 97 | setsubtitleanchor.invoke(mediaplayer, subtitleInstance, null); 98 | } catch (Exception e) { 99 | e.printStackTrace(); 100 | } 101 | 102 | return mediaplayer; 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /app/src/main/java/com/clam314/lame/MediaRecorderButton.java: -------------------------------------------------------------------------------- 1 | package com.clam314.lame; 2 | 3 | import android.content.Context; 4 | import android.os.Environment; 5 | import android.os.Handler; 6 | import android.os.Looper; 7 | import android.os.Message; 8 | import android.util.AttributeSet; 9 | import android.view.MotionEvent; 10 | import android.widget.Button; 11 | 12 | import java.io.File; 13 | 14 | /** 15 | * Created by clam314 on 2016/7/21 16 | */ 17 | public class MediaRecorderButton extends Button implements MediaRecorderListener{ 18 | 19 | //用于标识按钮不同状态,显示不同的样式 20 | private static final int NORMAL_STATUS = 109; 21 | private static final int RECORDING_STATUS = 110; 22 | private static final int CANCEL_STATUS = 111; 23 | private static final int DISTANCE_Y_CANCEL = 50; 24 | 25 | //设置录音的最短时长,过短的录音当做取消 26 | private static final long timeDistance = 1000; 27 | 28 | //延迟开始录音的时间,防止连按,多次触发录音功能导致阻塞主线程 29 | private static final long DELAYED_TIME = 15*100; 30 | 31 | //用于标识录音的不同状态 32 | public static final int RECORDER_SUCCESS = 209; 33 | public static final int START_RECORDER = 200; 34 | public static final int END_RECORDER_60S = 260; 35 | public static final int END_RECORDER_TOO_SHORT = 270; 36 | public static final int END_RECORDER_CANCEL = 280; 37 | private static final int COUNT_STATUS = 180; 38 | 39 | 40 | private long startTime = 0; 41 | private long downTime = 0; 42 | private boolean cancelCount = false; 43 | private boolean wantCancel = false; 44 | private boolean recording = false; 45 | private boolean overMaxRecodeTime = false; 46 | private String bastPath; 47 | private RecorderStatusListener statusListener; 48 | private RecorderFinishListener finishListener; 49 | private int mSecond = 0; 50 | 51 | private Handler handler = new Handler(Looper.getMainLooper()){ 52 | static final int COUNT_TIME_END = 0; 53 | int count = 60;//限制录音的最大时长,单位秒 54 | @Override 55 | public void handleMessage(Message msg) { 56 | super.handleMessage(msg); 57 | switch (msg.what){ 58 | case COUNT_STATUS: 59 | if(cancelCount){ 60 | removeMessages(COUNT_STATUS); 61 | count = 60; 62 | if(statusListener != null) statusListener.onEnd(END_RECORDER_CANCEL); 63 | break; 64 | } 65 | count--; 66 | mSecond = 60 - count; 67 | if(statusListener != null) statusListener.onEnd(count); 68 | if (count == COUNT_TIME_END) { 69 | removeMessages(COUNT_STATUS); 70 | changeBackground(NORMAL_STATUS); 71 | overMaxRecodeTime = true; 72 | endRecorder(false); 73 | if(statusListener != null) statusListener.onEnd(END_RECORDER_60S); 74 | count = 60; 75 | return; 76 | } 77 | sendEmptyMessageDelayed(COUNT_STATUS, 1000); 78 | break; 79 | case START_RECORDER: 80 | startRecorder(bastPath); 81 | break; 82 | } 83 | } 84 | }; 85 | 86 | public MediaRecorderButton(Context context) { 87 | super(context); 88 | init(); 89 | } 90 | 91 | public MediaRecorderButton(Context context, AttributeSet attrs) { 92 | super(context, attrs); 93 | init(); 94 | } 95 | 96 | public MediaRecorderButton(Context context, AttributeSet attrs, int defStyle) { 97 | super(context, attrs, defStyle); 98 | init(); 99 | } 100 | 101 | private void init() { 102 | bastPath = getBasePath(); 103 | changeBackground(NORMAL_STATUS); 104 | } 105 | 106 | public String getBasePath() { 107 | String strPath = null; 108 | if (!android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) { 109 | strPath = getContext().getFilesDir() + "/" + "lameMp3"; 110 | } else{ 111 | strPath = Environment.getExternalStorageDirectory() + "/" + "lameMp3"; 112 | } 113 | File dir = new File(strPath); 114 | if(!dir.exists()){ 115 | dir.mkdirs(); 116 | } 117 | return strPath; 118 | } 119 | 120 | public void setBastPath(String bastPath){ 121 | this.bastPath = bastPath; 122 | } 123 | 124 | public void setFinishListener(RecorderFinishListener listener){ 125 | finishListener = listener; 126 | LameMp3Manager.instance.setMediaRecorderListener(this); 127 | } 128 | 129 | public void setRecorderStatusListener(RecorderStatusListener listener){ 130 | if(listener != null){ 131 | this.statusListener = listener; 132 | } 133 | } 134 | 135 | private void startRecorder(String basePath){ 136 | overMaxRecodeTime = false; 137 | mSecond = 0; 138 | LameMp3Manager.instance.startRecorder(basePath+File.separator+"lame.mp3"); 139 | startTime = System.currentTimeMillis(); 140 | recording = true; 141 | cancelCount = false; 142 | handler.sendEmptyMessage(COUNT_STATUS); 143 | if(statusListener != null) statusListener.onStart(START_RECORDER); 144 | } 145 | 146 | private void endRecorder(boolean wantCancel){ 147 | if(recording){ 148 | boolean tooShort = System.currentTimeMillis() - startTime < timeDistance; 149 | if(tooShort){ 150 | LameMp3Manager.instance.cancelRecorder(); 151 | if(statusListener != null) statusListener.onEnd(END_RECORDER_TOO_SHORT); 152 | }else if(wantCancel){ 153 | LameMp3Manager.instance.cancelRecorder(); 154 | this.cancelCount = true; 155 | this.wantCancel = false; 156 | }else { 157 | LameMp3Manager.instance.stopRecorder(); 158 | } 159 | recording = false; 160 | } 161 | } 162 | 163 | @Override 164 | public boolean onTouchEvent(MotionEvent event) { 165 | int x = (int) event.getX(); 166 | int y = (int) event.getY(); 167 | switch (event.getAction()){ 168 | case MotionEvent.ACTION_DOWN: 169 | downTime = System.currentTimeMillis(); 170 | changeBackground(RECORDING_STATUS); 171 | handler.removeMessages(START_RECORDER); 172 | handler.sendEmptyMessageDelayed(START_RECORDER, DELAYED_TIME); 173 | break; 174 | case MotionEvent.ACTION_MOVE: 175 | if(wantToCancel(x, y)){ 176 | changeBackground(CANCEL_STATUS); 177 | wantCancel = true; 178 | } 179 | break; 180 | case MotionEvent.ACTION_UP: 181 | case MotionEvent.ACTION_CANCEL: 182 | changeBackground(NORMAL_STATUS); 183 | if(System.currentTimeMillis() - downTime < DELAYED_TIME){ 184 | handler.removeMessages(START_RECORDER); 185 | } 186 | //录音时间没有超时才停止录音 187 | if(!overMaxRecodeTime){ 188 | endRecorder(wantCancel); 189 | cancelCount = true; 190 | } 191 | } 192 | return super.onTouchEvent(event); 193 | } 194 | 195 | private boolean wantToCancel(int x, int y) { 196 | return x < 0 || x > getWidth() || y < -DISTANCE_Y_CANCEL || y > getHeight() + DISTANCE_Y_CANCEL; 197 | } 198 | 199 | private void changeBackground(int status){ 200 | switch (status){ 201 | case NORMAL_STATUS: 202 | setBackgroundResource(R.drawable.button_recordnormal); 203 | setText("按下开始录音"); 204 | break; 205 | case RECORDING_STATUS: 206 | setBackgroundResource(R.drawable.button_recording); 207 | setText("松开 结束"); 208 | break; 209 | case CANCEL_STATUS: 210 | setBackgroundResource(R.drawable.button_recording); 211 | setText("取消"); 212 | break; 213 | } 214 | } 215 | 216 | @Override 217 | public void onRecorderFinish(int status, String path) { 218 | if(finishListener != null){ 219 | finishListener.onRecorderFinish(status,path, String.valueOf(mSecond)); 220 | } 221 | } 222 | 223 | public interface RecorderStatusListener{ 224 | public void onStart(int status); 225 | public void onEnd(int status); 226 | } 227 | 228 | public interface RecorderFinishListener { 229 | public void onRecorderFinish(int status, String filePath, String second); 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /app/src/main/java/com/clam314/lame/MediaRecorderListener.java: -------------------------------------------------------------------------------- 1 | package com.clam314.lame; 2 | 3 | /** 4 | * Created by clam314 on 2016/7/21 5 | */ 6 | public interface MediaRecorderListener { 7 | 8 | public void onRecorderFinish(int status, String path); 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/clam314/lame/Mp3Recorder.java: -------------------------------------------------------------------------------- 1 | package com.clam314.lame; 2 | 3 | 4 | import java.io.File; 5 | import java.io.FileOutputStream; 6 | import java.io.IOException; 7 | import java.util.concurrent.ExecutorService; 8 | import java.util.concurrent.Executors; 9 | 10 | import android.media.AudioFormat; 11 | import android.media.AudioRecord; 12 | import android.media.MediaRecorder; 13 | import android.os.Message; 14 | import android.util.Log; 15 | 16 | /** 17 | * Created by clam314 on 2017/3/26. 18 | * 19 | * 负责录音的类 20 | */ 21 | 22 | 23 | public class Mp3Recorder { 24 | 25 | private static final String TAG = Mp3Recorder.class.getSimpleName(); 26 | 27 | static { 28 | System.loadLibrary("lamemp3"); 29 | } 30 | 31 | //默认采样率 32 | private static final int DEFAULT_SAMPLING_RATE = 44100; 33 | 34 | //转换周期,录音每满160帧,进行一次转换 35 | private static final int FRAME_COUNT = 160; 36 | 37 | //输出MP3的码率 38 | private static final int BIT_RATE = 32; 39 | 40 | //根据资料假定的最大值。 实测时有时超过此值。 41 | private static final int MAX_VOLUME = 2000; 42 | 43 | private AudioRecord audioRecord = null; 44 | 45 | private int bufferSize; 46 | 47 | private File mp3File; 48 | 49 | private int mVolume; 50 | 51 | private short[] mPCMBuffer; 52 | 53 | private FileOutputStream os = null; 54 | 55 | private DataEncodeThread encodeThread; 56 | 57 | private int samplingRate; 58 | 59 | private int channelConfig; 60 | 61 | private PCMFormat audioFormat; 62 | 63 | private boolean isRecording = false; 64 | 65 | private ExecutorService executor = Executors.newFixedThreadPool(1); 66 | 67 | private OnFinishListener finishListener; 68 | 69 | public interface OnFinishListener { 70 | void onFinish(String mp3SavePath); 71 | } 72 | 73 | public Mp3Recorder(int samplingRate, int channelConfig, PCMFormat audioFormat) { 74 | this.samplingRate = samplingRate; 75 | this.channelConfig = channelConfig; 76 | this.audioFormat = audioFormat; 77 | } 78 | 79 | /** 80 | * Default constructor. Setup recorder with default sampling rate 1 channel, 81 | * 16 bits pcm 82 | */ 83 | public Mp3Recorder() { 84 | this(DEFAULT_SAMPLING_RATE, AudioFormat.CHANNEL_IN_MONO, PCMFormat.PCM_16BIT); 85 | } 86 | 87 | 88 | public void startRecording(File mp3Save) throws IOException { 89 | if (isRecording) return; 90 | Log.d(TAG, "Start recording"); 91 | Log.d(TAG, "BufferSize = " + bufferSize); 92 | 93 | this.mp3File = mp3Save; 94 | if (audioRecord == null) { 95 | initAudioRecorder(); 96 | } 97 | audioRecord.startRecording(); 98 | 99 | Runnable runnable = new Runnable() { 100 | @Override 101 | public void run() { 102 | isRecording = true; 103 | //循环的从AudioRecord获取录音的PCM数据 104 | while (isRecording) { 105 | int readSize = audioRecord.read(mPCMBuffer, 0, bufferSize); 106 | if (readSize > 0) { 107 | //待转换的PCM数据放到转换线程中 108 | encodeThread.addChangeBuffer(mPCMBuffer,readSize); 109 | calculateRealVolume(mPCMBuffer, readSize); 110 | } 111 | } 112 | 113 | // 录音完毕,释放AudioRecord的资源 114 | try { 115 | audioRecord.stop(); 116 | audioRecord.release(); 117 | audioRecord = null; 118 | 119 | // 录音完毕,通知转换线程停止,并等待直到其转换完毕 120 | Message msg = Message.obtain(encodeThread.getHandler(), DataEncodeThread.PROCESS_STOP); 121 | msg.sendToTarget(); 122 | 123 | Log.d(TAG, "waiting for encoding thread"); 124 | encodeThread.join(); 125 | Log.d(TAG, "done encoding thread"); 126 | //转换完毕后回调监听 127 | if(finishListener != null) finishListener.onFinish(mp3File.getPath()); 128 | } catch (InterruptedException e) { 129 | e.printStackTrace(); 130 | } finally { 131 | if (os != null) { 132 | try { 133 | os.close(); 134 | } catch (IOException e) { 135 | e.printStackTrace(); 136 | } 137 | } 138 | } 139 | 140 | } 141 | }; 142 | executor.execute(runnable); 143 | } 144 | 145 | 146 | public void stopRecording() throws IOException { 147 | Log.d(TAG, "stop recording"); 148 | isRecording = false; 149 | } 150 | 151 | //计算音量大小 152 | private void calculateRealVolume(short[] buffer, int readSize) { 153 | double sum = 0; 154 | for (int i = 0; i < readSize; i++) { 155 | sum += buffer[i] * buffer[i]; 156 | } 157 | if (readSize > 0) { 158 | double amplitude = sum / readSize; 159 | mVolume = (int) Math.sqrt(amplitude); 160 | } 161 | } 162 | 163 | public int getVolume(){ 164 | if (mVolume >= MAX_VOLUME) { 165 | return MAX_VOLUME; 166 | } 167 | return mVolume; 168 | } 169 | 170 | public int getMaxVolume(){ 171 | return MAX_VOLUME; 172 | } 173 | 174 | 175 | public void setFinishListener(OnFinishListener listener){ 176 | this.finishListener = listener; 177 | } 178 | 179 | private void initAudioRecorder() throws IOException { 180 | int bytesPerFrame = audioFormat.getBytesPerFrame(); 181 | /* Get number of samples. Calculate the mPCMBuffer size (round up to the factor of given frame size) */ 182 | int frameSize = AudioRecord.getMinBufferSize(samplingRate, channelConfig, audioFormat.getAudioFormat()) / bytesPerFrame; 183 | if (frameSize % FRAME_COUNT != 0) { 184 | frameSize = frameSize + (FRAME_COUNT - frameSize % FRAME_COUNT); 185 | Log.d(TAG, "Frame size: " + frameSize); 186 | } 187 | bufferSize = frameSize * bytesPerFrame; 188 | 189 | audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, samplingRate, channelConfig, audioFormat.getAudioFormat(), bufferSize); 190 | 191 | mPCMBuffer = new short[bufferSize]; 192 | 193 | 194 | SimpleLame.init(samplingRate, 1, samplingRate, BIT_RATE); 195 | 196 | os = new FileOutputStream(mp3File); 197 | 198 | // Create and run thread used to encode data 199 | encodeThread = new DataEncodeThread(os, bufferSize); 200 | encodeThread.start(); 201 | //给AudioRecord设置刷新监听,待录音帧数每次达到FRAME_COUNT,就通知转换线程转换一次数据 202 | audioRecord.setRecordPositionUpdateListener(encodeThread, encodeThread.getHandler()); 203 | audioRecord.setPositionNotificationPeriod(FRAME_COUNT); 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /app/src/main/java/com/clam314/lame/PCMFormat.java: -------------------------------------------------------------------------------- 1 | package com.clam314.lame; 2 | import android.media.AudioFormat; 3 | 4 | /** 5 | * Created by clam314 on 2017/3/26. 6 | */ 7 | 8 | 9 | public enum PCMFormat { 10 | PCM_8BIT (1, AudioFormat.ENCODING_PCM_8BIT), 11 | PCM_16BIT (2, AudioFormat.ENCODING_PCM_16BIT); 12 | 13 | private int bytesPerFrame; 14 | private int audioFormat; 15 | 16 | PCMFormat(int bytesPerFrame, int audioFormat) { 17 | this.bytesPerFrame = bytesPerFrame; 18 | this.audioFormat = audioFormat; 19 | } 20 | 21 | public int getBytesPerFrame() { 22 | return bytesPerFrame; 23 | } 24 | 25 | public void setBytesPerFrame(int bytesPerFrame) { 26 | this.bytesPerFrame = bytesPerFrame; 27 | } 28 | 29 | public int getAudioFormat() { 30 | return audioFormat; 31 | } 32 | 33 | public void setAudioFormat(int audioFormat) { 34 | this.audioFormat = audioFormat; 35 | } 36 | } -------------------------------------------------------------------------------- /app/src/main/java/com/clam314/lame/SimpleLame.java: -------------------------------------------------------------------------------- 1 | package com.clam314.lame; 2 | 3 | /** 4 | * Created by clam314 on 2017/3/26 5 | */ 6 | 7 | public class SimpleLame { 8 | 9 | public native static void close(); 10 | 11 | public native static int encode(short[] buffer_l, short[] buffer_r, int samples, byte[] mp3buf); 12 | 13 | public native static int flush(byte[] mp3buf); 14 | 15 | public native static void init(int inSampleRate, int outChannel, int outSampleRate, int outBitrate, int quality); 16 | 17 | public static void init(int inSampleRate, int outChannel, int outSampleRate, int outBitrate) { 18 | init(inSampleRate, outChannel, outSampleRate, outBitrate, 7); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/anim_voice_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/button_recording.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/button_recordnormal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/voice_left_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clam314/LameMp3ForAndroid/1f69761a7ec3c91dedda3afe55ef8a111638ad50/app/src/main/res/drawable/voice_left_1.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/voice_left_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clam314/LameMp3ForAndroid/1f69761a7ec3c91dedda3afe55ef8a111638ad50/app/src/main/res/drawable/voice_left_2.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/voice_left_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clam314/LameMp3ForAndroid/1f69761a7ec3c91dedda3afe55ef8a111638ad50/app/src/main/res/drawable/voice_left_3.png -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 21 | 22 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clam314/LameMp3ForAndroid/1f69761a7ec3c91dedda3afe55ef8a111638ad50/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clam314/LameMp3ForAndroid/1f69761a7ec3c91dedda3afe55ef8a111638ad50/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clam314/LameMp3ForAndroid/1f69761a7ec3c91dedda3afe55ef8a111638ad50/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clam314/LameMp3ForAndroid/1f69761a7ec3c91dedda3afe55ef8a111638ad50/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clam314/LameMp3ForAndroid/1f69761a7ec3c91dedda3afe55ef8a111638ad50/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 64dp 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Lame 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/test/java/com/clam314/lame/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.clam314.lame; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:2.2.3' 9 | 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | jcenter() 18 | } 19 | } 20 | 21 | task clean(type: Delete) { 22 | delete rootProject.buildDir 23 | } 24 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/clam314/LameMp3ForAndroid/1f69761a7ec3c91dedda3afe55ef8a111638ad50/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Dec 28 10:00:20 PST 2015 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | --------------------------------------------------------------------------------