作者 王睿

合并分支 'develop' 到 'master'

第一次提交



查看合并请求 !1
正在显示 41 个修改的文件 包含 4838 行增加0 行删除

要显示太多修改。

为保证性能只显示 41 of 41+ 个文件。

*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
... ...
zhongqiyan
\ No newline at end of file
... ...
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JetCodeStyleSettings>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<MarkdownNavigatorCodeStyleSettings>
<option name="RIGHT_MARGIN" value="72" />
</MarkdownNavigatorCodeStyleSettings>
<codeStyleSettings language="XML">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4" />
</indentOptions>
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</codeStyleSettings>
</code_scheme>
</component>
\ No newline at end of file
... ...
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="delegatedBuild" value="true" />
<option name="testRunner" value="PLATFORM" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>
\ No newline at end of file
... ...
<component name="MarkdownNavigator.ProfileManager">
<settings default="" pdf-export="" />
</component>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
\ No newline at end of file
... ...
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>
\ No newline at end of file
... ...
/build
... ...
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 28
buildToolsVersion "28.0.3"
defaultConfig {
applicationId "com.example.zhongqiyan"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:support-v4:28.0.0'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'org.greenrobot:eventbus:3.1.1'
// retrofit
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
//rxjava rxandroid
implementation 'io.reactivex.rxjava2:rxjava:2.2.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'io.reactivex:rxandroid:1.2.1'
//配合Rxjava 使用
implementation 'com.squareup.okhttp3:logging-interceptor:3.8.1'
implementation 'com.squareup.okhttp3:okhttp:3.2.0'
implementation 'com.squareup.okio:okio:1.7.0'
// // butterknife 注解框架
// butterknife 注解框架
implementation 'com.jakewharton:butterknife:8.1.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.1.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
// Gson
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.jakewharton:butterknife:8.1.0'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}
... ...
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
... ...
package com.example.zhongqiyan
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.example.zhongqiyan", appContext.packageName)
}
}
... ...
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.zhongqiyan">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.WRITE_SETTINGS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission
android:name="android.permission.INSTALL_PACKAGES"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission
android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
tools:ignore="ProtectedPermissions" /> <!-- 录音 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" /> <!-- 播音 -->
<uses-permission android:name="android.permission.WAKE_LOCK" /> <!-- 极光 -->
<!-- 获取手机信息 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" /> <!-- 2017.5.27 极光推送权限 ym start -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".login.LoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize|stateHidden" />
<activity
android:name=".login.ForgotPasswordActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize|stateHidden" />
<activity
android:name=".login.ResetPasswordActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize|stateHidden" />
<activity
android:name=".login.RegisterdActivity"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustResize|stateHidden" />
</application>
</manifest>
\ No newline at end of file
... ...
package com.example.zhongqiyan;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import com.example.zhongqiyan.javasource.ca.uol.aig.fftpack.RealDoubleFFT;
public class AudioProcessing extends Activity implements View.OnClickListener {
int frequency = 8000;
int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
private RealDoubleFFT transformer;
int blockSize = 256;
Button startStopButton;
boolean started = false;
RecordAudio recordTask;
ImageView imageView;
Bitmap bitmap;
Canvas canvas;
Paint paint;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startStopButton = (Button) this.findViewById(R.id.StartStopButton);
startStopButton.setOnClickListener(this);
transformer = new RealDoubleFFT(blockSize);
imageView = (ImageView) this.findViewById(R.id.ImageView01);
bitmap = Bitmap.createBitmap((int)256,(int)100,Bitmap.Config.ARGB_8888);
canvas = new Canvas(bitmap);
paint = new Paint();
paint.setColor(Color.GREEN);
imageView.setImageBitmap(bitmap);
}
private class RecordAudio extends AsyncTask<Void, double[], Void> {
@Override
protected Void doInBackground(Void... params) {
try {
int bufferSize = AudioRecord.getMinBufferSize(frequency,
channelConfiguration, audioEncoding);
AudioRecord audioRecord = new AudioRecord(
MediaRecorder.AudioSource.DEFAULT, frequency,
channelConfiguration, audioEncoding, bufferSize);
short[] buffer = new short[blockSize];
double[] toTransform = new double[blockSize];
audioRecord.startRecording();
while (started) {
int bufferReadResult = audioRecord.read(buffer, 0, blockSize);
for (int i = 0; i < blockSize && i < bufferReadResult; i++) {
toTransform[i] = (double) buffer[i] / 32768.0; // signed 16 bit
}
transformer.ft(toTransform);
publishProgress(toTransform);
}
audioRecord.stop();
} catch (Throwable t) {
Log.e("AudioRecord", "Recording Failed");
}
return null;
}
}
protected void onProgressUpdate(double[]... toTransform) {
canvas.drawColor(Color.BLACK);
for (int i = 0; i < toTransform[0].length; i++) {
int x = i;
int downy = (int) (100 - (toTransform[0][i] * 10));
int upy = 100;
canvas.drawLine(x, downy, x, upy, paint);
}
imageView.invalidate();
}
public void onClick(View v) {
if (started) {
started = false;
startStopButton.setText("Start");
recordTask.cancel(true);
} else {
started = true;
startStopButton.setText("Stop");
recordTask = new RecordAudio();
recordTask.execute();
}
}
}
... ...
package com.example.zhongqiyan;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import com.example.zhongqiyan.javasource.ca.uol.aig.fftpack.RealDoubleFFT;
/**
* 可视化频率
*
* @time 下午12:00:21
* @author retacn yue
* @Email zhenhuayue@sina.com
*/
public class AudioProcessingActivity extends Activity implements View.OnClickListener {
private Button btn_start_stop;
private ImageView img_frequency;
private Bitmap bitmap;
private Canvas canvas;
private Paint paint;
private AudioRecordTask recordTask;
private RealDoubleFFT trasformer;
int blockSize = 256;
int frequency = 8000;
int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
boolean started = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.audio_processing);
findView();
trasformer = new RealDoubleFFT(blockSize);
bitmap = Bitmap.createBitmap(256, 100, Bitmap.Config.ARGB_8888);
canvas = new Canvas(bitmap);
paint = new Paint();
paint.setColor(Color.RED);
img_frequency.setImageBitmap(bitmap);
}
@Override
public void onClick(View v) {
if (started) {
started = false;
btn_start_stop.setText("Start");
} else {
started = true;
btn_start_stop.setText("Stop");
recordTask = new AudioRecordTask();
recordTask.execute();
}
}
/**
* 实例化控件
*/
private void findView() {
btn_start_stop = (Button) this.findViewById(R.id.StartStopButton);
btn_start_stop.setOnClickListener(this);
img_frequency = (ImageView) this.findViewById(R.id.ImageView01);
}
/*****************************************************************/
private static int[] mSampleRates = new int[] { 8000, 11025, 22050, 44100 };
public AudioRecord findAudioRecord() {
for (int rate : mSampleRates) {
for (short audioFormat : new short[] { AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT }) {
for (short channelConfig : new short[] { AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.CHANNEL_CONFIGURATION_STEREO }) {
try {
Log.d("tag", "Attempting rate " + rate + "Hz, bits: " + audioFormat + ", channel: " + channelConfig);
int bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat);
if (bufferSize != AudioRecord.ERROR_BAD_VALUE) {
Log.e("tag", "++++++++");
AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, rate, channelConfig, audioFormat, bufferSize);
if (recorder.getState() == AudioRecord.STATE_INITIALIZED)
Log.e("tag", "-----");
return recorder;
}
} catch (Exception e) {
Log.e("tag", rate + "Exception, keep trying.", e);
}
}
}
}
Log.e("tag", "===========");
return null;
}
/**
* 音频合成任务
*/
private class AudioRecordTask extends AsyncTask<Void, double[], Void> {
@Override
protected Void doInBackground(Void... params) {
try {
int bufferSize = AudioRecord.getMinBufferSize(frequency, //
channelConfiguration, //
audioEncoding);
AudioRecord audioRecord = findAudioRecord();
/*****************************************************************/
/*
* AudioRecord audioRecord = new
* AudioRecord(MediaRecorder.AudioSource.MIC,// 输入源 frequency,//
* channelConfiguration,// audioEncoding,// bufferSize);
*/
short[] buffer = new short[blockSize];
double[] toTransform = new double[blockSize];
audioRecord.startRecording();
while (started) {
int bufferReadResult = audioRecord.read(buffer, 0, blockSize);
for (int i = 0; i < blockSize && i < bufferReadResult; i++) {
toTransform[i] = (double) buffer[i] / 32768.0;
}
// TODO
DebugLog.e("toTransform==="+toTransform);
trasformer.ft(toTransform);
publishProgress(toTransform);
}
audioRecord.stop();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
}
return null;
}
protected void onProgressUpdate(double[]... toTransform) {
canvas.drawColor(Color.BLACK);
for (int i = 0; i < toTransform[0].length; i++) {
int x = i;
int downy = (int) (100 - (toTransform[0][i] * 10));
int upy = 100;
canvas.drawLine(x, downy, x, upy, paint);
}
img_frequency.invalidate();
}
}
}
... ...
package com.example.zhongqiyan;
import android.os.Looper;
import android.util.Log;
import androidx.annotation.IntRange;
/**
* 日志打印工具
*
* @author wr
*/
public class DebugLog {
/**
* 控制是否打印日志
**/
public static boolean isDebug = true;
/**
* 类名
**/
private static String className;
/**
* 方法名
**/
private static String methodName;
private DebugLog() {
/* Protect from instantiations */
}
private static String createLog(String log) {
StringBuffer buffer = new StringBuffer();
buffer.append("[");
buffer.append(methodName);
buffer.append("]");
buffer.append(log);
return buffer.toString();
}
private static void getMethodNames(StackTraceElement[] sElements) {
className = sElements[1].getFileName();
methodName = sElements[1].getMethodName();
}
public static void e(String message) {
if (!isDebug)
return;
e(message, 3);
}
public static void e(String message, int stackLevel) {
if (!isDebug)
return;
printCallStatck(4, stackLevel);
getMethodNames(new Throwable().getStackTrace());
Log.e(className, createLog(message));
}
public static void i(String message) {
if (!isDebug)
return;
printCallStatck(2);
getMethodNames(new Throwable().getStackTrace());
Log.i(className, createLog(message));
}
public static void d(String message) {
if (!isDebug)
return;
printCallStatck(1);
getMethodNames(new Throwable().getStackTrace());
Log.d(className, createLog(message));
}
public static void v(String message) {
if (!isDebug)
return;
printCallStatck(0);
getMethodNames(new Throwable().getStackTrace());
Log.v(className, createLog(message));
}
public static void w(String message) {
if (!isDebug)
return;
printCallStatck(3);
getMethodNames(new Throwable().getStackTrace());
Log.w(className, createLog(message));
}
public static void wtf(String message) {
if (!isDebug)
return;
printCallStatck(5);
getMethodNames(new Throwable().getStackTrace());
Log.wtf(className, createLog(message));
}
/**
* 打印堆栈信息
*/
public static void printCallStatck(@IntRange(from = 0, to = 6) int level) {
// if (true) {
// return;
// }
printCallStatck(level, 2);
}
/**
* 打印堆栈信息
*/
public static void printCallStatck(@IntRange(from = 0, to = 6) int level, int stackLeve) {
// if (true) {
// return;
// }
printInfo("----", " ", level);
printThreadInfo(level);
Throwable ex = new Throwable();
StringBuffer sb = new StringBuffer();
StackTraceElement[] stackElements = ex.getStackTrace();
if (stackElements == null || stackElements.length <= stackLeve) {
return;
}
sb.append("at " + stackElements[stackLeve].getClassName() + ".");
sb.append(stackElements[stackLeve].getMethodName());
sb.append("(" +
stackElements[stackLeve].getFileName() +
":"
+ stackElements[stackLeve].getLineNumber() +
")");
sb.append("\n");
printInfo("CallStatckInfo", sb.toString(), level);
}
/**
* 打印线程信息
*
* @param level
*/
private static void printThreadInfo(@IntRange(from = 0, to = 6) int level) {
if (Looper.myLooper() == Looper.getMainLooper()) {
printInfo("ThreadInfo ", "MainThread", level);
} else {
printInfo("ThreadInfo ", "ThreadGroup:" + Thread.currentThread().getThreadGroup()
+ "ThreadName:" + Thread.currentThread().getName()
+ "ThreadID:" + Thread.currentThread().getId(), level);
}
}
/**
* 根据级别打印信息
*
* @param tag
* @param msg
* @param level
*/
private static void printInfo(String tag, String msg, @IntRange(from = 0, to = 6) int level) {
switch (level) {
case 0:
Log.v(tag, msg);
break;
case 1:
Log.d(tag, msg);
break;
case 2:
Log.i(tag, msg);
break;
case 3:
Log.w(tag, msg);
break;
case 4:
Log.e(tag, msg);
break;
case 5:
Log.wtf(tag, msg);
break;
}
}
// public static void eLogHttpRequest(OkHttpRequest okHttpRequest, String response) {
// StringBuilder sb = new StringBuilder();
// sb.append("url:" + okHttpRequest.getUrl() + "\n");
// if (okHttpRequest.getTag() != null) {
// sb.append("tag:" + okHttpRequest.getTag().toString() + "\n");
// }
// Map<String, String> params = okHttpRequest.getParams();
// if (params != null) {
// sb.append("params:\n");
// for (String key : params.keySet()) {
// sb.append(key + ":" + params.get(key) + "\n");
// }
// }
// sb.append("response:" + response);
// e(sb.toString(), 3);
// }
}
... ...
package com.example.zhongqiyan;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import com.example.zhongqiyan.javasource.ca.uol.aig.fftpack.RealDoubleFFT;
public class MainActivity extends Activity implements View.OnClickListener {
//采样率:音频的采样频率,每秒钟能够采样的次数,采样率越高,音质越高。给出的实例是44100、22050、11025但不限于这几个参数。例如要采集低质量的音频就可以使用4000、8000等低采样率。
int frequency = 8000;
//声道设置:android支持双声道立体声和单声道。MONO单声道,STEREO立体声
int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;
private RealDoubleFFT transformer;
int blockSize = 256;
Button startStopButton;
boolean started = false;
RecordAudio recordTask;
ImageView imageView;
Bitmap bitmap;
Canvas canvas;
Paint paint;
//AudioRecord audioRecord;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startStopButton = (Button) this.findViewById(R.id.StartStopButton);
startStopButton.setOnClickListener(this);
transformer = new RealDoubleFFT(blockSize);
imageView = (ImageView) this.findViewById(R.id.ImageView01);
bitmap = Bitmap.createBitmap((int) 256, (int) 100,
Bitmap.Config.ARGB_8888);
canvas = new Canvas(bitmap);
paint = new Paint();
paint.setColor(Color.GREEN);
imageView.setImageBitmap(bitmap);
}
public class RecordAudio extends AsyncTask<Void, double[], Void> {
@Override
protected Void doInBackground(Void... arg0) {
try {
// int bufferSize = AudioRecord.getMinBufferSize(frequency,
// AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
int bufferSize = AudioRecord.getMinBufferSize(frequency,
channelConfiguration, audioEncoding);
//audioSource:
//音频源:指的是从哪里采集音频。这里我们当然是从麦克风采集音频,所以此参数的值为MIC
//sampleRateInHz:
//采样率:音频的采样频率,每秒钟能够采样的次数,采样率越高,音质越高。给出的实例是44100、22050、11025但不限于这几个参数。例如要采集低质量的音频就可以使用4000、8000等低采样率。
//channelConfig:
//声道设置:android支持双声道立体声和单声道。MONO单声道,STEREO立体声
//audioFormat:
//编码制式和采样大小:采集来的数据当然使用PCM编码(脉冲代码调制编码,即PCM编码。PCM通过抽样、量化、编码三个步骤将连续变化的模拟信号转换为数字编码。)
//android支持的采样大小16bit 或者8bit。当然采样大小越大,那么信息量越多,音质也越高,现在主流的采样大小都是16bit,在低质量的语音传输的时候8bit足够了。
//bufferSizeInBytes:
//采集数据需要的缓冲区的大小,如果不知道最小需要的大小可以在getMinBufferSize()查看。
AudioRecord audioRecord = new AudioRecord(
MediaRecorder.AudioSource.MIC, frequency,
channelConfiguration, audioEncoding, bufferSize);
short[] buffer = new short[blockSize];
double[] toTransform = new double[blockSize];
DebugLog.e("buffer==="+buffer.toString());
audioRecord.startRecording();
// started = true; hopes this should true before calling
// following while loop
while (started) {
int bufferReadResult = audioRecord.read(buffer, 0,
blockSize);
for (int i = 0; i < blockSize && i < bufferReadResult; i++) {
toTransform[i] = (double) buffer[i] / 32768.0; // signed
// 16
}
DebugLog.e("2buffer==="+toTransform.toString());// bit
transformer.ft(toTransform);
publishProgress(toTransform);
}
audioRecord.stop();
} catch (Throwable t) {
t.printStackTrace();
Log.e("AudioRecord", "Recording Failed");
}
return null;
}
@Override
protected void onProgressUpdate(double[]... toTransform) {
canvas.drawColor(Color.BLACK);
for (int i = 0; i < toTransform[0].length; i++) {
int x = i;
int downy = (int) (100 - (toTransform[0][i] * 10));
int upy = 100;
canvas.drawLine(x, downy, x, upy, paint);
}
imageView.invalidate();
// TODO Auto-generated method stub
// super.onProgressUpdate(values);
}
}
// @Override
// public boolean onCreateOptionsMenu(Menu menu) {
// getMenuInflater().inflate(R.menu.activity_main, menu);
// return true;
// }
public void onClick(View arg0) {
// TODO Auto-generated method stub
if (started) {
started = false;
startStopButton.setText("Start");
recordTask.cancel(true);
} else {
started = true;
startStopButton.setText("Stop");
recordTask = new RecordAudio();
recordTask.execute();
}
}
}
... ...
package com.example.zhongqiyan;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.zhongqiyan.javasource.ca.uol.aig.fftpack.RealDoubleFFT;
public class MainActivity2 extends Activity implements View.OnClickListener {
int audioSource = MediaRecorder.AudioSource.MIC; // Audio source is the device MIC
int channelConfig = AudioFormat.CHANNEL_IN_MONO; // Recording in mono
int audioEncoding = AudioFormat.ENCODING_PCM_16BIT; // Records in 16bit
// private DoubleFFT_1D fft; // The fft double array
private RealDoubleFFT transformer;
int blockSize = 256; // deal with this many samples at a time
int sampleRate = 8000; // Sample rate in Hz
public double frequency = 0.0; // the frequency given
RecordAudio recordTask; // Creates a Record Audio command
TextView tv; // Creates a text view for the frequency
boolean started = false;
Button startStopButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView)findViewById(R.id.textView1);
startStopButton= (Button)findViewById(R.id.StartStopButton);
}
// @Override
// public boolean onCreateOptionsMenu(Menu menu) {
// // Inflate the menu; this adds items to the action bar if it is present.
// getMenuInflater().inflate(R.menu.main, menu);
// return true;
// }
private class RecordAudio extends AsyncTask<Void, Double, Void>{
@SuppressLint("WrongThread")
@Override
protected Void doInBackground(Void... params){
/*Calculates the fft and frequency of the input*/
//try{
int bufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioEncoding); // Gets the minimum buffer needed
AudioRecord audioRecord = new AudioRecord(audioSource, sampleRate, channelConfig, audioEncoding, bufferSize); // The RAW PCM sample recording
short[] buffer = new short[blockSize]; // Save the raw PCM samples as short bytes
// double[] audioDataDoubles = new double[(blockSize*2)]; // Same values as above, as doubles
// -----------------------------------------------
double[] re = new double[blockSize];
double[] im = new double[blockSize];
double[] magnitude = new double[blockSize];
// ----------------------------------------------------
double[] toTransform = new double[blockSize];
tv.setText("Hello");
// fft = new DoubleFFT_1D(blockSize);
try{
audioRecord.startRecording(); //Start
}catch(Throwable t){
Log.e("AudioRecord", "Recording Failed");
}
while(started){
/* Reads the data from the microphone. it takes in data
* to the size of the window "blockSize". The data is then
* given in to audioRecord. The int returned is the number
* of bytes that were read*/
int bufferReadResult = audioRecord.read(buffer, 0, blockSize);
// Read in the data from the mic to the array
for(int i = 0; i < blockSize && i < bufferReadResult; i++) {
/* dividing the short by 32768.0 gives us the
* result in a range -1.0 to 1.0.
* Data for the compextForward is given back
* as two numbers in sequence. Therefore audioDataDoubles
* needs to be twice as large*/
// audioDataDoubles[2*i] = (double) buffer[i]/32768.0; // signed 16 bit
//audioDataDoubles[(2*i)+1] = 0.0;
toTransform[i] = (double) buffer[i] / 32768.0; // signed 16 bit
}
//audiodataDoubles now holds data to work with
// fft.complexForward(audioDataDoubles);
transformer.ft(toTransform);
//------------------------------------------------------------------------------------------
// Calculate the Real and imaginary and Magnitude.
for(int i = 0; i < blockSize; i++){
// real is stored in first part of array
re[i] = toTransform[i*2];
// imaginary is stored in the sequential part
im[i] = toTransform[(i*2)+1];
// magnitude is calculated by the square root of (imaginary^2 + real^2)
magnitude[i] = Math.sqrt((re[i] * re[i]) + (im[i]*im[i]));
}
double peak = -1.0;
// Get the largest magnitude peak
for(int i = 0; i < blockSize; i++){
if(peak < magnitude[i])
peak = magnitude[i];
}
// calculated the frequency
frequency = (sampleRate * peak)/blockSize;
//----------------------------------------------------------------------------------------------
/* calls onProgressUpdate
* publishes the frequency
*/
publishProgress(frequency);
try{
audioRecord.stop();
}
catch(IllegalStateException e){
Log.e("Stop failed", e.toString());
}
}
// }
return null;
}
protected void onProgressUpdate(Double... frequencies){
//print the frequency
String info = Double.toString(frequencies[0]);
tv.setText(info);
}
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(started){
started = false;
startStopButton.setText("Start");
recordTask.cancel(true);
} else {
started = true;
startStopButton.setText("Stop");
recordTask = new RecordAudio();
recordTask.execute();
}
}
}
... ...
package com.example.zhongqiyan.base;
/**
* Activity管理类
* Created by 18514 on 2019/1/5.
*/
import android.app.Activity;
import java.util.Stack;
/**
* Activity管理类
*/
public class ActivityStackManager {
private static Stack<Activity> activityStack;
private static ActivityStackManager instance;
private ActivityStackManager() {
}
public synchronized static ActivityStackManager getActivityStackManager() {
if (instance == null) {
instance = new ActivityStackManager();
}
return instance;
}
/**
* 关闭activity
* finish the activity and remove it from stack.
*
* @param activity
*/
public void popActivity(Activity activity) {
if (activityStack == null) {
return;
}
if (activity != null) {
activity.finish();
activity.overridePendingTransition(0, 0);
activityStack.remove(activity);
activity = null;
}
}
/**
* 获取当前的Activity
* get the current activity.
*
* @return
*/
public Activity currentActivity() {
if (activityStack == null || activityStack.isEmpty()) {
return null;
}
Activity activity = (Activity) activityStack.lastElement();
return activity;
}
/**
* 获取最后一个的Activity
* get the first activity in the stack.
*
* @return
*/
public Activity firstActivity() {
if (activityStack == null || activityStack.isEmpty()) {
return null;
}
Activity activity = (Activity) activityStack.firstElement();
return activity;
}
/**
* 添加activity到Stack
* add the activity to the stack.
*
* @param activity
*/
public void pushActivity(Activity activity) {
if (activityStack == null) {
activityStack = new Stack<Activity>();
}
activityStack.add(activity);
}
/**
* remove所有Activity
* remove all activity.
*/
public void popAllActivity() {
if (activityStack == null) {
return;
}
while (true) {
if (activityStack.empty()) {
break;
}
Activity activity = currentActivity();
popActivity(activity);
}
}
/**
* remove所有Activity但保持目前的Activity
* remove all activity but keep the current activity.
*/
public void popAllActivityWithOutCurrent() {
Activity activity = currentActivity();
while (true) {
if (activityStack.size() == 1) {
break;
}
if (firstActivity() == activity) {
break;
} else {
popActivity(firstActivity());
}
}
}
}
... ...
package com.example.zhongqiyan.base;
import android.app.Activity;
import java.util.Stack;
/**
* activity 堆栈工具
*
* @packageName: cn.white.ymc.wanandroidmaster.util
* @fileName: AppDavikActivityUtil
* @date: 2018/7/19 15:47
* @author: ymc
* @QQ:745612618
*/
public class AppDavikActivityUtil {
/**
* 存储ActivityStack
*/
private static Stack<Activity> activityStack = new Stack<>();
/**
* 单例模式
*/
private static AppDavikActivityUtil instance;
/**
* 单列堆栈集合对象
* @return AppDavikActivityMgr 单利堆栈集合对象
*/
public static AppDavikActivityUtil getScreenManager() {
if (instance == null) {
synchronized (AppDavikActivityUtil.class){
if (instance == null) {
instance = new AppDavikActivityUtil();
}
}
}
return instance;
}
/**
* 堆栈中销毁并移除
* @param activity 指定Act对象
*/
public void removeActivity(Activity activity) {
if (null != activity) {
activityStack.remove(activity);
activity.finish();
activity = null;
}
}
/**
* 栈中销毁并移除所有Act对象
*/
public void removeAllActivity() {
if (null != activityStack && activityStack.size() > 0) {
//创建临时集合对象
Stack<Activity> activityTemp = new Stack<Activity>();
for (Activity activity : activityStack) {
if (null != activity) {
//添加到临时集合中
activityTemp.add(activity);
//结束Activity
activity.finish();
}
}
activityStack.removeAll(activityTemp);
}
System.gc();
System.exit(0);
}
/**
* 获取当前Act对象
* @return Activity 当前act
*/
public Activity currentActivity() {
Activity activity = null;
if (!activityStack.empty()){
activity = activityStack.lastElement();
}
return activity;
}
/**
* 获得当前Act的类名
* @return String
*/
public String getCurrentActivityName() {
String actSimpleName = "";
if (!activityStack.empty()) {
actSimpleName = activityStack.lastElement().getClass().getSimpleName();
}
return actSimpleName;
}
/**
* 将Act纳入推栈集合中
* @param activity Act对象
*/
public void addActivity(Activity activity) {
if (null == activityStack) {
activityStack = new Stack<>();
}
activityStack.add(activity);
}
/**
* 退出栈中所有Activity
* @param cls
* @return void
*/
public void exitApp(Class<?> cls) {
while (true) {
Activity activity = currentActivity();
if (null == activity) {
break;
}
if (activity.getClass().equals(cls)) {
break;
}
removeActivity(activity);
}
System.gc();
System.exit(0);
}
}
... ...
package com.example.zhongqiyan.base;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.zhongqiyan.DebugLog;
import com.example.zhongqiyan.R;
import com.example.zhongqiyan.base.instant.ViewInject;
import com.example.zhongqiyan.base.instant.slideslip.SlideLip;
import com.example.zhongqiyan.network.ApiService;
import com.example.zhongqiyan.network.ApiStore;
import java.util.List;
import butterknife.ButterKnife;
import butterknife.Unbinder;
public abstract class BaseActivity extends AppCompatActivity{
public AppDavikActivityUtil appDavikActivityUtil = AppDavikActivityUtil.getScreenManager();
final String TAG = this.getClass().getSimpleName(); //获取当前activity
/**
* context
*/
protected Context ctx;
protected BaseActivity activity;
boolean lip;
private int width;
private int height;
private Unbinder bind;
int yes, no;
/**
* 初始化数据
*/
protected abstract void initData();
/**
* 绑定事件
*/
protected abstract void setEvent();
@SuppressLint("NewApi")
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
no = getResources().getColor(R.color.color_232323);
yes = getResources().getColor(R.color.color_ffab13);
super.onCreate(savedInstanceState);
DebugLog.e(TAG + "--->OnCreate");
activity = this; // 上下文
new ViewInject(activity).setView().injectViews().injectEvents().TopNavigationBar(); // 先初始化 - > 实例化 - > 点击事件 - > 导航栏颜色 , 样式
bind = ButterKnife.bind(this);
initData();//数据
setEvent();//事件
ctx = this;
ActivityStackManager.getActivityStackManager().pushActivity(this); // 将activity添加到堆栈中
initAttributes();
}
// 注解
private void initAttributes() {
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
Display defaultDisplay = windowManager.getDefaultDisplay();
width = defaultDisplay.getWidth();
height = defaultDisplay.getHeight();
SlideLip slide = activity.getClass().getAnnotation(SlideLip.class);
if (slide != null) {
try {
lip = slide.slidelip();
} catch (Exception e) {
e.printStackTrace();
}
}
}
// ---------------------------------------------------- 简用 -------------------------------------------------------------
/**
* @param manager // - > manager 0 = GridLayoutManager | 1 = LinearLayoutManager
* @param rv
* @param orientation // - > orientation 0 = VERTICAL | else HORIZONTAL
* @param count // - > count 设置 GridLayoutManager 的横向数量
*/
@SuppressLint("WrongConstant")
public void setRv(RecyclerView rv, int manager, int orientation, int count) {
if (manager == 0) {
GridLayoutManager gridManager = new GridLayoutManager(this, count);
rv.setLayoutManager(gridManager);
} else {
LinearLayoutManager linearManager = new LinearLayoutManager(this);
if (orientation == 0) {
linearManager.setOrientation(LinearLayoutManager.VERTICAL);
} else {
linearManager.setOrientation(LinearLayoutManager.HORIZONTAL);
}
rv.setLayoutManager(linearManager);
}
}
// -------------------------- api -------------------------------------------
public ApiService Api() {
ApiService api = ApiStore.createApi(ApiService.class);
return api;
}
// ----------------------- check 仿 tablayout .. ---------------------------------
// - > 主要是因为懒 .. 所以手写一个 后面闲的蛋疼的时候 , 会自己去写控件 这个只是提供一个思路
List<View> list;
public void checkData(List<View> line) {
this.list = line;
check();
}
// 0 . 2 . 4 .. text 1 . 3 . 5 .. view
public void check() {
for (int i = 1; i < list.size() + 1; i++) {
if (i == 1 || i % 2 == 1) {
((TextView) list.get(i - 1)).setTextColor(no);
} else {
list.get(i - 1).setBackgroundColor(no);
list.get(i - 1).setVisibility(View.INVISIBLE);
}
}
}
// ----------------------------------- 生命周期 ----------------------------------
@Override
protected void onStart() {
super.onStart();
Log.i(TAG, "--->onStart()");
}
@Override
protected void onResume() {
super.onResume();
Log.i(TAG, "--->onResume()");
}
@Override
protected void onRestart() {
super.onRestart();
Log.i(TAG, "--->onRestart()");
}
@Override
protected void onPause() {
super.onPause();
Log.i(TAG, "--->onPause()");
}
@Override
protected void onStop() {
super.onStop();
Log.i(TAG, "--->onStop()");
}
@Override
protected void onDestroy() {
appDavikActivityUtil.removeActivity(this);
Log.i(TAG, "--->onDestroy()");
bind.unbind();
super.onDestroy();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float dx = 0, dy = 0, ux = 0, uy = 0;
if (lip == true) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: // down
dx = event.getX();
dy = event.getY();
break;
case MotionEvent.ACTION_UP:
ux = event.getX();
uy = event.getY();
if ((ux - dx) > (width / 2)) {
activity.finish();
}
break;
}
}
return super.onTouchEvent(event);
}
/**
* 跳转Activity Flag == true --> finish
* skip Another Activity
*
* @param activity
* @param cls
*/
public static void skipAnotherActivity(Activity activity, Class<? extends Activity> cls, boolean flag) {
activity.startActivity(new Intent(activity, cls));
if (flag == true) {
activity.finish();
}
}
/**
* 退出应用
* called while exit app
*/
public void exitLogic() {
ActivityStackManager.getActivityStackManager().popAllActivity(); //清楚所有栈中的activity
System.exit(0);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
FragmentManager fm = getSupportFragmentManager();
int index = requestCode >> 16;
if (index != 0) {
index--;
if (fm.getFragments() == null || index < 0
|| index >= fm.getFragments().size()) {
Log.w(TAG, "Activity result fragment index out of range: 0x"
+ Integer.toHexString(requestCode));
return;
}
Fragment frag = fm.getFragments().get(index);
if (frag == null) {
Log.w(TAG, "Activity result no fragment exists for index: 0x"
+ Integer.toHexString(requestCode));
} else {
handleResult(frag, requestCode, resultCode, data);
}
return;
}
}
/**
* 递归调用,对所有子Fragement生效
*
* @param frag
* @param requestCode
* @param resultCode
* @param data
*/
private void handleResult(Fragment frag, int requestCode, int resultCode,
Intent data) {
frag.onActivityResult(requestCode & 0xffff, resultCode, data);
List<Fragment> frags = frag.getChildFragmentManager().getFragments();
if (frags != null) {
for (Fragment f : frags) {
if (f != null)
handleResult(f, requestCode, resultCode, data);
}
}
}
}
... ...
package com.example.zhongqiyan.base;
public class Config {
public static int RUN_MODE = 1; // 0 测试 1 正式
public static final String BASE_IP = "http://ctest.ynsdfx.com";//测试服务器
public static final String LOGIN_IP = "http://api.ynsdfx.com";//登录的
public static String Token = ""; // 0 测试 1 正式
}
... ...
package com.example.zhongqiyan.base.instant;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @fileName: InstantViews
* @date: 2019/12/7
* @author: lm
* @QQ:820139338 - > 没事别加着玩
*/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface InstantViews {
int value();
int[] inject() default 0;
}
... ...
package com.example.zhongqiyan.base.instant;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @fileName: Layout
* @date: 2019/12/7
* @author: lm
* @QQ:820139338 - > 没事别加着玩
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface Layout {
int value() default -1;
}
... ...
package com.example.zhongqiyan.base.instant;
import android.graphics.Color;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @fileName: TopNavigationBar
* @date: 2019/12/7
* @author: lm
* @QQ:820139338 - > 没事别加着玩
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface TopNavigationBar {
int color() default Color.TRANSPARENT; // 0 - > 状态栏颜色
int setBarBiack() default 0; // - > 状态栏字体颜色
}
... ...
package com.example.zhongqiyan.base.instant;
import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.view.View;
import com.example.zhongqiyan.base.BaseActivity;
import com.example.zhongqiyan.base.instant.click.ClickView;
import com.example.zhongqiyan.base.instant.click.DynamicHandler;
import com.example.zhongqiyan.base.instant.click.ListenerViews;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @fileName: ViewInject
* @date: 2019/12/7
* @author: lm
* @QQ:820139338 - > 没事别加着玩
*/
public class ViewInject {
Activity activity;
public ViewInject(BaseActivity activity) {
this.activity = activity;
}
/**
* 初始化
*
*/
public ViewInject setView() {
for (Class c = activity.getClass(); c != Context.class; c = c.getSuperclass()) {
Layout annotation = (Layout) c.getAnnotation(Layout.class);
if (annotation != null) {
try {
activity.setContentView(annotation.value());
} catch (RuntimeException e) {
e.printStackTrace();
}
// return;
}
}
return this;
}
/**
* 状态栏设置
*
* @param activity
*/
public ViewInject TopNavigationBar() {
TopNavigationBar annotation = activity.getClass().getAnnotation(TopNavigationBar.class);
if (annotation != null) {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
int color = annotation.color(); // 状态栏颜色
activity.getWindow().setStatusBarColor(color);
int status = annotation.setBarBiack(); // - > 状态栏模式
switch (status) {
case 0: // SYSTEM_UI_FLAG_LIGHT_STATUS_BAR 状态栏存在 , 布局下推 , 字体黑色
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
break;
case 1: // SYSTEM_UI_FLAG_FULLSCREEN 状态栏初始隐藏(模式全屏), 滑动后可唤醒 (布局下推)
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
break;
case 2: // SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 字体白色
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_STABLE); // 隐藏 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
return this;
}
/**
* 实例化
*
* @param activity
*/
public ViewInject injectViews() {
Class<? extends Activity> a = activity.getClass();
Field[] fields = a.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(InstantViews.class)) {
InstantViews annotation = field.getAnnotation(InstantViews.class);
int value = annotation.value();
try {
Method method = a.getMethod("findViewById", int.class);
Object invoke = method.invoke(activity, value);
field.setAccessible(true); //值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查
field.set(activity, invoke);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return this;
}
/**
* 点击事件
*
* @param activity
*/
public ViewInject injectEvents() {
Class<? extends Activity> aClass = activity.getClass();
Method[] methods = aClass.getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(ClickView.class)) {
ClickView onClick = method.getAnnotation(ClickView.class);
int[] viewIds = onClick.value();
ListenerViews eventBase = onClick.annotationType().getAnnotation(ListenerViews.class);
String listenerSetter = eventBase.listenerSetter();
Class listenerType = eventBase.listenerType();
String methodName = eventBase.methodName();
DynamicHandler handler = new DynamicHandler(activity);
Object listener = Proxy.newProxyInstance(listenerType.getClassLoader(), new Class<?>[]{listenerType}, handler);
handler.addMethod(methodName, method);
for (int viewId : viewIds) {
try {
Method findViewByIdMethod = aClass.getMethod("findViewById", int.class);
findViewByIdMethod.setAccessible(true);
View view = (View) findViewByIdMethod.invoke(activity, viewId);
Method setEventListenerMethod = view.getClass().getMethod(listenerSetter, listenerType);
setEventListenerMethod.setAccessible(true);
setEventListenerMethod.invoke(view, listener);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
return this;
}
}
... ...
package com.example.zhongqiyan.base.instant.click;
import android.view.View;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @fileName: ClickView
* @date: 2019/12/7
* @author: lm
* @QQ:820139338 - > 没事别加着玩
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@ListenerViews(listenerType = View.OnClickListener.class,listenerSetter = "setOnClickListener", methodName = "onClick")
public @interface ClickView {
int[] value() default 0;
}
... ...
package com.example.zhongqiyan.base.instant.click;
import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.HashMap;
/**
* @fileName: DynamicHandler
* @date: 2019/12/7
* @author: lm
* @QQ:820139338 - > 没事别加着玩
*/
public class DynamicHandler implements InvocationHandler {
private final HashMap<String, Method> methodMap = new HashMap<>(1);
// 因为传进来的为activity,使用弱引用主要是为了防止内存泄漏
private WeakReference<Object> handlerRef;
public DynamicHandler(Object object) {
this.handlerRef = new WeakReference<Object>(object);
}
public void addMethod(String name, Method method) {
methodMap.put(name, method);
}
// 当回到OnClickListener的OnClick方法的时候,它会调用这里的invoke方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 得到activity实例
Object handler = handlerRef.get();
if (handler != null) {
// method对应的就是回调方法OnClick,得到方法名
String methodName = method.getName();
// 得到activtiy里面的clickBtnInvoked方法
method = methodMap.get(methodName);
if (method != null) {
// 回调clickBtnInvoked方法
return method.invoke(handler, args);
}
}
return null;
}
}
... ...
package com.example.zhongqiyan.base.instant.click;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @fileName: ListenerViews
* @date: 2019/12/7
* @author: lm
* @QQ:820139338 - > 没事别加着玩
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ListenerViews {
Class listenerType();
String listenerSetter();
String methodName();
}
... ...
package com.example.zhongqiyan.base.instant.fragment;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author: Kongzue
* @github: https://github.com/kongzue/
* @homepage: http://kongzue.com/
* @mail: myzcxhh@live.cn
* @createTime: 2019/11/21 15:17
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BindView {
int value() default 0;
}
... ...
package com.example.zhongqiyan.base.instant.fragment;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author: Kongzue
* @github: https://github.com/kongzue/
* @homepage: http://kongzue.com/
* @mail: myzcxhh@live.cn
* @createTime: 2019/11/21 22:08
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BindViews {
int[] value() default 0;
}
\ No newline at end of file
... ...
package com.example.zhongqiyan.base.instant.fragment;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author: Kongzue
* @github: https://github.com/kongzue/
* @homepage: http://kongzue.com/
* @mail: myzcxhh@live.cn
* @createTime: 2019/11/21 15:19
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OnClick {
int value() default 0;
}
\ No newline at end of file
... ...
package com.example.zhongqiyan.base.instant.slideslip;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @fileName: SlideLip
* @date: 2019/12/7
* @author: lm
* @QQ:820139338 - > 没事别加着玩
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface SlideLip {
boolean slidelip() default false;
}
... ...
package com.example.zhongqiyan.javasource.ca.uol.aig.fftpack;
/**
* Construct a 1-D complex data sequence.
*/
public class Complex1D
{
/**
* <em>x</em>[<em>i</em>] is the real part of <em>i</em>-th complex data.
*/
public double x[];
/**
* <em>y</em>[<em>i</em>] is the imaginary part of <em>i</em>-th complex data.
*/
public double y[];
}
... ...
package com.example.zhongqiyan.javasource.ca.uol.aig.fftpack;
/**
* FFT transform of a complex periodic sequence.
* @author Baoshe Zhang
* @author Astronomical Instrument Group of University of Lethbridge.
*/
public class ComplexDoubleFFT extends ComplexDoubleFFT_Mixed
{
/**
* <em>norm_factor</em> can be used to normalize this FFT transform. This is because
* a call of forward transform (<em>ft</em>) followed by a call of backward transform
* (<em>bt</em>) will multiply the input sequence by <em>norm_factor</em>.
*/
public double norm_factor;
private double wavetable[];
private int ndim;
/**
* Construct a wavenumber table with size <em>n</em> for Complex FFT.
* The sequences with the same size can share a wavenumber table. The prime
* factorization of <em>n</em> together with a tabulation of the trigonometric functions
* are computed and stored.
*
* @param n the size of a complex data sequence. When <em>n</em> is a multiplication of small
* numbers (4, 2, 3, 5), this FFT transform is very efficient.
*/
public ComplexDoubleFFT(int n)
{
ndim = n;
norm_factor = n;
if(wavetable == null || wavetable.length !=(4*ndim+15))
{
wavetable = new double[4*ndim + 15];
}
cffti(ndim, wavetable);
}
/**
* Forward complex FFT transform.
*
* @param x 2*<em>n</em> real double data representing <em>n</em> complex double data.
* As an input parameter, <em>x</em> is an array of 2*<em>n</em> real
* data representing <em>n</em> complex data. As an output parameter, <em>x</em> represents <em>n</em>
* FFT'd complex data. Their relation as follows:
* <br>
* x[2*i] is the real part of <em>i</em>-th complex data;
* <br>
* x[2*i+1] is the imaginary part of <em>i</em>-the complex data.
*
*/
public void ft(double x[])
{
if(x.length != 2*ndim)
throw new IllegalArgumentException("The length of data can not match that of the wavetable");
cfftf(ndim, x, wavetable);
}
/**
* Forward complex FFT transform.
*
* @param x an array of <em>n</em> Complex data
*/
public void ft(Complex1D x)
{
if(x.x.length != ndim)
throw new IllegalArgumentException("The length of data can not match that of the wavetable");
double[] y = new double[2*ndim];
for(int i=0; i<ndim; i++)
{
y[2*i] = x.x[i];
y[2*i+1] = x.y[i];
}
cfftf(ndim, y, wavetable);
for(int i=0; i<ndim; i++)
{
x.x[i]=y[2*i];
x.y[i]=y[2*i+1];
}
}
/**
* Backward complex FFT transform. It is the unnormalized inverse transform of <em>ft</em>(double[]).
*
* @param x 2*<em>n</em> real double data representing <em>n</em> complex double data.
*
* As an input parameter, <em>x</em> is an array of 2*<em>n</em>
* real data representing <em>n</em> complex data. As an output parameter, <em>x</em> represents
* <em>n</em> FFT'd complex data. Their relation as follows:
* <br>
* x[2*<em>i</em>] is the real part of <em>i</em>-th complex data;
* <br>
* x[2*<em>i</em>+1] is the imaginary part of <em>i</em>-the complex data.
*
*/
public void bt(double x[])
{
if(x.length != 2*ndim)
throw new IllegalArgumentException("The length of data can not match that of the wavetable");
cfftb(ndim, x, wavetable);
}
/**
* Backward complex FFT transform. It is the unnormalized inverse transform of <em>ft</em>(Complex1D[]).
*
*
* @param x an array of <em>n</em> Complex data
*/
public void bt(Complex1D x)
{
if(x.x.length != ndim)
throw new IllegalArgumentException("The length of data can not match that of the wavetable");
double[] y = new double[2*ndim];
for(int i=0; i<ndim; i++)
{
y[2*i] = x.x[i];
y[2*i+1] = x.y[i];
}
cfftb(ndim, y, wavetable);
for(int i=0; i<ndim; i++)
{
x.x[i]=y[2*i];
x.y[i]=y[2*i+1];
}
}
}
... ...
package com.example.zhongqiyan.javasource.ca.uol.aig.fftpack;
/**
* @author Baoshe Zhang
* @author Astronomical Instrument Group of University of Lethbridge.
*/
class ComplexDoubleFFT_Mixed
{
/*----------------------------------------------------------------------
passf2: Complex FFT's forward/backward processing of factor 2;
isign is +1 for backward and -1 for forward transforms
----------------------------------------------------------------------*/
void passf2(int ido, int l1, final double cc[], double ch[], final double wtable[], int offset, int isign)
/*isign==+1 for backward transform*/
{
int i, k, ah, ac;
double ti2, tr2;
int iw1;
iw1 = offset;
if(ido<=2)
{
for(k=0; k<l1; k++)
{
ah=k*ido;
ac=2*k*ido;
ch[ah]=cc[ac]+cc[ac+ido];
ch[ah+ido*l1]=cc[ac]-cc[ac+ido];
ch[ah+1]=cc[ac+1]+cc[ac+ido+1];
ch[ah+ido*l1+1]=cc[ac+1]-cc[ac+ido+1];
}
}
else
{
for(k=0; k<l1; k++)
{
for(i=0; i<ido-1; i+=2)
{
ah=i+k*ido;
ac=i+2*k*ido;
ch[ah]=cc[ac]+cc[ac+ido];
tr2=cc[ac]-cc[ac+ido];
ch[ah+1]=cc[ac+1]+cc[ac+1+ido];
ti2=cc[ac+1]-cc[ac+1+ido];
ch[ah+l1*ido+1]=wtable[i+iw1]*ti2+isign*wtable[i+1+iw1]*tr2;
ch[ah+l1*ido]=wtable[i+iw1]*tr2-isign*wtable[i+1+iw1]*ti2;
}
}
}
}
/*----------------------------------------------------------------------
passf3: Complex FFT's forward/backward processing of factor 3;
isign is +1 for backward and -1 for forward transforms
----------------------------------------------------------------------*/
void passf3(int ido, int l1, final double cc[], double ch[], final double wtable[], int offset, int isign)
{
final double taur=-0.5;
final double taui=0.866025403784439;
int i, k, ac, ah;
double ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2;
int iw1, iw2;
iw1 = offset;
iw2 = iw1 + ido;
if(ido==2)
{
for(k=1; k<=l1; k++)
{
ac=(3*k-2)*ido;
tr2=cc[ac]+cc[ac+ido];
cr2=cc[ac-ido]+taur*tr2;
ah=(k-1)*ido;
ch[ah]=cc[ac-ido]+tr2;
ti2=cc[ac+1]+cc[ac+ido+1];
ci2=cc[ac-ido+1]+taur*ti2;
ch[ah+1]=cc[ac-ido+1]+ti2;
cr3=isign*taui*(cc[ac]-cc[ac+ido]);
ci3=isign*taui*(cc[ac+1]-cc[ac+ido+1]);
ch[ah+l1*ido]=cr2-ci3;
ch[ah+2*l1*ido]=cr2+ci3;
ch[ah+l1*ido+1]=ci2+cr3;
ch[ah+2*l1*ido+1]=ci2-cr3;
}
}
else
{
for(k=1; k<=l1; k++)
{
for(i=0; i<ido-1; i+=2)
{
ac=i+(3*k-2)*ido;
tr2=cc[ac]+cc[ac+ido];
cr2=cc[ac-ido]+taur*tr2;
ah=i+(k-1)*ido;
ch[ah]=cc[ac-ido]+tr2;
ti2=cc[ac+1]+cc[ac+ido+1];
ci2=cc[ac-ido+1]+taur*ti2;
ch[ah+1]=cc[ac-ido+1]+ti2;
cr3=isign*taui*(cc[ac]-cc[ac+ido]);
ci3=isign*taui*(cc[ac+1]-cc[ac+ido+1]);
dr2=cr2-ci3;
dr3=cr2+ci3;
di2=ci2+cr3;
di3=ci2-cr3;
ch[ah+l1*ido+1]=wtable[i+iw1]*di2+isign*wtable[i+1+iw1]*dr2;
ch[ah+l1*ido]=wtable[i+iw1]*dr2-isign*wtable[i+1+iw1]*di2;
ch[ah+2*l1*ido+1]=wtable[i+iw2]*di3+isign*wtable[i+1+iw2]*dr3;
ch[ah+2*l1*ido]=wtable[i+iw2]*dr3-isign*wtable[i+1+iw2]*di3;
}
}
}
}
/*----------------------------------------------------------------------
passf4: Complex FFT's forward/backward processing of factor 4;
isign is +1 for backward and -1 for forward transforms
----------------------------------------------------------------------*/
void passf4(int ido, int l1, final double cc[], double ch[], final double wtable[], int offset, int isign)
{
int i, k, ac, ah;
double ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4;
int iw1, iw2, iw3;
iw1 = offset;
iw2 = iw1 + ido;
iw3 = iw2 + ido;
if(ido==2)
{
for(k=0; k<l1; k++)
{
ac=4*k*ido+1;
ti1=cc[ac]-cc[ac+2*ido];
ti2=cc[ac]+cc[ac+2*ido];
tr4=cc[ac+3*ido]-cc[ac+ido];
ti3=cc[ac+ido]+cc[ac+3*ido];
tr1=cc[ac-1]-cc[ac+2*ido-1];
tr2=cc[ac-1]+cc[ac+2*ido-1];
ti4=cc[ac+ido-1]-cc[ac+3*ido-1];
tr3=cc[ac+ido-1]+cc[ac+3*ido-1];
ah=k*ido;
ch[ah]=tr2+tr3;
ch[ah+2*l1*ido]=tr2-tr3;
ch[ah+1]=ti2+ti3;
ch[ah+2*l1*ido+1]=ti2-ti3;
ch[ah+l1*ido]=tr1+isign*tr4;
ch[ah+3*l1*ido]=tr1-isign*tr4;
ch[ah+l1*ido+1]=ti1+isign*ti4;
ch[ah+3*l1*ido+1]=ti1-isign*ti4;
}
}
else
{
for(k=0; k<l1; k++)
{
for(i=0; i<ido-1; i+=2)
{
ac=i+1+4*k*ido;
ti1=cc[ac]-cc[ac+2*ido];
ti2=cc[ac]+cc[ac+2*ido];
ti3=cc[ac+ido]+cc[ac+3*ido];
tr4=cc[ac+3*ido]-cc[ac+ido];
tr1=cc[ac-1]-cc[ac+2*ido-1];
tr2=cc[ac-1]+cc[ac+2*ido-1];
ti4=cc[ac+ido-1]-cc[ac+3*ido-1];
tr3=cc[ac+ido-1]+cc[ac+3*ido-1];
ah=i+k*ido;
ch[ah]=tr2+tr3;
cr3=tr2-tr3;
ch[ah+1]=ti2+ti3;
ci3=ti2-ti3;
cr2=tr1+isign*tr4;
cr4=tr1-isign*tr4;
ci2=ti1+isign*ti4;
ci4=ti1-isign*ti4;
ch[ah+l1*ido]=wtable[i+iw1]*cr2-isign*wtable[i+1+iw1]*ci2;
ch[ah+l1*ido+1]=wtable[i+iw1]*ci2+isign*wtable[i+1+iw1]*cr2;
ch[ah+2*l1*ido]=wtable[i+iw2]*cr3-isign*wtable[i+1+iw2]*ci3;
ch[ah+2*l1*ido+1]=wtable[i+iw2]*ci3+isign*wtable[i+1+iw2]*cr3;
ch[ah+3*l1*ido]=wtable[i+iw3]*cr4-isign*wtable[i+1+iw3]*ci4;
ch[ah+3*l1*ido+1]=wtable[i+iw3]*ci4+isign*wtable[i+1+iw3]*cr4;
}
}
}
}
/*----------------------------------------------------------------------
passf5: Complex FFT's forward/backward processing of factor 5;
isign is +1 for backward and -1 for forward transforms
----------------------------------------------------------------------*/
void passf5(int ido, int l1, final double cc[], double ch[], final double wtable[], int offset, int isign)
/*isign==-1 for forward transform and+1 for backward transform*/
{
final double tr11=0.309016994374947;
final double ti11=0.951056516295154;
final double tr12=-0.809016994374947;
final double ti12=0.587785252292473;
int i, k, ac, ah;
double ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4,
ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5;
int iw1, iw2, iw3, iw4;
iw1 = offset;
iw2 = iw1 + ido;
iw3 = iw2 + ido;
iw4 = iw3 + ido;
if(ido==2)
{
for(k=1; k<=l1;++k)
{
ac=(5*k-4)*ido+1;
ti5=cc[ac]-cc[ac+3*ido];
ti2=cc[ac]+cc[ac+3*ido];
ti4=cc[ac+ido]-cc[ac+2*ido];
ti3=cc[ac+ido]+cc[ac+2*ido];
tr5=cc[ac-1]-cc[ac+3*ido-1];
tr2=cc[ac-1]+cc[ac+3*ido-1];
tr4=cc[ac+ido-1]-cc[ac+2*ido-1];
tr3=cc[ac+ido-1]+cc[ac+2*ido-1];
ah=(k-1)*ido;
ch[ah]=cc[ac-ido-1]+tr2+tr3;
ch[ah+1]=cc[ac-ido]+ti2+ti3;
cr2=cc[ac-ido-1]+tr11*tr2+tr12*tr3;
ci2=cc[ac-ido]+tr11*ti2+tr12*ti3;
cr3=cc[ac-ido-1]+tr12*tr2+tr11*tr3;
ci3=cc[ac-ido]+tr12*ti2+tr11*ti3;
cr5=isign*(ti11*tr5+ti12*tr4);
ci5=isign*(ti11*ti5+ti12*ti4);
cr4=isign*(ti12*tr5-ti11*tr4);
ci4=isign*(ti12*ti5-ti11*ti4);
ch[ah+l1*ido]=cr2-ci5;
ch[ah+4*l1*ido]=cr2+ci5;
ch[ah+l1*ido+1]=ci2+cr5;
ch[ah+2*l1*ido+1]=ci3+cr4;
ch[ah+2*l1*ido]=cr3-ci4;
ch[ah+3*l1*ido]=cr3+ci4;
ch[ah+3*l1*ido+1]=ci3-cr4;
ch[ah+4*l1*ido+1]=ci2-cr5;
}
}
else
{
for(k=1; k<=l1; k++)
{
for(i=0; i<ido-1; i+=2)
{
ac=i+1+(k*5-4)*ido;
ti5=cc[ac]-cc[ac+3*ido];
ti2=cc[ac]+cc[ac+3*ido];
ti4=cc[ac+ido]-cc[ac+2*ido];
ti3=cc[ac+ido]+cc[ac+2*ido];
tr5=cc[ac-1]-cc[ac+3*ido-1];
tr2=cc[ac-1]+cc[ac+3*ido-1];
tr4=cc[ac+ido-1]-cc[ac+2*ido-1];
tr3=cc[ac+ido-1]+cc[ac+2*ido-1];
ah=i+(k-1)*ido;
ch[ah]=cc[ac-ido-1]+tr2+tr3;
ch[ah+1]=cc[ac-ido]+ti2+ti3;
cr2=cc[ac-ido-1]+tr11*tr2+tr12*tr3;
ci2=cc[ac-ido]+tr11*ti2+tr12*ti3;
cr3=cc[ac-ido-1]+tr12*tr2+tr11*tr3;
ci3=cc[ac-ido]+tr12*ti2+tr11*ti3;
cr5=isign*(ti11*tr5+ti12*tr4);
ci5=isign*(ti11*ti5+ti12*ti4);
cr4=isign*(ti12*tr5-ti11*tr4);
ci4=isign*(ti12*ti5-ti11*ti4);
dr3=cr3-ci4;
dr4=cr3+ci4;
di3=ci3+cr4;
di4=ci3-cr4;
dr5=cr2+ci5;
dr2=cr2-ci5;
di5=ci2-cr5;
di2=ci2+cr5;
ch[ah+l1*ido]=wtable[i+iw1]*dr2-isign*wtable[i+1+iw1]*di2;
ch[ah+l1*ido+1]=wtable[i+iw1]*di2+isign*wtable[i+1+iw1]*dr2;
ch[ah+2*l1*ido]=wtable[i+iw2]*dr3-isign*wtable[i+1+iw2]*di3;
ch[ah+2*l1*ido+1]=wtable[i+iw2]*di3+isign*wtable[i+1+iw2]*dr3;
ch[ah+3*l1*ido]=wtable[i+iw3]*dr4-isign*wtable[i+1+iw3]*di4;
ch[ah+3*l1*ido+1]=wtable[i+iw3]*di4+isign*wtable[i+1+iw3]*dr4;
ch[ah+4*l1*ido]=wtable[i+iw4]*dr5-isign*wtable[i+1+iw4]*di5;
ch[ah+4*l1*ido+1]=wtable[i+iw4]*di5+isign*wtable[i+1+iw4]*dr5;
}
}
}
}
/*----------------------------------------------------------------------
passfg: Complex FFT's forward/backward processing of general factor;
isign is +1 for backward and -1 for forward transforms
----------------------------------------------------------------------*/
void passfg(int nac[], int ido, int ip, int l1, int idl1,
final double cc[], double c1[], double c2[], double ch[], double ch2[],
final double wtable[], int offset, int isign)
{
int idij, idlj, idot, ipph, i, j, k, l, jc, lc, ik, nt, idj, idl, inc, idp;
double wai, war;
int iw1;
iw1 = offset;
idot=ido / 2;
nt=ip*idl1;
ipph=(ip+1)/ 2;
idp=ip*ido;
if(ido>=l1)
{
for(j=1; j<ipph; j++)
{
jc=ip-j;
for(k=0; k<l1; k++)
{
for(i=0; i<ido; i++)
{
ch[i+(k+j*l1)*ido]=cc[i+(j+k*ip)*ido]+cc[i+(jc+k*ip)*ido];
ch[i+(k+jc*l1)*ido]=cc[i+(j+k*ip)*ido]-cc[i+(jc+k*ip)*ido];
}
}
}
for(k=0; k<l1; k++)
for(i=0; i<ido; i++)
ch[i+k*ido]=cc[i+k*ip*ido];
}
else
{
for(j=1; j<ipph; j++)
{
jc=ip-j;
for(i=0; i<ido; i++)
{
for(k=0; k<l1; k++)
{
ch[i+(k+j*l1)*ido]=cc[i+(j+k*ip)*ido]+cc[i+(jc+k*ip)*ido];
ch[i+(k+jc*l1)*ido]=cc[i+(j+k*ip)*ido]-cc[i+(jc+k*ip)*ido];
}
}
}
for(i=0; i<ido; i++)
for(k=0; k<l1; k++)
ch[i+k*ido]=cc[i+k*ip*ido];
}
idl=2-ido;
inc=0;
for(l=1; l<ipph; l++)
{
lc=ip-l;
idl+=ido;
for(ik=0; ik<idl1; ik++)
{
c2[ik+l*idl1]=ch2[ik]+wtable[idl-2+iw1]*ch2[ik+idl1];
c2[ik+lc*idl1]=isign*wtable[idl-1+iw1]*ch2[ik+(ip-1)*idl1];
}
idlj=idl;
inc+=ido;
for(j=2; j<ipph; j++)
{
jc=ip-j;
idlj+=inc;
if(idlj>idp) idlj-=idp;
war=wtable[idlj-2+iw1];
wai=wtable[idlj-1+iw1];
for(ik=0; ik<idl1; ik++)
{
c2[ik+l*idl1]+=war*ch2[ik+j*idl1];
c2[ik+lc*idl1]+=isign*wai*ch2[ik+jc*idl1];
}
}
}
for(j=1; j<ipph; j++)
for(ik=0; ik<idl1; ik++)
ch2[ik]+=ch2[ik+j*idl1];
for(j=1; j<ipph; j++)
{
jc=ip-j;
for(ik=1; ik<idl1; ik+=2)
{
ch2[ik-1+j*idl1]=c2[ik-1+j*idl1]-c2[ik+jc*idl1];
ch2[ik-1+jc*idl1]=c2[ik-1+j*idl1]+c2[ik+jc*idl1];
ch2[ik+j*idl1]=c2[ik+j*idl1]+c2[ik-1+jc*idl1];
ch2[ik+jc*idl1]=c2[ik+j*idl1]-c2[ik-1+jc*idl1];
}
}
nac[0]=1;
if(ido==2) return;
nac[0]=0;
for(ik=0; ik<idl1; ik++) c2[ik]=ch2[ik];
for(j=1; j<ip; j++)
{
for(k=0; k<l1; k++)
{
c1[(k+j*l1)*ido+0]=ch[(k+j*l1)*ido+0];
c1[(k+j*l1)*ido+1]=ch[(k+j*l1)*ido+1];
}
}
if(idot<=l1)
{
idij=0;
for(j=1; j<ip; j++)
{
idij+=2;
for(i=3; i<ido; i+=2)
{
idij+=2;
for(k=0; k<l1; k++)
{
c1[i-1+(k+j*l1)*ido]=
wtable[idij-2+iw1]*ch[i-1+(k+j*l1)*ido]-
isign*wtable[idij-1+iw1]*ch[i+(k+j*l1)*ido];
c1[i+(k+j*l1)*ido]=
wtable[idij-2+iw1]*ch[i+(k+j*l1)*ido]+
isign*wtable[idij-1+iw1]*ch[i-1+(k+j*l1)*ido];
}
}
}
}
else
{
idj=2-ido;
for(j=1; j<ip; j++)
{
idj+=ido;
for(k=0; k<l1; k++)
{
idij=idj;
for(i=3; i<ido; i+=2)
{
idij+=2;
c1[i-1+(k+j*l1)*ido]=
wtable[idij-2+iw1]*ch[i-1+(k+j*l1)*ido]-
isign*wtable[idij-1+iw1]*ch[i+(k+j*l1)*ido];
c1[i+(k+j*l1)*ido]=
wtable[idij-2+iw1]*ch[i+(k+j*l1)*ido]+
isign*wtable[idij-1+iw1]*ch[i-1+(k+j*l1)*ido];
}
}
}
}
}
/*---------------------------------------------------------
cfftf1: further processing of Complex forward FFT
--------------------------------------------------------*/
void cfftf1(int n, double c[], final double wtable[], int isign)
{
int idot, i;
int k1, l1, l2;
int na, nf, ip, iw, ido, idl1;
int[] nac = new int[1];
int iw1, iw2;
double[] ch = new double[2*n];
iw1=2*n;
iw2=4*n;
System.arraycopy(wtable, 0, ch, 0, 2*n);
nac[0] = 0;
nf=(int)wtable[1+iw2];
na=0;
l1=1;
iw=iw1;
for(k1=2; k1<=nf+1; k1++)
{
ip=(int)wtable[k1+iw2];
l2=ip*l1;
ido=n / l2;
idot=ido+ido;
idl1=idot*l1;
if(ip==4)
{
if(na==0)
{
passf4(idot, l1, c, ch, wtable, iw, isign);
}
else
{
passf4(idot, l1, ch, c, wtable, iw, isign);
}
na=1-na;
}
else if(ip==2)
{
if(na==0)
{
passf2(idot, l1, c, ch, wtable, iw, isign);
}
else
{
passf2(idot, l1, ch, c, wtable, iw, isign);
}
na=1-na;
}
else if(ip==3)
{
if(na==0)
{
passf3(idot, l1, c, ch, wtable, iw, isign);
}
else
{
passf3(idot, l1, ch, c, wtable, iw, isign);
}
na=1-na;
}
else if(ip==5)
{
if(na==0)
{
passf5(idot, l1, c, ch, wtable, iw, isign);
}
else
{
passf5(idot, l1, ch, c, wtable, iw, isign);
}
na=1-na;
}
else
{
if(na==0)
{
passfg(nac, idot, ip, l1, idl1, c, c, c, ch, ch, wtable, iw, isign);
}
else
{
passfg(nac, idot, ip, l1, idl1, ch, ch, ch, c, c, wtable, iw, isign);
}
if(nac[0] !=0) na=1-na;
}
l1=l2;
iw+=(ip-1)*idot;
}
if(na==0) return;
for(i=0; i<2*n; i++) c[i]=ch[i];
}
/*---------------------------------------------------------
cfftf: Complex forward FFT
--------------------------------------------------------*/
void cfftf(int n, double c[], double wtable[])
{
cfftf1(n, c, wtable, -1);
}
/*---------------------------------------------------------
cfftb: Complex borward FFT
--------------------------------------------------------*/
void cfftb(int n, double c[], double wtable[])
{
cfftf1(n, c, wtable, +1);
}
/*---------------------------------------------------------
cffti1: further initialization of Complex FFT
--------------------------------------------------------*/
void cffti1(int n, double wtable[])
{
final int[] ntryh = {3, 4, 2, 5};
final double twopi=2.0D*Math.PI;
double argh;
int idot, ntry=0, i, j;
double argld;
int i1, k1, l1, l2, ib;
double fi;
int ld, ii, nf, ip, nl, nq, nr;
double arg;
int ido, ipm;
nl=n;
nf=0;
j=0;
factorize_loop:
while(true)
{
j++;
if(j<=4)
ntry=ntryh[j-1];
else
ntry+=2;
do
{
nq=nl / ntry;
nr=nl-ntry*nq;
if(nr !=0) continue factorize_loop;
nf++;
wtable[nf+1+4*n]=ntry;
nl=nq;
if(ntry==2 && nf !=1)
{
for(i=2; i<=nf; i++)
{
ib=nf-i+2;
wtable[ib+1+4*n]=wtable[ib+4*n];
}
wtable[2+4*n]=2;
}
} while(nl !=1);
break factorize_loop;
}
wtable[0+4*n]=n;
wtable[1+4*n]=nf;
argh=twopi /(double)n;
i=1;
l1=1;
for(k1=1; k1<=nf; k1++)
{
ip=(int)wtable[k1+1+4*n];
ld=0;
l2=l1*ip;
ido=n / l2;
idot=ido+ido+2;
ipm=ip-1;
for(j=1; j<=ipm; j++)
{
i1=i;
wtable[i-1+2*n]=1;
wtable[i+2*n]=0;
ld+=l1;
fi=0;
argld=ld*argh;
for(ii=4; ii<=idot; ii+=2)
{
i+=2;
fi+=1;
arg=fi*argld;
wtable[i-1+2*n]=Math.cos(arg);
wtable[i+2*n]=Math.sin(arg);
}
if(ip>5)
{
wtable[i1-1+2*n]=wtable[i-1+2*n];
wtable[i1+2*n]=wtable[i+2*n];
}
}
l1=l2;
}
}
/*---------------------------------------------------------
cffti: Initialization of Real forward FFT
--------------------------------------------------------*/
void cffti(int n, double wtable[])
{
if(n==1) return;
cffti1(n, wtable);
} /*cffti*/
}
... ...
package com.example.zhongqiyan.javasource.ca.uol.aig.fftpack;
/**
* FFT transform of a real periodic sequence.
* @author Baoshe Zhang
* @author Astronomical Instrument Group of University of Lethbridge.
*/
public class RealDoubleFFT extends RealDoubleFFT_Mixed
{
/**
* <em>norm_factor</em> can be used to normalize this FFT transform. This is because
* a call of forward transform (<em>ft</em>) followed by a call of backward transform
* (<em>bt</em>) will multiply the input sequence by <em>norm_factor</em>.
*/
public double norm_factor;
private double wavetable[];
private int ndim;
/**
* Construct a wavenumber table with size <em>n</em>.
* The sequences with the same size can share a wavenumber table. The prime
* factorization of <em>n</em> together with a tabulation of the trigonometric functions
* are computed and stored.
*
* @param n the size of a real data sequence. When <em>n</em> is a multiplication of small
* numbers (4, 2, 3, 5), this FFT transform is very efficient.
*/
public RealDoubleFFT(int n)
{
ndim = n;
norm_factor = n;
if(wavetable == null || wavetable.length !=(2*ndim+15))
{
wavetable = new double[2*ndim + 15];
}
rffti(ndim, wavetable);
}
/**
* Forward real FFT transform. It computes the discrete transform of a real data sequence.
*
* @param x an array which contains the sequence to be transformed. After FFT,
* <em>x</em> contains the transform coeffients used to construct <em>n</em> complex FFT coeffients.
* <br>
* The real part of the first complex FFT coeffients is <em>x</em>[0]; its imaginary part
* is 0. If <em>n</em> is even set <em>m</em> = <em>n</em>/2, if <em>n</em> is odd set
* <em>m</em> = <em>n</em>/2, then for
* <br>
* <em>k</em> = 1, ..., <em>m</em>-1 <br>
* the real part of <em>k</em>-th complex FFT coeffients is <em>x</em>[2*<em>k</em>-1];
* <br>
* the imaginary part of <em>k</em>-th complex FFT coeffients is <em>x</em>[2*<em>k</em>-2].
* <br>
* If <em>n</em> is even,
* the real of part of (<em>n</em>/2)-th complex FFT coeffients is <em>x</em>[<em>n</em>]; its imaginary part is 0.
* The remaining complex FFT coeffients can be obtained by the symmetry relation:
* the (<em>n</em>-<em>k</em>)-th complex FFT coeffient is the conjugate of <em>n</em>-th complex FFT coeffient.
*
*/
public void ft(double x[])
{
if(x.length != ndim)
throw new IllegalArgumentException("The length of data can not match that of the wavetable");
rfftf(ndim, x, wavetable);
}
/**
* Forward real FFT transform. It computes the discrete transform of a real data sequence.
*
* @param x an array which contains the sequence to be transformed. After FFT,
* <em>x</em> contains the transform coeffients used to construct <em>n</em> complex FFT coeffients.
* <br>
* @param y the first complex (<em>n</em>+1)/2 (when <em>n</em> is odd) or (<em>n</em>/2+1) (when
* <em>n</em> is even) FFT coeffients.
* The remaining complex FFT coeffients can be obtained by the symmetry relation:
* the (<em>n</em>-<em>k</em>)-th complex FFT coeffient is the conjugate of <em>n</em>-th complex FFT coeffient.
*
*/
public void ft(double x[], Complex1D y)
{
if(x.length != ndim)
throw new IllegalArgumentException("The length of data can not match that of the wavetable");
rfftf(ndim, x, wavetable);
if(ndim%2 == 0)
{
y.x = new double[ndim/2 + 1];
y.y = new double[ndim/2 + 1];
}
else
{
y.x = new double[(ndim+1)/2];
y.y = new double[(ndim+1)/2];
}
y.x[0] = x[0];
y.y[0] = 0.0D;
for(int i=1; i<(ndim+1)/2; i++)
{
y.x[i] = x[2*i-1];
y.y[i] = x[2*i];
}
if(ndim%2 == 0)
{
y.x[ndim/2] = x[ndim-1];
y.y[ndim/2] = 0.0D;
}
}
/**
* Backward real FFT transform. It is the unnormalized inverse transform of <em>ft</em>(double[]).
*
* @param x an array which contains the sequence to be transformed. After FFT,
* <em>x</em> contains the transform coeffients. Also see the comments of <em>ft</em>(double[])
* for the relation between <em>x</em> and complex FFT coeffients.
*/
public void bt(double x[])
{
if(x.length != ndim)
throw new IllegalArgumentException("The length of data can not match that of the wavetable");
rfftb(ndim, x, wavetable);
}
/**
* Backward real FFT transform. It is the unnormalized inverse transform of <em>ft</em>(Complex1D, double[]).
*
* @param x an array which contains the sequence to be transformed. When <em>n</em> is odd, it contains the first
* (<em>n</em>+1)/2 complex data; when <em>n</em> is even, it contains (<em>n</em>/2+1) complex data.
* @param y the real FFT coeffients.
* <br>
* Also see the comments of <em>ft</em>(double[]) for the relation
* between <em>x</em> and complex FFT coeffients.
*/
public void bt(Complex1D x, double y[])
{
if(ndim%2 == 0)
{
if(x.x.length != ndim/2+1)
throw new IllegalArgumentException("The length of data can not match that of the wavetable");
}
else
{
if(x.x.length != (ndim+1)/2)
throw new IllegalArgumentException("The length of data can not match that of the wavetable");
}
y[0] = x.x[0];
for(int i=1; i<(ndim+1)/2; i++)
{
y[2*i-1]=x.x[i];
y[2*i]=x.y[i];
}
if(ndim%2 == 0)
{
y[ndim-1]=x.x[ndim/2];
}
rfftb(ndim, y, wavetable);
}
}
... ...
package com.example.zhongqiyan.javasource.ca.uol.aig.fftpack;
/**
* cosine FFT transform of a real even sequence.
* @author Baoshe Zhang
* @author Astronomical Instrument Group of University of Lethbridge.
*/
public class RealDoubleFFT_Even extends RealDoubleFFT_Mixed
{
/**
* <em>norm_factor</em> can be used to normalize this FFT transform. This is because
* a call of forward transform (<em>ft</em>) followed by a call of backward transform
* (<em>bt</em>) will multiply the input sequence by <em>norm_factor</em>.
*/
public double norm_factor;
private double wavetable[];
private int ndim;
/**
* Construct a wavenumber table with size <em>n</em>.
* The sequences with the same size can share a wavenumber table. The prime
* factorization of <em>n</em> together with a tabulation of the trigonometric functions
* are computed and stored.
*
* @param n the size of a real data sequence. When (<em>n</em>-1) is a multiplication of small
* numbers (4, 2, 3, 5), this FFT transform is very efficient.
*/
public RealDoubleFFT_Even(int n)
{
ndim = n;
norm_factor = 2*(n-1);
if(wavetable == null || wavetable.length !=(3*ndim+15))
{
wavetable = new double[3*ndim + 15];
}
costi(ndim, wavetable);
}
/**
* Forward cosine FFT transform. It computes the discrete sine transform of
* an odd sequence.
*
* @param x an array which contains the sequence to be transformed. After FFT,
* <em>x</em> contains the transform coeffients.
*/
public void ft(double x[])
{
cost(ndim, x, wavetable);
}
/**
* Backward cosine FFT transform. It is the unnormalized inverse transform of <em>ft</em>.
*
* @param x an array which contains the sequence to be transformed. After FFT,
* <em>x</em> contains the transform coeffients.
*/
public void bt(double x[])
{
cost(ndim, x, wavetable);
}
/*-------------------------------------------------------------
cost: cosine FFT. Backward and forward cos-FFT are the same.
------------------------------------------------------------*/
void cost(int n, double x[], final double wtable[])
{
int modn, i, k;
double c1, t1, t2;
int kc;
double xi;
int nm1;
double x1h;
int ns2;
double tx2, x1p3, xim2;
nm1=n-1;
ns2=n / 2;
if(n-2<0) return;
else if(n==2)
{
x1h=x[0]+x[1];
x[1]=x[0]-x[1];
x[0]=x1h;
}
else if(n==3)
{
x1p3=x[0]+x[2];
tx2=x[1]+x[1];
x[1]=x[0]-x[2];
x[0]=x1p3+tx2;
x[2]=x1p3-tx2;
}
else
{
c1=x[0]-x[n-1];
x[0]+=x[n-1];
for(k=1; k<ns2; k++)
{
kc=nm1-k;
t1=x[k]+x[kc];
t2=x[k]-x[kc];
c1+=wtable[kc]*t2;
t2=wtable[k]*t2;
x[k]=t1-t2;
x[kc]=t1+t2;
}
modn=n%2;
if(modn !=0) x[ns2]+=x[ns2];
rfftf1(nm1, x, wtable, n);
xim2=x[1];
x[1]=c1;
for(i=3; i<n; i+=2)
{
xi=x[i];
x[i]=x[i-2]-x[i-1];
x[i-1]=xim2;
xim2=xi;
}
if(modn !=0) x[n-1]=xim2;
}
}
/*----------------------------------
costi: initialization of cos-FFT
---------------------------------*/
void costi(int n, double wtable[])
{
final double pi=Math.PI; //3.14159265358979;
int k, kc, ns2;
double dt;
if(n<=3) return;
ns2=n / 2;
dt=pi /(double)(n-1);
for(k=1; k<ns2; k++)
{
kc=n-k-1;
wtable[k]=2*Math.sin(k*dt);
wtable[kc]=2*Math.cos(k*dt);
}
rffti1(n-1, wtable, n);
}
}
... ...
package com.example.zhongqiyan.javasource.ca.uol.aig.fftpack;
/**
* cosine FFT transform with odd wave numbers.
* @author Baoshe Zhang
* @author Astronomical Instrument Group of University of Lethbridge.
*/
public class RealDoubleFFT_Even_Odd extends RealDoubleFFT_Mixed
{
/**
* <em>norm_factor</em> can be used to normalize this FFT transform. This is because
* a call of forward transform (<em>ft</em>) followed by a call of backward transform
* (<em>bt</em>) will multiply the input sequence by <em>norm_factor</em>.
*/
public double norm_factor;
protected double wavetable[];
protected int ndim;
/**
* Construct a wavenumber table with size <em>n</em>.
* The sequences with the same size can share a wavenumber table. The prime
* factorization of <em>n</em> together with a tabulation of the trigonometric functions
* are computed and stored.
*
* @param n the size of a real data sequence. When <em>n</em> is a multiplication of small
* numbers(4, 2, 3, 5), this FFT transform is very efficient.
*/
public RealDoubleFFT_Even_Odd(int n)
{
ndim = n;
norm_factor = 4*n;
if(wavetable == null || wavetable.length !=(3*ndim+15))
{
wavetable = new double[3*ndim + 15];
}
cosqi(ndim, wavetable);
}
/**
* Forward FFT transform of quarter wave data. It computes the coeffients in
* cosine series representation with only odd wave numbers.
*
* @param x an array which contains the sequence to be transformed. After FFT,
* <em>x</em> contains the transform coeffients.
*/
public void ft(double x[])
{
cosqf(ndim, x, wavetable);
}
/**
* Backward FFT transform of quarter wave data. It is the unnormalized inverse transform
* of <em>ft</em>.
*
* @param x an array which contains the sequence to be tranformed. After FFT, <em>x</em> contains
* the transform coeffients.
*/
public void bt(double x[])
{
cosqb(ndim, x, wavetable);
}
/*----------------------------------------------------------------------
cosqf1: further processing of forward cos-FFT with odd wave numbers.
----------------------------------------------------------------------*/
void cosqf1(int n, double x[], double wtable[])
{
int modn, i, k;
int kc, np2, ns2;
double xim1;
ns2=(n+1)/ 2;
np2=n+2;
for(k=1; k<ns2; k++)
{
kc=n-k;
wtable[k+n]=x[k]+x[kc];
wtable[kc+n]=x[k]-x[kc];
}
modn=n%2;
if(modn==0) wtable[ns2+n]=x[ns2]+x[ns2];
for(k=1; k<ns2; k++)
{
kc=n-k;
x[k]=wtable[k-1]*wtable[kc+n]+wtable[kc-1]*wtable[k+n];
x[kc]=wtable[k-1]*wtable[k+n]-wtable[kc-1]*wtable[kc+n];
}
if(modn==0) x[ns2]=wtable[ns2-1]*wtable[ns2+n];
rfftf1(n, x, wtable, n);
for(i=2; i<n; i+=2)
{
xim1=x[i-1]-x[i];
x[i]=x[i-1]+x[i];
x[i-1]=xim1;
}
}
/*----------------------------------------------------------------------
cosqb1: further processing of backward cos-FFT with odd wave numbers.
----------------------------------------------------------------------*/
void cosqb1(int n, double x[], double wtable[])
{
int modn, i, k;
int kc, ns2;
double xim1;
ns2=(n+1)/ 2;
for(i=2; i<n; i+=2)
{
xim1=x[i-1]+x[i];
x[i]-=x[i-1];
x[i-1]=xim1;
}
x[0]+=x[0];
modn=n%2;
if(modn==0) x[n-1]+=x[n-1];
rfftb1(n, x, wtable, n);
for(k=1; k<ns2; k++)
{
kc=n-k;
wtable[k+n]=wtable[k-1]*x[kc]+wtable[kc-1]*x[k];
wtable[kc+n]=wtable[k-1]*x[k]-wtable[kc-1]*x[kc];
}
if(modn==0) x[ns2]=wtable[ns2-1]*(x[ns2]+x[ns2]);
for(k=1; k<ns2; k++)
{
kc=n-k;
x[k]=wtable[k+n]+wtable[kc+n];
x[kc]=wtable[k+n]-wtable[kc+n];
}
x[0]+=x[0];
}
/*-----------------------------------------------
cosqf: forward cosine FFT with odd wave numbers.
----------------------------------------------*/
void cosqf(int n, double x[], final double wtable[])
{
final double sqrt2=1.4142135623731;
double tsqx;
if(n<2)
{
return;
}
else if(n==2)
{
tsqx=sqrt2*x[1];
x[1]=x[0]-tsqx;
x[0]+=tsqx;
}
else
{
cosqf1(n, x, wtable);
}
}
/*-----------------------------------------------
cosqb: backward cosine FFT with odd wave numbers.
----------------------------------------------*/
void cosqb(int n, double x[], double wtable[])
{
final double tsqrt2=2.82842712474619;
double x1;
if(n<2)
{
x[0]*=4;
}
else if(n==2)
{
x1=4*(x[0]+x[1]);
x[1]=tsqrt2*(x[0]-x[1]);
x[0]=x1;
}
else
{
cosqb1(n, x, wtable);
}
}
/*-----------------------------------------------------------
cosqi: initialization of cosine FFT with odd wave numbers.
----------------------------------------------------------*/
void cosqi(int n, double wtable[])
{
final double pih=Math.PI/2.0D; //1.57079632679491;
int k;
double dt;
dt=pih / (double)n;
for(k=0; k<n; k++) wtable[k]=Math.cos((k+1)*dt);
rffti1(n, wtable, n);
}
}
... ...
package com.example.zhongqiyan.javasource.ca.uol.aig.fftpack;
/**
* @author Baoshe Zhang
* @author Astronomical Instrument Group of University of Lethbridge.
*/
class RealDoubleFFT_Mixed
{
/*-------------------------------------------------
radf2: Real FFT's forward processing of factor 2
-------------------------------------------------*/
void radf2(int ido, int l1, final double cc[], double ch[],
final double wtable[], int offset)
{
int i, k, ic;
double ti2, tr2;
int iw1;
iw1 = offset;
for(k=0; k<l1; k++)
{
ch[2*k*ido]=cc[k*ido]+cc[(k+l1)*ido];
ch[(2*k+1)*ido+ido-1]=cc[k*ido]-cc[(k+l1)*ido];
}
if(ido<2) return;
if(ido !=2)
{
for(k=0; k<l1; k++)
{
for(i=2; i<ido; i+=2)
{
ic=ido-i;
tr2 = wtable[i-2+iw1]*cc[i-1+(k+l1)*ido]
+wtable[i-1+iw1]*cc[i+(k+l1)*ido];
ti2 = wtable[i-2+iw1]*cc[i+(k+l1)*ido]
-wtable[i-1+iw1]*cc[i-1+(k+l1)*ido];
ch[i+2*k*ido]=cc[i+k*ido]+ti2;
ch[ic+(2*k+1)*ido]=ti2-cc[i+k*ido];
ch[i-1+2*k*ido]=cc[i-1+k*ido]+tr2;
ch[ic-1+(2*k+1)*ido]=cc[i-1+k*ido]-tr2;
}
}
if(ido%2==1)return;
}
for(k=0; k<l1; k++)
{
ch[(2*k+1)*ido]=-cc[ido-1+(k+l1)*ido];
ch[ido-1+2*k*ido]=cc[ido-1+k*ido];
}
}
/*-------------------------------------------------
radb2: Real FFT's backward processing of factor 2
-------------------------------------------------*/
void radb2(int ido, int l1, final double cc[], double ch[],
final double wtable[], int offset)
{
int i, k, ic;
double ti2, tr2;
int iw1 = offset;
for(k=0; k<l1; k++)
{
ch[k*ido]=cc[2*k*ido]+cc[ido-1+(2*k+1)*ido];
ch[(k+l1)*ido]=cc[2*k*ido]-cc[ido-1+(2*k+1)*ido];
}
if(ido<2) return;
if(ido !=2)
{
for(k=0; k<l1;++k)
{
for(i=2; i<ido; i+=2)
{
ic=ido-i;
ch[i-1+k*ido]=cc[i-1+2*k*ido]+cc[ic-1+(2*k+1)*ido];
tr2=cc[i-1+2*k*ido]-cc[ic-1+(2*k+1)*ido];
ch[i+k*ido]=cc[i+2*k*ido]-cc[ic+(2*k+1)*ido];
ti2=cc[i+(2*k)*ido]+cc[ic+(2*k+1)*ido];
ch[i-1+(k+l1)*ido]=wtable[i-2+iw1]*tr2-wtable[i-1+iw1]*ti2;
ch[i+(k+l1)*ido]=wtable[i-2+iw1]*ti2+wtable[i-1+iw1]*tr2;
}
}
if(ido%2==1) return;
}
for(k=0; k<l1; k++)
{
ch[ido-1+k*ido]=2*cc[ido-1+2*k*ido];
ch[ido-1+(k+l1)*ido]=-2*cc[(2*k+1)*ido];
}
}
/*-------------------------------------------------
radf3: Real FFT's forward processing of factor 3
-------------------------------------------------*/
void radf3(int ido, int l1, final double cc[], double ch[],
final double wtable[], int offset)
{
final double taur=-0.5D;
final double taui=0.866025403784439D;
int i, k, ic;
double ci2, di2, di3, cr2, dr2, dr3, ti2, ti3, tr2, tr3;
int iw1, iw2;
iw1 = offset;
iw2 = iw1 + ido;
for(k=0; k<l1; k++)
{
cr2=cc[(k+l1)*ido]+cc[(k+2*l1)*ido];
ch[3*k*ido]=cc[k*ido]+cr2;
ch[(3*k+2)*ido]=taui*(cc[(k+l1*2)*ido]-cc[(k+l1)*ido]);
ch[ido-1+(3*k+1)*ido]=cc[k*ido]+taur*cr2;
}
if(ido==1) return;
for(k=0; k<l1; k++)
{
for(i=2; i<ido; i+=2)
{
ic=ido-i;
dr2 = wtable[i-2+iw1]*cc[i-1+(k+l1)*ido]
+wtable[i-1+iw1]*cc[i+(k+l1)*ido];
di2 = wtable[i-2+iw1]*cc[i+(k+l1)*ido]
-wtable[i-1+iw1]*cc[i-1+(k+l1)*ido];
dr3 = wtable[i-2+iw2]*cc[i-1+(k+l1*2)*ido]
+wtable[i-1+iw2]*cc[i+(k+l1*2)*ido];
di3 = wtable[i-2+iw2]*cc[i+(k+l1*2)*ido]
-wtable[i-1+iw2]*cc[i-1+(k+l1*2)*ido];
cr2 = dr2+dr3;
ci2 = di2+di3;
ch[i-1+3*k*ido]=cc[i-1+k*ido]+cr2;
ch[i+3*k*ido]=cc[i+k*ido]+ci2;
tr2=cc[i-1+k*ido]+taur*cr2;
ti2=cc[i+k*ido]+taur*ci2;
tr3=taui*(di2-di3);
ti3=taui*(dr3-dr2);
ch[i-1+(3*k+2)*ido]=tr2+tr3;
ch[ic-1+(3*k+1)*ido]=tr2-tr3;
ch[i+(3*k+2)*ido]=ti2+ti3;
ch[ic+(3*k+1)*ido]=ti3-ti2;
}
}
}
/*-------------------------------------------------
radb3: Real FFT's backward processing of factor 3
-------------------------------------------------*/
void radb3(int ido, int l1, final double cc[], double ch[],
final double wtable[], int offset)
{
final double taur=-0.5D;
final double taui=0.866025403784439D;
int i, k, ic;
double ci2, ci3, di2, di3, cr2, cr3, dr2, dr3, ti2, tr2;
int iw1, iw2;
iw1 = offset;
iw2 = iw1 + ido;
for(k=0; k<l1; k++)
{
tr2=2*cc[ido-1+(3*k+1)*ido];
cr2=cc[3*k*ido]+taur*tr2;
ch[k*ido]=cc[3*k*ido]+tr2;
ci3=2*taui*cc[(3*k+2)*ido];
ch[(k+l1)*ido]=cr2-ci3;
ch[(k+2*l1)*ido]=cr2+ci3;
}
if(ido==1) return;
for(k=0; k<l1; k++)
{
for(i=2; i<ido; i+=2)
{
ic=ido-i;
tr2=cc[i-1+(3*k+2)*ido]+cc[ic-1+(3*k+1)*ido];
cr2=cc[i-1+3*k*ido]+taur*tr2;
ch[i-1+k*ido]=cc[i-1+3*k*ido]+tr2;
ti2=cc[i+(3*k+2)*ido]-cc[ic+(3*k+1)*ido];
ci2=cc[i+3*k*ido]+taur*ti2;
ch[i+k*ido]=cc[i+3*k*ido]+ti2;
cr3=taui*(cc[i-1+(3*k+2)*ido]-cc[ic-1+(3*k+1)*ido]);
ci3=taui*(cc[i+(3*k+2)*ido]+cc[ic+(3*k+1)*ido]);
dr2=cr2-ci3;
dr3=cr2+ci3;
di2=ci2+cr3;
di3=ci2-cr3;
ch[i-1+(k+l1)*ido] = wtable[i-2+iw1]*dr2
-wtable[i-1+iw1]*di2;
ch[i+(k+l1)*ido] = wtable[i-2+iw1]*di2
+wtable[i-1+iw1]*dr2;
ch[i-1+(k+2*l1)*ido] = wtable[i-2+iw2]*dr3
-wtable[i-1+iw2]*di3;
ch[i+(k+2*l1)*ido] = wtable[i-2+iw2]*di3
+wtable[i-1+iw2]*dr3;
}
}
}
/*-------------------------------------------------
radf4: Real FFT's forward processing of factor 4
-------------------------------------------------*/
void radf4(int ido, int l1, final double cc[], double ch[],
final double wtable[], int offset)
{
final double hsqt2=0.7071067811865475D;
int i, k, ic;
double ci2, ci3, ci4, cr2, cr3, cr4, ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4;
int iw1, iw2, iw3;
iw1 = offset;
iw2 = offset + ido;
iw3 = iw2 + ido;
for(k=0; k<l1; k++)
{
tr1=cc[(k+l1)*ido]+cc[(k+3*l1)*ido];
tr2=cc[k*ido]+cc[(k+2*l1)*ido];
ch[4*k*ido]=tr1+tr2;
ch[ido-1+(4*k+3)*ido]=tr2-tr1;
ch[ido-1+(4*k+1)*ido]=cc[k*ido]-cc[(k+2*l1)*ido];
ch[(4*k+2)*ido]=cc[(k+3*l1)*ido]-cc[(k+l1)*ido];
}
if(ido<2) return;
if(ido !=2)
{
for(k=0; k<l1; k++)
{
for(i=2; i<ido; i+=2)
{
ic=ido-i;
cr2 = wtable[i-2+iw1]*cc[i-1+(k+l1)*ido]
+wtable[i-1+iw1]*cc[i+(k+l1)*ido];
ci2 = wtable[i-2+iw1]*cc[i+(k+l1)*ido]
-wtable[i-1+iw1]*cc[i-1+(k+l1)*ido];
cr3 = wtable[i-2+iw2]*cc[i-1+(k+2*l1)*ido]
+wtable[i-1+iw2]*cc[i+(k+2*l1)*ido];
ci3 = wtable[i-2+iw2]*cc[i+(k+2*l1)*ido]
-wtable[i-1+iw2]*cc[i-1+(k+2*l1)*ido];
cr4 = wtable[i-2+iw3]*cc[i-1+(k+3*l1)*ido]
+wtable[i-1+iw3]*cc[i+(k+3*l1)*ido];
ci4 = wtable[i-2+iw3]*cc[i+(k+3*l1)*ido]
-wtable[i-1+iw3]*cc[i-1+(k+3*l1)*ido];
tr1=cr2+cr4;
tr4=cr4-cr2;
ti1=ci2+ci4;
ti4=ci2-ci4;
ti2=cc[i+k*ido]+ci3;
ti3=cc[i+k*ido]-ci3;
tr2=cc[i-1+k*ido]+cr3;
tr3=cc[i-1+k*ido]-cr3;
ch[i-1+4*k*ido]=tr1+tr2;
ch[ic-1+(4*k+3)*ido]=tr2-tr1;
ch[i+4*k*ido]=ti1+ti2;
ch[ic+(4*k+3)*ido]=ti1-ti2;
ch[i-1+(4*k+2)*ido]=ti4+tr3;
ch[ic-1+(4*k+1)*ido]=tr3-ti4;
ch[i+(4*k+2)*ido]=tr4+ti3;
ch[ic+(4*k+1)*ido]=tr4-ti3;
}
}
if(ido%2==1) return;
}
for(k=0; k<l1; k++)
{
ti1=-hsqt2*(cc[ido-1+(k+l1)*ido]+cc[ido-1+(k+3*l1)*ido]);
tr1=hsqt2*(cc[ido-1+(k+l1)*ido]-cc[ido-1+(k+3*l1)*ido]);
ch[ido-1+4*k*ido]=tr1+cc[ido-1+k*ido];
ch[ido-1+(4*k+2)*ido]=cc[ido-1+k*ido]-tr1;
ch[(4*k+1)*ido]=ti1-cc[ido-1+(k+2*l1)*ido];
ch[(4*k+3)*ido]=ti1+cc[ido-1+(k+2*l1)*ido];
}
}
/*-------------------------------------------------
radb4: Real FFT's backward processing of factor 4
-------------------------------------------------*/
void radb4(int ido, int l1, final double cc[], double ch[],
final double wtable[], int offset)
{
final double sqrt2=1.414213562373095D;
int i, k, ic;
double ci2, ci3, ci4, cr2, cr3, cr4;
double ti1, ti2, ti3, ti4, tr1, tr2, tr3, tr4;
int iw1, iw2, iw3;
iw1 = offset;
iw2 = iw1 + ido;
iw3 = iw2 + ido;
for(k=0; k<l1; k++)
{
tr1=cc[4*k*ido]-cc[ido-1+(4*k+3)*ido];
tr2=cc[4*k*ido]+cc[ido-1+(4*k+3)*ido];
tr3=cc[ido-1+(4*k+1)*ido]+cc[ido-1+(4*k+1)*ido];
tr4=cc[(4*k+2)*ido]+cc[(4*k+2)*ido];
ch[k*ido]=tr2+tr3;
ch[(k+l1)*ido]=tr1-tr4;
ch[(k+2*l1)*ido]=tr2-tr3;
ch[(k+3*l1)*ido]=tr1+tr4;
}
if(ido<2) return;
if(ido !=2)
{
for(k=0; k<l1;++k)
{
for(i=2; i<ido; i+=2)
{
ic=ido-i;
ti1=cc[i+4*k*ido]+cc[ic+(4*k+3)*ido];
ti2=cc[i+4*k*ido]-cc[ic+(4*k+3)*ido];
ti3=cc[i+(4*k+2)*ido]-cc[ic+(4*k+1)*ido];
tr4=cc[i+(4*k+2)*ido]+cc[ic+(4*k+1)*ido];
tr1=cc[i-1+4*k*ido]-cc[ic-1+(4*k+3)*ido];
tr2=cc[i-1+4*k*ido]+cc[ic-1+(4*k+3)*ido];
ti4=cc[i-1+(4*k+2)*ido]-cc[ic-1+(4*k+1)*ido];
tr3=cc[i-1+(4*k+2)*ido]+cc[ic-1+(4*k+1)*ido];
ch[i-1+k*ido]=tr2+tr3;
cr3=tr2-tr3;
ch[i+k*ido]=ti2+ti3;
ci3=ti2-ti3;
cr2=tr1-tr4;
cr4=tr1+tr4;
ci2=ti1+ti4;
ci4=ti1-ti4;
ch[i-1+(k+l1)*ido] = wtable[i-2+iw1]*cr2
-wtable[i-1+iw1]*ci2;
ch[i+(k+l1)*ido] = wtable[i-2+iw1]*ci2
+wtable[i-1+iw1]*cr2;
ch[i-1+(k+2*l1)*ido] = wtable[i-2+iw2]*cr3
-wtable[i-1+iw2]*ci3;
ch[i+(k+2*l1)*ido] = wtable[i-2+iw2]*ci3
+wtable[i-1+iw2]*cr3;
ch[i-1+(k+3*l1)*ido] = wtable[i-2+iw3]*cr4
-wtable[i-1+iw3]*ci4;
ch[i+(k+3*l1)*ido] = wtable[i-2+iw3]*ci4
+wtable[i-1+iw3]*cr4;
}
}
if(ido%2==1) return;
}
for(k=0; k<l1; k++)
{
ti1=cc[(4*k+1)*ido]+cc[(4*k+3)*ido];
ti2=cc[(4*k+3)*ido]-cc[(4*k+1)*ido];
tr1=cc[ido-1+4*k*ido]-cc[ido-1+(4*k+2)*ido];
tr2=cc[ido-1+4*k*ido]+cc[ido-1+(4*k+2)*ido];
ch[ido-1+k*ido]=tr2+tr2;
ch[ido-1+(k+l1)*ido]=sqrt2*(tr1-ti1);
ch[ido-1+(k+2*l1)*ido]=ti2+ti2;
ch[ido-1+(k+3*l1)*ido]=-sqrt2*(tr1+ti1);
}
}
/*-------------------------------------------------
radf5: Real FFT's forward processing of factor 5
-------------------------------------------------*/
void radf5(int ido, int l1, final double cc[], double ch[],
final double wtable[], int offset)
{
final double tr11=0.309016994374947D;
final double ti11=0.951056516295154D;
final double tr12=-0.809016994374947D;
final double ti12=0.587785252292473D;
int i, k, ic;
double ci2, di2, ci4, ci5, di3, di4, di5, ci3, cr2, cr3, dr2, dr3,
dr4, dr5, cr5, cr4, ti2, ti3, ti5, ti4, tr2, tr3, tr4, tr5;
int iw1, iw2, iw3, iw4;
iw1 = offset;
iw2 = iw1 + ido;
iw3 = iw2 + ido;
iw4 = iw3 + ido;
for(k=0; k<l1; k++)
{
cr2=cc[(k+4*l1)*ido]+cc[(k+l1)*ido];
ci5=cc[(k+4*l1)*ido]-cc[(k+l1)*ido];
cr3=cc[(k+3*l1)*ido]+cc[(k+2*l1)*ido];
ci4=cc[(k+3*l1)*ido]-cc[(k+2*l1)*ido];
ch[5*k*ido]=cc[k*ido]+cr2+cr3;
ch[ido-1+(5*k+1)*ido]=cc[k*ido]+tr11*cr2+tr12*cr3;
ch[(5*k+2)*ido]=ti11*ci5+ti12*ci4;
ch[ido-1+(5*k+3)*ido]=cc[k*ido]+tr12*cr2+tr11*cr3;
ch[(5*k+4)*ido]=ti12*ci5-ti11*ci4;
}
if(ido==1) return;
for(k=0; k<l1;++k)
{
for(i=2; i<ido; i+=2)
{
ic=ido-i;
dr2 = wtable[i-2+iw1]*cc[i-1+(k+l1)*ido]
+wtable[i-1+iw1]*cc[i+(k+l1)*ido];
di2 = wtable[i-2+iw1]*cc[i+(k+l1)*ido]
-wtable[i-1+iw1]*cc[i-1+(k+l1)*ido];
dr3 = wtable[i-2+iw2]*cc[i-1+(k+2*l1)*ido]
+wtable[i-1+iw2]*cc[i+(k+2*l1)*ido];
di3 = wtable[i-2+iw2]*cc[i+(k+2*l1)*ido]
-wtable[i-1+iw2]*cc[i-1+(k+2*l1)*ido];
dr4 = wtable[i-2+iw3]*cc[i-1+(k+3*l1)*ido]
+wtable[i-1+iw3]*cc[i+(k+3*l1)*ido];
di4 = wtable[i-2+iw3]*cc[i+(k+3*l1)*ido]
-wtable[i-1+iw3]*cc[i-1+(k+3*l1)*ido];
dr5 = wtable[i-2+iw4]*cc[i-1+(k+4*l1)*ido]
+wtable[i-1+iw4]*cc[i+(k+4*l1)*ido];
di5 = wtable[i-2+iw4]*cc[i+(k+4*l1)*ido]
-wtable[i-1+iw4]*cc[i-1+(k+4*l1)*ido];
cr2=dr2+dr5;
ci5=dr5-dr2;
cr5=di2-di5;
ci2=di2+di5;
cr3=dr3+dr4;
ci4=dr4-dr3;
cr4=di3-di4;
ci3=di3+di4;
ch[i-1+5*k*ido]=cc[i-1+k*ido]+cr2+cr3;
ch[i+5*k*ido]=cc[i+k*ido]+ci2+ci3;
tr2=cc[i-1+k*ido]+tr11*cr2+tr12*cr3;
ti2=cc[i+k*ido]+tr11*ci2+tr12*ci3;
tr3=cc[i-1+k*ido]+tr12*cr2+tr11*cr3;
ti3=cc[i+k*ido]+tr12*ci2+tr11*ci3;
tr5=ti11*cr5+ti12*cr4;
ti5=ti11*ci5+ti12*ci4;
tr4=ti12*cr5-ti11*cr4;
ti4=ti12*ci5-ti11*ci4;
ch[i-1+(5*k+2)*ido]=tr2+tr5;
ch[ic-1+(5*k+1)*ido]=tr2-tr5;
ch[i+(5*k+2)*ido]=ti2+ti5;
ch[ic+(5*k+1)*ido]=ti5-ti2;
ch[i-1+(5*k+4)*ido]=tr3+tr4;
ch[ic-1+(5*k+3)*ido]=tr3-tr4;
ch[i+(5*k+4)*ido]=ti3+ti4;
ch[ic+(5*k+3)*ido]=ti4-ti3;
}
}
}
/*-------------------------------------------------
radb5: Real FFT's backward processing of factor 5
-------------------------------------------------*/
void radb5(int ido, int l1, final double cc[], double ch[],
final double wtable[], int offset)
{
final double tr11=0.309016994374947D;
final double ti11=0.951056516295154D;
final double tr12=-0.809016994374947D;
final double ti12=0.587785252292473D;
int i, k, ic;
double ci2, ci3, ci4, ci5, di3, di4, di5, di2, cr2, cr3, cr5, cr4,
ti2, ti3, ti4, ti5, dr3, dr4, dr5, dr2, tr2, tr3, tr4, tr5;
int iw1, iw2, iw3, iw4;
iw1 = offset;
iw2 = iw1 + ido;
iw3 = iw2 + ido;
iw4 = iw3 + ido;
for(k=0; k<l1; k++)
{
ti5=2*cc[(5*k+2)*ido];
ti4=2*cc[(5*k+4)*ido];
tr2=2*cc[ido-1+(5*k+1)*ido];
tr3=2*cc[ido-1+(5*k+3)*ido];
ch[k*ido]=cc[5*k*ido]+tr2+tr3;
cr2=cc[5*k*ido]+tr11*tr2+tr12*tr3;
cr3=cc[5*k*ido]+tr12*tr2+tr11*tr3;
ci5=ti11*ti5+ti12*ti4;
ci4=ti12*ti5-ti11*ti4;
ch[(k+l1)*ido]=cr2-ci5;
ch[(k+2*l1)*ido]=cr3-ci4;
ch[(k+3*l1)*ido]=cr3+ci4;
ch[(k+4*l1)*ido]=cr2+ci5;
}
if(ido==1) return;
for(k=0; k<l1;++k)
{
for(i=2; i<ido; i+=2)
{
ic=ido-i;
ti5=cc[i+(5*k+2)*ido]+cc[ic+(5*k+1)*ido];
ti2=cc[i+(5*k+2)*ido]-cc[ic+(5*k+1)*ido];
ti4=cc[i+(5*k+4)*ido]+cc[ic+(5*k+3)*ido];
ti3=cc[i+(5*k+4)*ido]-cc[ic+(5*k+3)*ido];
tr5=cc[i-1+(5*k+2)*ido]-cc[ic-1+(5*k+1)*ido];
tr2=cc[i-1+(5*k+2)*ido]+cc[ic-1+(5*k+1)*ido];
tr4=cc[i-1+(5*k+4)*ido]-cc[ic-1+(5*k+3)*ido];
tr3=cc[i-1+(5*k+4)*ido]+cc[ic-1+(5*k+3)*ido];
ch[i-1+k*ido]=cc[i-1+5*k*ido]+tr2+tr3;
ch[i+k*ido]=cc[i+5*k*ido]+ti2+ti3;
cr2=cc[i-1+5*k*ido]+tr11*tr2+tr12*tr3;
ci2=cc[i+5*k*ido]+tr11*ti2+tr12*ti3;
cr3=cc[i-1+5*k*ido]+tr12*tr2+tr11*tr3;
ci3=cc[i+5*k*ido]+tr12*ti2+tr11*ti3;
cr5=ti11*tr5+ti12*tr4;
ci5=ti11*ti5+ti12*ti4;
cr4=ti12*tr5-ti11*tr4;
ci4=ti12*ti5-ti11*ti4;
dr3=cr3-ci4;
dr4=cr3+ci4;
di3=ci3+cr4;
di4=ci3-cr4;
dr5=cr2+ci5;
dr2=cr2-ci5;
di5=ci2-cr5;
di2=ci2+cr5;
ch[i-1+(k+l1)*ido] = wtable[i-2+iw1]*dr2
-wtable[i-1+iw1]*di2;
ch[i+(k+l1)*ido] = wtable[i-2+iw1]*di2
+wtable[i-1+iw1]*dr2;
ch[i-1+(k+2*l1)*ido] = wtable[i-2+iw2]*dr3
-wtable[i-1+iw2]*di3;
ch[i+(k+2*l1)*ido] = wtable[i-2+iw2]*di3
+wtable[i-1+iw2]*dr3;
ch[i-1+(k+3*l1)*ido] = wtable[i-2+iw3]*dr4
-wtable[i-1+iw3]*di4;
ch[i+(k+3*l1)*ido] = wtable[i-2+iw3]*di4
+wtable[i-1+iw3]*dr4;
ch[i-1+(k+4*l1)*ido] = wtable[i-2+iw4]*dr5
-wtable[i-1+iw4]*di5;
ch[i+(k+4*l1)*ido] = wtable[i-2+iw4]*di5
+wtable[i-1+iw4]*dr5;
}
}
}
/*---------------------------------------------------------
radfg: Real FFT's forward processing of general factor
--------------------------------------------------------*/
void radfg(int ido, int ip, int l1, int idl1, double cc[],
double c1[], double c2[], double ch[], double ch2[],
final double wtable[], int offset)
{
final double twopi=2.0D*Math.PI; //6.28318530717959;
int idij, ipph, i, j, k, l, j2, ic, jc, lc, ik, is, nbd;
double dc2, ai1, ai2, ar1, ar2, ds2, dcp, arg, dsp, ar1h, ar2h;
int iw1 = offset;
arg=twopi / (double)ip;
dcp=Math.cos(arg);
dsp=Math.sin(arg);
ipph=(ip+1)/ 2;
nbd=(ido-1)/ 2;
if(ido !=1)
{
for(ik=0; ik<idl1; ik++) ch2[ik]=c2[ik];
for(j=1; j<ip; j++)
for(k=0; k<l1; k++)
ch[(k+j*l1)*ido]=c1[(k+j*l1)*ido];
if(nbd<=l1)
{
is=-ido;
for(j=1; j<ip; j++)
{
is+=ido;
idij=is-1;
for(i=2; i<ido; i+=2)
{
idij+=2;
for(k=0; k<l1; k++)
{
ch[i-1+(k+j*l1)*ido]=
wtable[idij-1+iw1]*c1[i-1+(k+j*l1)*ido]
+wtable[idij+iw1]*c1[i+(k+j*l1)*ido];
ch[i+(k+j*l1)*ido]=
wtable[idij-1+iw1]*c1[i+(k+j*l1)*ido]
-wtable[idij+iw1]*c1[i-1+(k+j*l1)*ido];
}
}
}
}
else
{
is=-ido;
for(j=1; j<ip; j++)
{
is+=ido;
for(k=0; k<l1; k++)
{
idij=is-1;
for(i=2; i<ido; i+=2)
{
idij+=2;
ch[i-1+(k+j*l1)*ido]=
wtable[idij-1+iw1]*c1[i-1+(k+j*l1)*ido]
+wtable[idij+iw1]*c1[i+(k+j*l1)*ido];
ch[i+(k+j*l1)*ido]=
wtable[idij-1+iw1]*c1[i+(k+j*l1)*ido]
-wtable[idij+iw1]*c1[i-1+(k+j*l1)*ido];
}
}
}
}
if(nbd>=l1)
{
for(j=1; j<ipph; j++)
{
jc=ip-j;
for(k=0; k<l1; k++)
{
for(i=2; i<ido; i+=2)
{
c1[i-1+(k+j*l1)*ido]=ch[i-1+(k+j*l1)*ido]+ch[i-1+(k+jc*l1)*ido];
c1[i-1+(k+jc*l1)*ido]=ch[i+(k+j*l1)*ido]-ch[i+(k+jc*l1)*ido];
c1[i+(k+j*l1)*ido]=ch[i+(k+j*l1)*ido]+ch[i+(k+jc*l1)*ido];
c1[i+(k+jc*l1)*ido]=ch[i-1+(k+jc*l1)*ido]-ch[i-1+(k+j*l1)*ido];
}
}
}
}
else
{
for(j=1; j<ipph; j++)
{
jc=ip-j;
for(i=2; i<ido; i+=2)
{
for(k=0; k<l1; k++)
{
c1[i-1+(k+j*l1)*ido]=
ch[i-1+(k+j*l1)*ido]+ch[i-1+(k+jc*l1)*ido];
c1[i-1+(k+jc*l1)*ido]=ch[i+(k+j*l1)*ido]-ch[i+(k+jc*l1)*ido];
c1[i+(k+j*l1)*ido]=ch[i+(k+j*l1)*ido]+ch[i+(k+jc*l1)*ido];
c1[i+(k+jc*l1)*ido]=ch[i-1+(k+jc*l1)*ido]-ch[i-1+(k+j*l1)*ido];
}
}
}
}
}
else
{
for(ik=0; ik<idl1; ik++) c2[ik]=ch2[ik];
}
for(j=1; j<ipph; j++)
{
jc=ip-j;
for(k=0; k<l1; k++)
{
c1[(k+j*l1)*ido]=ch[(k+j*l1)*ido]+ch[(k+jc*l1)*ido];
c1[(k+jc*l1)*ido]=ch[(k+jc*l1)*ido]-ch[(k+j*l1)*ido];
}
}
ar1=1;
ai1=0;
for(l=1; l<ipph; l++)
{
lc=ip-l;
ar1h=dcp*ar1-dsp*ai1;
ai1=dcp*ai1+dsp*ar1;
ar1=ar1h;
for(ik=0; ik<idl1; ik++)
{
ch2[ik+l*idl1]=c2[ik]+ar1*c2[ik+idl1];
ch2[ik+lc*idl1]=ai1*c2[ik+(ip-1)*idl1];
}
dc2=ar1;
ds2=ai1;
ar2=ar1;
ai2=ai1;
for(j=2; j<ipph; j++)
{
jc=ip-j;
ar2h=dc2*ar2-ds2*ai2;
ai2=dc2*ai2+ds2*ar2;
ar2=ar2h;
for(ik=0; ik<idl1; ik++)
{
ch2[ik+l*idl1]+=ar2*c2[ik+j*idl1];
ch2[ik+lc*idl1]+=ai2*c2[ik+jc*idl1];
}
}
}
for(j=1; j<ipph; j++)
for(ik=0; ik<idl1; ik++)
ch2[ik]+=c2[ik+j*idl1];
if(ido>=l1)
{
for(k=0; k<l1; k++)
{
for(i=0; i<ido; i++)
{
cc[i+k*ip*ido]=ch[i+k*ido];
}
}
}
else
{
for(i=0; i<ido; i++)
{
for(k=0; k<l1; k++)
{
cc[i+k*ip*ido]=ch[i+k*ido];
}
}
}
for(j=1; j<ipph; j++)
{
jc=ip-j;
j2=2*j;
for(k=0; k<l1; k++)
{
cc[ido-1+(j2-1+k*ip)*ido]=ch[(k+j*l1)*ido];
cc[(j2+k*ip)*ido]=ch[(k+jc*l1)*ido];
}
}
if(ido==1) return;
if(nbd>=l1)
{
for(j=1; j<ipph; j++)
{
jc=ip-j;
j2=2*j;
for(k=0; k<l1; k++)
{
for(i=2; i<ido; i+=2)
{
ic=ido-i;
cc[i-1+(j2+k*ip)*ido]=ch[i-1+(k+j*l1)*ido]+ch[i-1+(k+jc*l1)*ido];
cc[ic-1+(j2-1+k*ip)*ido]=ch[i-1+(k+j*l1)*ido]-ch[i-1+(k+jc*l1)*ido];
cc[i+(j2+k*ip)*ido]=ch[i+(k+j*l1)*ido]+ch[i+(k+jc*l1)*ido];
cc[ic+(j2-1+k*ip)*ido]=ch[i+(k+jc*l1)*ido]-ch[i+(k+j*l1)*ido];
}
}
}
}
else
{
for(j=1; j<ipph; j++)
{
jc=ip-j;
j2=2*j;
for(i=2; i<ido; i+=2)
{
ic=ido-i;
for(k=0; k<l1; k++)
{
cc[i-1+(j2+k*ip)*ido]=ch[i-1+(k+j*l1)*ido]+ch[i-1+(k+jc*l1)*ido];
cc[ic-1+(j2-1+k*ip)*ido]=ch[i-1+(k+j*l1)*ido]-ch[i-1+(k+jc*l1)*ido];
cc[i+(j2+k*ip)*ido]=ch[i+(k+j*l1)*ido]+ch[i+(k+jc*l1)*ido];
cc[ic+(j2-1+k*ip)*ido]=ch[i+(k+jc*l1)*ido]-ch[i+(k+j*l1)*ido];
}
}
}
}
}
/*---------------------------------------------------------
radbg: Real FFT's backward processing of general factor
--------------------------------------------------------*/
void radbg(int ido, int ip, int l1, int idl1, double cc[], double c1[],
double c2[], double ch[], double ch2[], final double wtable[], int offset)
{
final double twopi=2.0D*Math.PI; //6.28318530717959;
int idij, ipph, i, j, k, l, j2, ic, jc, lc, ik, is;
double dc2, ai1, ai2, ar1, ar2, ds2;
int nbd;
double dcp, arg, dsp, ar1h, ar2h;
int iw1 = offset;
arg=twopi / (double)ip;
dcp=Math.cos(arg);
dsp=Math.sin(arg);
nbd=(ido-1)/ 2;
ipph=(ip+1)/ 2;
if(ido>=l1)
{
for(k=0; k<l1; k++)
{
for(i=0; i<ido; i++)
{
ch[i+k*ido]=cc[i+k*ip*ido];
}
}
}
else
{
for(i=0; i<ido; i++)
{
for(k=0; k<l1; k++)
{
ch[i+k*ido]=cc[i+k*ip*ido];
}
}
}
for(j=1; j<ipph; j++)
{
jc=ip-j;
j2=2*j;
for(k=0; k<l1; k++)
{
ch[(k+j*l1)*ido]=cc[ido-1+(j2-1+k*ip)*ido]+cc[ido-1+(j2-1+k*ip)*ido];
ch[(k+jc*l1)*ido]=cc[(j2+k*ip)*ido]+cc[(j2+k*ip)*ido];
}
}
if(ido !=1)
{
if(nbd>=l1)
{
for(j=1; j<ipph; j++)
{
jc=ip-j;
for(k=0; k<l1; k++)
{
for(i=2; i<ido; i+=2)
{
ic=ido-i;
ch[i-1+(k+j*l1)*ido]=cc[i-1+(2*j+k*ip)*ido]+cc[ic-1+(2*j-1+k*ip)*ido];
ch[i-1+(k+jc*l1)*ido]=cc[i-1+(2*j+k*ip)*ido]-cc[ic-1+(2*j-1+k*ip)*ido];
ch[i+(k+j*l1)*ido]=cc[i+(2*j+k*ip)*ido]-cc[ic+(2*j-1+k*ip)*ido];
ch[i+(k+jc*l1)*ido]=cc[i+(2*j+k*ip)*ido]+cc[ic+(2*j-1+k*ip)*ido];
}
}
}
}
else
{
for(j=1; j<ipph; j++)
{
jc=ip-j;
for(i=2; i<ido; i+=2)
{
ic=ido-i;
for(k=0; k<l1; k++)
{
ch[i-1+(k+j*l1)*ido]=cc[i-1+(2*j+k*ip)*ido]+cc[ic-1+(2*j-1+k*ip)*ido];
ch[i-1+(k+jc*l1)*ido]=cc[i-1+(2*j+k*ip)*ido]-cc[ic-1+(2*j-1+k*ip)*ido];
ch[i+(k+j*l1)*ido]=cc[i+(2*j+k*ip)*ido]-cc[ic+(2*j-1+k*ip)*ido];
ch[i+(k+jc*l1)*ido]=cc[i+(2*j+k*ip)*ido]+cc[ic+(2*j-1+k*ip)*ido];
}
}
}
}
}
ar1=1;
ai1=0;
for(l=1; l<ipph; l++)
{
lc=ip-l;
ar1h=dcp*ar1-dsp*ai1;
ai1=dcp*ai1+dsp*ar1;
ar1=ar1h;
for(ik=0; ik<idl1; ik++)
{
c2[ik+l*idl1]=ch2[ik]+ar1*ch2[ik+idl1];
c2[ik+lc*idl1]=ai1*ch2[ik+(ip-1)*idl1];
}
dc2=ar1;
ds2=ai1;
ar2=ar1;
ai2=ai1;
for(j=2; j<ipph; j++)
{
jc=ip-j;
ar2h=dc2*ar2-ds2*ai2;
ai2=dc2*ai2+ds2*ar2;
ar2=ar2h;
for(ik=0; ik<idl1; ik++)
{
c2[ik+l*idl1]+=ar2*ch2[ik+j*idl1];
c2[ik+lc*idl1]+=ai2*ch2[ik+jc*idl1];
}
}
}
for(j=1; j<ipph; j++)
{
for(ik=0; ik<idl1; ik++)
{
ch2[ik]+=ch2[ik+j*idl1];
}
}
for(j=1; j<ipph; j++)
{
jc=ip-j;
for(k=0; k<l1; k++)
{
ch[(k+j*l1)*ido]=c1[(k+j*l1)*ido]-c1[(k+jc*l1)*ido];
ch[(k+jc*l1)*ido]=c1[(k+j*l1)*ido]+c1[(k+jc*l1)*ido];
}
}
if(ido==1) return;
if(nbd>=l1)
{
for(j=1; j<ipph; j++)
{
jc=ip-j;
for(k=0; k<l1; k++)
{
for(i=2; i<ido; i+=2)
{
ch[i-1+(k+j*l1)*ido]=c1[i-1+(k+j*l1)*ido]-c1[i+(k+jc*l1)*ido];
ch[i-1+(k+jc*l1)*ido]=c1[i-1+(k+j*l1)*ido]+c1[i+(k+jc*l1)*ido];
ch[i+(k+j*l1)*ido]=c1[i+(k+j*l1)*ido]+c1[i-1+(k+jc*l1)*ido];
ch[i+(k+jc*l1)*ido]=c1[i+(k+j*l1)*ido]-c1[i-1+(k+jc*l1)*ido];
}
}
}
}
else
{
for(j=1; j<ipph; j++)
{
jc=ip-j;
for(i=2; i<ido; i+=2)
{
for(k=0; k<l1; k++)
{
ch[i-1+(k+j*l1)*ido]=c1[i-1+(k+j*l1)*ido]-c1[i+(k+jc*l1)*ido];
ch[i-1+(k+jc*l1)*ido]=c1[i-1+(k+j*l1)*ido]+c1[i+(k+jc*l1)*ido];
ch[i+(k+j*l1)*ido]=c1[i+(k+j*l1)*ido]+c1[i-1+(k+jc*l1)*ido];
ch[i+(k+jc*l1)*ido]=c1[i+(k+j*l1)*ido]-c1[i-1+(k+jc*l1)*ido];
}
}
}
}
for(ik=0; ik<idl1; ik++) c2[ik]=ch2[ik];
for(j=1; j<ip; j++)
for(k=0; k<l1; k++)
c1[(k+j*l1)*ido]=ch[(k+j*l1)*ido];
if(nbd<=l1)
{
is=-ido;
for(j=1; j<ip; j++)
{
is+=ido;
idij=is-1;
for(i=2; i<ido; i+=2)
{
idij+=2;
for(k=0; k<l1; k++)
{
c1[i-1+(k+j*l1)*ido] = wtable[idij-1+iw1]*ch[i-1+(k+j*l1)*ido]
-wtable[idij+iw1]*ch[i+(k+j*l1)*ido];
c1[i+(k+j*l1)*ido] = wtable[idij-1+iw1]*ch[i+(k+j*l1)*ido]
+wtable[idij+iw1]*ch[i-1+(k+j*l1)*ido];
}
}
}
}
else
{
is=-ido;
for(j=1; j<ip; j++)
{
is+=ido;
for(k=0; k<l1; k++)
{
idij=is-1;
for(i=2; i<ido; i+=2)
{
idij+=2;
c1[i-1+(k+j*l1)*ido] = wtable[idij-1+iw1]*ch[i-1+(k+j*l1)*ido]
-wtable[idij+iw1]*ch[i+(k+j*l1)*ido];
c1[i+(k+j*l1)*ido] = wtable[idij-1+iw1]*ch[i+(k+j*l1)*ido]
+wtable[idij+iw1]*ch[i-1+(k+j*l1)*ido];
}
}
}
}
}
/*---------------------------------------------------------
rfftf1: further processing of Real forward FFT
--------------------------------------------------------*/
void rfftf1(int n, double c[], final double wtable[], int offset)
{
int i;
int k1, l1, l2, na, kh, nf, ip, iw, ido, idl1;
double[] ch = new double[n];
System.arraycopy(wtable, offset, ch, 0, n);
nf=(int)wtable[1+2*n+offset];
na=1;
l2=n;
iw=n-1+n+offset;
for(k1=1; k1<=nf;++k1)
{
kh=nf-k1;
ip=(int)wtable[kh+2+2*n+offset];
l1=l2 / ip;
ido=n / l2;
idl1=ido*l1;
iw-=(ip-1)*ido;
na=1-na;
if(ip==4)
{
if(na==0)
{
radf4(ido, l1, c, ch, wtable, iw);
}
else
{
radf4(ido, l1, ch, c, wtable, iw);
}
}
else if(ip==2)
{
if(na==0)
{
radf2(ido, l1, c, ch, wtable, iw);
}
else
{
radf2(ido, l1, ch, c, wtable, iw);
}
}
else if(ip==3)
{
if(na==0)
{
radf3(ido, l1, c, ch, wtable, iw);
}
else
{
radf3(ido, l1, ch, c, wtable, iw);
}
}
else if(ip==5)
{
if(na==0)
{
radf5(ido, l1, c, ch, wtable, iw);
}
else
{
radf5(ido, l1, ch, c, wtable, iw);
}
}
else
{
if(ido==1) na=1-na;
if(na==0)
{
radfg(ido, ip, l1, idl1, c, c, c, ch, ch, wtable, iw);
na=1;
}
else
{
radfg(ido, ip, l1, idl1, ch, ch, ch, c, c, wtable, iw);
na=0;
}
}
l2=l1;
}
if(na==1) return;
for(i=0; i<n; i++) c[i]=ch[i];
}
/*---------------------------------------------------------
rfftb1: further processing of Real backward FFT
--------------------------------------------------------*/
void rfftb1(int n, double c[], final double wtable[], int offset)
{
int i;
int k1, l1, l2, na, nf, ip, iw, ido, idl1;
double[] ch = new double[n];
System.arraycopy(wtable, offset, ch, 0, n);
nf=(int)wtable[1+2*n+offset];
na=0;
l1=1;
iw=n+offset;
for(k1=1; k1<=nf; k1++)
{
ip=(int)wtable[k1+1+2*n+offset];
l2=ip*l1;
ido=n / l2;
idl1=ido*l1;
if(ip==4)
{
if(na==0)
{
radb4(ido, l1, c, ch, wtable, iw);
}
else
{
radb4(ido, l1, ch, c, wtable, iw);
}
na=1-na;
}
else if(ip==2)
{
if(na==0)
{
radb2(ido, l1, c, ch, wtable, iw);
}
else
{
radb2(ido, l1, ch, c, wtable, iw);
}
na=1-na;
}
else if(ip==3)
{
if(na==0)
{
radb3(ido, l1, c, ch, wtable, iw);
}
else
{
radb3(ido, l1, ch, c, wtable, iw);
}
na=1-na;
}
else if(ip==5)
{
if(na==0)
{
radb5(ido, l1, c, ch, wtable, iw);
}
else
{
radb5(ido, l1, ch, c, wtable, iw);
}
na=1-na;
}
else
{
if(na==0)
{
radbg(ido, ip, l1, idl1, c, c, c, ch, ch, wtable, iw);
}
else
{
radbg(ido, ip, l1, idl1, ch, ch, ch, c, c, wtable, iw);
}
if(ido==1) na=1-na;
}
l1=l2;
iw+=(ip-1)*ido;
}
if(na==0) return;
for(i=0; i<n; i++) c[i]=ch[i];
}
/*---------------------------------------------------------
rfftf: Real forward FFT
--------------------------------------------------------*/
void rfftf(int n, double r[], double wtable[])
{
if(n==1) return;
rfftf1(n, r, wtable, 0);
} /*rfftf*/
/*---------------------------------------------------------
rfftf: Real backward FFT
--------------------------------------------------------*/
void rfftb(int n, double r[], double wtable[])
{
if(n==1) return;
rfftb1(n, r, wtable, 0);
} /*rfftb*/
/*---------------------------------------------------------
rffti1: further initialization of Real FFT
--------------------------------------------------------*/
void rffti1(int n, double wtable[], int offset)
{
final int[] ntryh= new int[] {4, 2, 3, 5};
final double twopi=2.0D*Math.PI;
double argh;
int ntry=0, i, j;
double argld;
int k1, l1, l2, ib;
double fi;
int ld, ii, nf, ip, nl, is, nq, nr;
double arg;
int ido, ipm;
int nfm1;
nl=n;
nf=0;
j=0;
factorize_loop:
while(true)
{
++j;
if(j<=4)
ntry=ntryh[j-1];
else
ntry+=2;
do
{
nq=nl / ntry;
nr=nl-ntry*nq;
if(nr !=0) continue factorize_loop;
++nf;
wtable[nf+1+2*n+offset]=ntry;
nl=nq;
if(ntry==2 && nf !=1)
{
for(i=2; i<=nf; i++)
{
ib=nf-i+2;
wtable[ib+1+2*n+offset]=wtable[ib+2*n+offset];
}
wtable[2+2*n+offset]=2;
}
}while(nl !=1);
break factorize_loop;
}
wtable[0+2*n+offset] = n;
wtable[1+2*n+offset] = nf;
argh=twopi /(double)(n);
is=0;
nfm1=nf-1;
l1=1;
if(nfm1==0) return;
for(k1=1; k1<=nfm1; k1++)
{
ip=(int)wtable[k1+1+2*n+offset];
ld=0;
l2=l1*ip;
ido=n / l2;
ipm=ip-1;
for(j=1; j<=ipm;++j)
{
ld+=l1;
i=is;
argld=(double)ld*argh;
fi=0;
for(ii=3; ii<=ido; ii+=2)
{
i+=2;
fi+=1;
arg=fi*argld;
wtable[i-2+n+offset] = Math.cos(arg);
wtable[i-1+n+offset] = Math.sin(arg);
}
is+=ido;
}
l1=l2;
}
} /*rffti1*/
/*---------------------------------------------------------
rffti: Initialization of Real FFT
--------------------------------------------------------*/
void rffti(int n, double wtable[]) /* length of wtable = 2*n + 15 */
{
if(n==1) return;
rffti1(n, wtable, 0);
} /*rffti*/
}
... ...
package com.example.zhongqiyan.javasource.ca.uol.aig.fftpack;
/**
* sine FFT transform of a real odd sequence.
* @author Baoshe Zhang
* @author Astronomical Instrument Group of University of Lethbridge.
*/
public class RealDoubleFFT_Odd extends RealDoubleFFT_Mixed
{
/**
* <em>norm_factor</em> can be used to normalize this FFT transform. This is because
* a call of forward transform (<em>ft</em>) followed by a call of backward
* transform (<em>bt</em>) will multiply the input sequence by <em>norm_factor</em>.
*/
public double norm_factor;
private double wavetable[];
private int ndim;
/**
* Construct a wavenumber table with size <em>n</em>.
* The sequences with the same size can share a wavenumber table. The prime
* factorization of <em>n</em> together with a tabulation of the trigonometric functions
* are computed and stored.
*
* @param n the size of a real data sequence. When (<em>n</em>+1) is a multiplication of small
* numbers (4, 2, 3, 5), this FFT transform is very efficient.
*/
public RealDoubleFFT_Odd(int n)
{
ndim = n;
norm_factor = 2*(n+1);
int wtable_length = 2*ndim + ndim/2 + 3 + 15;
if(wavetable == null || wavetable.length != wtable_length)
{
wavetable = new double[wtable_length];
}
sinti(ndim, wavetable);
}
/**
* Forward sine FFT transform. It computes the discrete sine transform of
* an odd sequence.
*
* @param x an array which contains the sequence to be transformed. After FFT,
* <em>x</em> contains the transform coeffients.
*/
public void ft(double x[])
{
sint(ndim, x, wavetable);
}
/**
* Backward sine FFT transform. It is the unnormalized inverse transform of <em>ft</em>.
*
* @param x an array which contains the sequence to be transformed. After FFT,
* <em>x</em> contains the transform coeffients.
*/
public void bt(double x[])
{
sint(ndim, x, wavetable);
}
/*---------------------------------------
sint1: further processing of sine FFT.
--------------------------------------*/
void sint1(int n, double war[], double wtable[])
{
final double sqrt3=1.73205080756888;
int modn, i, k;
double xhold, t1, t2;
int kc, np1, ns2;
int iw1, iw2, iw3;
double[] wtable_p1 = new double[2*(n+1)+15];
iw1=n / 2;
iw2=iw1+n+1;
iw3=iw2+n+1;
double[] x = new double[n+1];
for(i=0; i<n; i++)
{
wtable[i+iw1]=war[i];
war[i]=wtable[i+iw2];
}
if(n<2)
{
wtable[0+iw1]+=wtable[0+iw1];
}
else if(n==2)
{
xhold=sqrt3*(wtable[0+iw1]+wtable[1+iw1]);
wtable[1+iw1]=sqrt3*(wtable[0+iw1]-wtable[1+iw1]);
wtable[0+iw1]=xhold;
}
else
{
np1=n+1;
ns2=n / 2;
wtable[0+iw2]=0;
for(k=0; k<ns2; k++)
{
kc=n-k-1;
t1=wtable[k+iw1]-wtable[kc+iw1];
t2=wtable[k]*(wtable[k+iw1]+wtable[kc+iw1]);
wtable[k+1+iw2]=t1+t2;
wtable[kc+1+iw2]=t2-t1;
}
modn=n%2;
if(modn !=0)
wtable[ns2+1+iw2]=4*wtable[ns2+iw1];
System.arraycopy(wtable, iw1, wtable_p1, 0, n+1);
System.arraycopy(war, 0, wtable_p1, n+1, n);
System.arraycopy(wtable, iw3, wtable_p1, 2*(n+1), 15);
System.arraycopy(wtable, iw2, x, 0, n+1);
rfftf1(np1, x, wtable_p1, 0);
System.arraycopy(x, 0, wtable, iw2, n+1);
wtable[0+iw1]=0.5*wtable[0+iw2];
for(i=2; i<n; i+=2)
{
wtable[i-1+iw1]=-wtable[i+iw2];
wtable[i+iw1]=wtable[i-2+iw1]+wtable[i-1+iw2];
}
if(modn==0)
wtable[n-1+iw1]=-wtable[n+iw2];
}
for(i=0; i<n; i++)
{
wtable[i+iw2]=war[i];
war[i]=wtable[i+iw1];
}
}
/*----------------
sint: sine FFT
---------------*/
void sint(int n, double x[], double wtable[])
{
sint1(n, x, wtable);
}
/*----------------------------------------------------------------------
sinti: initialization of sin-FFT
----------------------------------------------------------------------*/
void sinti(int n, double wtable[])
{
final double pi=Math.PI; //3.14159265358979;
int k, ns2;
double dt;
if(n<=1) return;
ns2=n / 2;
dt=pi /(double)(n+1);
for(k=0; k<ns2; k++)
wtable[k]=2*Math.sin((k+1)*dt);
rffti1(n+1, wtable, ns2);
}
}
... ...