How can I show FFT results of that algorithm? - android

I have searched on stackoverflow for the fastest FFT algorithm, and I found the following:
public class FFT {
int n, m;
// Lookup tables. Only need to recompute when size of FFT changes.
double[] cos;
double[] sin;
public FFT(int n) {
this.n = n;
this.m = (int) (Math.log(n) / Math.log(2));
// Make sure n is a power of 2
if (n != (1 << m))
throw new RuntimeException("FFT length must be power of 2");
// precompute tables
cos = new double[n / 2];
sin = new double[n / 2];
for (int i = 0; i < n / 2; i++) {
cos[i] = Math.cos(-2 * Math.PI * i / n);
sin[i] = Math.sin(-2 * Math.PI * i / n);
}
}
public void fft(double[] x, double[] y) {
int i, j, k, n1, n2, a;
double c, s, t1, t2;
// Bit-reverse
j = 0;
n2 = n / 2;
for (i = 1; i < n - 1; i++) {
n1 = n2;
while (j >= n1) {
j = j - n1;
n1 = n1 / 2;
}
j = j + n1;
if (i < j) {
t1 = x[i];
x[i] = x[j];
x[j] = t1;
t1 = y[i];
y[i] = y[j];
y[j] = t1;
}
}
// FFT
n1 = 0;
n2 = 1;
for (i = 0; i < m; i++) {
n1 = n2;
n2 = n2 + n2;
a = 0;
for (j = 0; j < n1; j++) {
c = cos[a];
s = sin[a];
a += 1 << (m - i - 1);
for (k = j; k < n; k = k + n2) {
t1 = c * x[k + n1] - s * y[k + n1];
t2 = s * x[k + n1] + c * y[k + n1];
x[k + n1] = x[k] - t1;
y[k + n1] = y[k] - t2;
x[k] = x[k] + t1;
y[k] = y[k] + t2;
}
}
}
}
}
My question is that I have a MediaRecorder Object to capture audio as follows:
if (mRecorder == null) {
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mRecorder.setOutputFile("/dev/null");
try {
mRecorder.prepare();
} catch (IllegalStateException e) {
Log.e("error", "IllegalStateException");
} catch (IOException e) {
Log.e("error", "IOException");
;
}
mRecorder.start();
}
Now I want to use this FFT algorithm on my captured audio and show the results on an equalizer or something. How I can do that?

MediaRecorder doesn't give you access directly to the audio buffer, but if you use AudioRecord you can. If you must use MediaRecorder then perhaps save it to a file and then re-read the file back in again.
Someone has worked on an example here Capturing Sound for Analysis and Visualizing Frequencies in Android

Related

interpolate a given array to be in new lenght

in order to interpolate 2 values, I can use
lerp(int a, int b) {
return (a + b) / 2;
}
Now imagine I've an array(1, 30, 100, 300) and I want to interpolate it to array in size N (N=10 for example).
If N == 7, then:
1,15,30,65,100,200,300
I've no idea how to interpolate 4 values to be 10. I need a method that looks like:
interpolate(fina int[] input, final int newSize) {
int[] res = new int[newSize];
...
return res;
}
that works even on my example above with newSize of 7, 10 or whatever.
Any idea how to implement it?
SOLVED.
public static double[] interpolate(double[] x, int newLength) {
double[] y = null;
if (newLength > 0) {
int N = x.length;
if (N == 1) {
y = new double[1];
y[0] = x[0];
return y;
} else if (newLength == 1) {
y = new double[1];
int ind = (int) Math.floor(N * 0.5 + 0.5);
ind = Math.max(1, ind);
ind = Math.min(ind, N);
y[0] = x[ind - 1];
return y;
} else {
y = new double[newLength];
double Beta = ((double) newLength) / N;
double newBeta = 1.0;
if (newLength > 2)
newBeta = (N - 2.0) / (newLength - 2.0);
y[0] = x[0];
y[1] = x[1];
y[newLength - 1] = x[N - 1];
double tmp, alpha;
int i, j;
for (i = 2; i <= newLength - 2; i++) {
tmp = 1.0 + (i - 1) * newBeta;
j = (int) Math.floor(tmp);
alpha = tmp - j;
y[i] = (1.0 - alpha) * x[Math.max(0, j)] + alpha * x[Math.min(N - 1, j + 1)];
}
}
}
return y;
}
/**
* Find the maximum of all elements in the array, ignoring elements that are NaN.
* #param data
* #return
*/
public static double max(double[] data) {
double max = Double.NaN;
for (int i = 0; i < data.length; i++) {
if (Double.isNaN(data[i]))
continue;
if (Double.isNaN(max) || data[i] > max)
max = data[i];
}
return max;
}
public static int max(int[] data) {
int max = data[0];
for (int i = 1; i < data.length; i++) {
if (data[i] > max)
max = data[i];
}
return max;
}

How to apply hanning window function

Audio beacon is generating different frequency between 18 khz to 19 khz.I'm trying to record all frequency using AudioTrack Api.I refered this link How to get frequency from fft result?. I'm getting all data is 0 after apply hanning window function.1)how to apply hanning window? 2)how to filter frequency?3) I record different range frequency audio and save it in .wav formate.I'm reading that audio file and convert into frequency.But i'm getting high frqeuency only.How to get multiple peak frequency?
int fftSize = 1024;
public void startRecord() {
short[] bytebuff = new short[2 * fftSize];
while (started) {
int bufferReadResult = audioRecord.read(bytebuff, 0, bytebuff.length);
if (bufferReadResult >= 0) {
fft(bytebuff);
}
}
}
public void fft(short[] bufferByte) {
int N = bufferByte.length;
DoubleFFT_1D fft1d = new DoubleFFT_1D(N);
double[] fft = new double[N * 2];
double[] magnitude = new double[N / 2];
for (int i = 0; i < N; i++) {//Hann window function
bufferByte[i] = (byte) (bufferByte[i] * 0.5 * (1.0 - Math.cos(2.0 * Math.PI * i / (bufferByte.length))));//here i'm getting all data is zero.
}
for (int i = 0; i < N - 1; ++i) {
fft[2 * i] = bufferByte[i];
fft[2 * i + 1] = 0;
}
fft1d.complexForward(fft);
// calculate power spectrum (magnitude) values from fft[]
for (int i = 0; i < (N / 2) - 1; i++) {
double real = fft[2 * i];
double imaginary = fft[2 * i + 1];
magnitude[i] = Math.sqrt(real * real + imaginary * imaginary);
}
double max_magnitude = -1;
int max_index = -1;
for (int i = 0; i < (N / 2) - 1; i++) {
if (magnitude[i] > max_magnitude) {
max_magnitude = magnitude[i];
max_index = i;
}
}
int freq = max_index * 44100 / N;
Log.e("AudioBEacon", "---" + freq);
}
You have a bad cast here:
bufferByte[i] = (byte) (bufferByte[i] * ...
It should be:
bufferByte[i] = (short) (bufferByte[i] * ...

Fast Fourier transform of the recorded wav file in Android

There is a wav file on SD card. First, I connect to a file and reads the byte:
File file = null;file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/202.wav");
byte[] byteData = new byte[(int) file.length()];
FileInputStream in = null;
try {
in = new FileInputStream( file );
in.read( byteData );
in.close();}
I then use the transformation of data from a byte type in type double, because the FFT procedure does not work with byte type:
double[] transformed = new double[(int) file.length()];
for (int j=1;j<8194;j++) {
transformed[j] = (double)byteData[j]; }
And then the procedure of FFT processing this data:
public void spektr(double[] x, double[] y, int Dim, int D, double[] xx, double[] yy) {
int I,J,N,L,K,LE,LE1,IP,NV2,NM1;
double Arg,U1,U2,U3,C,S,T1,T2,T3,T4;
N = (int) Math.pow(2,Dim);
Log.v("N", "N "+N);
for (L = 1; L < Dim; L++){
LE = (int) Math.pow(2,Dim+1-L);
LE1 = LE/2;
U1 = (double)1.0;
U2 = (double)0.0;
Arg = (double)Math.PI/LE1;
C = (double)Math.cos(Arg);
S = D*(double)Math.sin(Arg);
for(J = 1; J < LE1; J++){
I = J;
do{
IP = I+LE1;
T1 = x[I] + x[IP];
T2 = y[I] + y[IP];
T3 = x[I] - x[IP];
T4 = y[I] - y[IP];
x[IP] = T3*U1 - T4*U2;
y[IP] = T4*U1 + T3*U2;
x[I] = T1;
y[I] = T2;
I = I + LE;
}while(I <= N);
U3 = U1*C - U2*S;
U2 = U2*C - U1*S;
U1 = U3;
}
}
NV2 = N / 2;
Log.v("NV2", "NV2 "+NV2);
NM1 = N-1;
Log.v("NM1", "NM1 "+NM1);
J = 1;
for(I = 1; I < NM1; I++){
if (I < J){
T1 = x[J];
T2 = y[J];
x[J] = x[I];
y[J] = y[I];
x[I] = T1;
y[I] = T2;
}
K = NV2;
while (K < J){
J = J - K;
K = K / 2;
};
J = J + K;
}
for(I = 1; I < N; I++){
x[I] = x[I] / N*2;
y[I] = y[I] / N*2;
}
for(I = 1; I < N; I++){
xx[I] = x[I];
yy[I] = y[I];
}
xx[1] = (double)0.0;
}
Reads the file successfully, but the processing procedure of the FFT is not working.
How to find the FFT procedure, or give the code to check the FFT result?
here is some free library to do FFT in java.

Android - AudioRecord class does not read data, audioData and fftArray return zero

I am new to android and I have been working on a Pitch Analyzer application (minimum SDK: 8). I read many articles on how to implement Audiorecord class but I wonder why it does not read any data when I record. I tried to display the values of the audioData and fftArray but zero is returned, so I assumed the problem is with the read method. Please try to check these. Here are the codes I used:
FFT.java
Complex.java
record.java
final Intent intent = new Intent("pitch.analyzer.PitZer.ASSESSMENT");
MediaRecorder recorder;
AudioRecord tuner;
int audioSource = MediaRecorder.AudioSource.MIC;
int sampleRateInHz = AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_SYSTEM);
int channelConfig = AudioFormat.CHANNEL_CONFIGURATION_MONO;
int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
int bufferSizeInBytes = 4096;
int samples;
short[] audioBuffer;
short[] audioData;
double[] temp;
TextView fft;
TextView results;
//TextView bufferSize;
Complex[] fftTempArray;
Complex[] fftArray;
Complex[] fftInverse;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.record);
Button start=(Button)findViewById(R.id.record);
Button stop=(Button)findViewById(R.id.stop);
fft = (TextView)findViewById(R.id.fft);
results = (TextView)findViewById(R.id.results);
//bufferSize = (TextView)findViewById(R.id.bufferSize);
audioData = new short[bufferSizeInBytes];
tuner = new AudioRecord(audioSource, sampleRateInHz, channelConfig, audioFormat, bufferSizeInBytes);
//final AudioRecorder recorder = new AudioRecorder("/audiometer/temp");
start.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
acquire();
computeFFT();
display();
}
});
//….wait a while
stop.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
startActivity(intent);
}
});
}
public void acquire(){
try {
tuner.startRecording();
samples = tuner.read(audioData, 0, bufferSizeInBytes);
}
catch (Throwable t){
}
}
public void computeFFT(){
//Conversion from short to double
double[] micBufferData = new double[bufferSizeInBytes];//size may need to change
final int bytesPerSample = 2; // As it is 16bit PCM
final double amplification = 100.0; // choose a number as you like
for (int index = 0, floatIndex = 0; index < bufferSizeInBytes - bytesPerSample + 1; index += bytesPerSample, floatIndex++) {
double sample = 0;
for (int b = 0; b < bytesPerSample; b++) {
int v = audioData[index + b];
if (b < bytesPerSample - 1 || bytesPerSample == 1) {
v &= 0xFF;
}
sample += v << (b * 8);
}
double sample32 = amplification * (sample / 32768.0);
micBufferData[floatIndex] = sample32;
}
//Create Complex array for use in FFT
fftTempArray = new Complex[bufferSizeInBytes];
for (int i=0; i<bufferSizeInBytes; i++)
{
fftTempArray[i] = new Complex(micBufferData[i], 0);
}
//Obtain array of FFT data
fftArray = FFT.fft(fftTempArray);
fftInverse = FFT.ifft(fftTempArray);
double[] freq2 = new double[fftArray.length];
//Create an array of magnitude of fftArray
double[] magnitude = new double[fftArray.length];
for (int i=0; i<fftArray.length; i++){
magnitude[i]= fftArray[i].abs();
freq2[i] = ComputeFrequency(magnitude[i]);
}
fft.setTextColor(Color.BLUE);
//fft.setText("fftArray is "+ fftArray[500] +" and fftTempArray is "+fftTempArray[500] + " and fftInverse is "+fftInverse[500]+" and audioData is "+audioData[500]+ " and magnitude is "+ magnitude[1] + ", "+magnitude[500]+", "+magnitude[1000]+ " and freq2 is "+ freq2[1]+" You rock dude!");
/*for(int i = 2; i < samples; i++){
fft.append(" " + magnitude[i] + " Hz");
}
for(int i = 2; i < samples; i++){
fft.append(" " + freq2[i] + " Hz");
}
*/
}
private double ComputeFrequency(double arrayIndex) {
return ((1.0 * sampleRateInHz) / (1.0 * 100)) * arrayIndex;
}
public void display(){
results.setTextColor(Color.BLUE);
results.setText("results: "+audioData[1]+"");
for(int i = 2; i < samples; i++){
results.append(" " + audioData[i]);
}
results.invalidate();
//fft.setTextColor(Color.GREEN);
fft.setText("sampleRateInHz: "+sampleRateInHz);
fft.append("\nfftArray: "+fftArray[0]+" Hz");
for(int i = 1; i < samples; i++){
fft.append(" " + fftArray[i] + " Hz");
}
fft.append("\naudioData: "+audioData[1]);
fft.append("\nsamples: "+samples);
//fft.invalidate();
}
public void stop() throws IOException {
tuner.stop();
//audioInput.reset();
tuner.release();
//recorder.stop();
//recorder.reset();
//recorder.release();
}
Before reading from the device you should start a recording(and stop it once you finish).
Here is the code i use for a simple read:
short[] audioData = new short[bufferSize];
int offset =0;
int shortRead = 0;
//start tapping into the microphone
audioRecored.startRecording();
//start reading from the microphone to an internal buffer - chuck by chunk
while (offset < bufferSize)
{
shortRead = audioRecored.read(audioData, offset ,bufferSize - offset);
offset += shortRead;
}
//stop tapping into the microphone
audioRecored.stop();
Also check if microphone is used only once, in application.
All devices before version 23, does not allow nonblocking reading of microphone stream.
If there are two processes reading from microphone stream only first one is getting real data.
Other returns -2, or -3 (read count) as an exception to read blocked stream.

Android: How to shift pitch of output sound (realtime)

I'm new in Android development. I'm looking for any method that applies pitch shifting to output sound (in real-time). But I couldn't find any point to start.
I've found this topic but I still don't know how can I apply this.
Any suggestions?
In general, the algorithm is called a phase vocoder -- searching for that on the Internets should get you started.
There are a few open source phase vocoders out there, you should be able to use those for reference too.
You can do phase vocoder in real-time -- the main component used is the FFT, so you'll need a fast FFT. The Android libraries can do this for you, see this documentation: http://developer.android.com/reference/android/media/audiofx/Visualizer.html
As it happens, I'm about to release an open source FFT for ARM that is faster than Apple's vDSP library (which was hitherto the fastest). I'll post back in a few days when I've uploaded it to github.com.
Good luck.
There is no built-in pitch shifting algorithm in the Android SDK. You have to code your own. Pitch shifting is a real hardcore DSP algorithm; good sounding algorithms are results of many months or rather years of development...
I personally do not know any Java implementation so I suggest you to adopt some of the free C++ PS algorithms, the best one - which I use in my audio applications, is SoundTouch:
http://www.surina.net/soundtouch/
I played with its code a little and it seems it would not be too much complicated to rewrite it in Java.
HOME URL: http://www.dspdimension.com
public class AudioPitch{
//region Private Static Memebers
private static int MAX_FRAME_LENGTH = 8192;
private static double M_PI = 3.14159265358979323846;
private static float[] gInFIFO = new float[MAX_FRAME_LENGTH];
private static float[] gOutFIFO = new float[MAX_FRAME_LENGTH];
private static float[] gFFTworksp = new float[2 * MAX_FRAME_LENGTH];
private static float[] gLastPhase = new float[MAX_FRAME_LENGTH / 2 + 1];
private static float[] gSumPhase = new float[MAX_FRAME_LENGTH / 2 + 1];
private static float[] gOutputAccum = new float[2 * MAX_FRAME_LENGTH];
private static float[] gAnaFreq = new float[MAX_FRAME_LENGTH];
private static float[] gAnaMagn = new float[MAX_FRAME_LENGTH];
private static float[] gSynFreq = new float[MAX_FRAME_LENGTH];
private static float[] gSynMagn = new float[MAX_FRAME_LENGTH];
private static long gRover;
//endregion
public static void PitchShift(float pitchShift, long numSampsToProcess, long fftFrameSize/*(long)2048*/, long osamp/*(long)10*/, float sampleRate, float[] indata)
{
double magn, phase, tmp, window, real, imag;
double freqPerBin, expct;
long i, k, qpd, index, inFifoLatency, stepSize, fftFrameSize2;
float[] outdata = indata;
/* set up some handy variables */
fftFrameSize2 = fftFrameSize / 2;
stepSize = fftFrameSize / osamp;
freqPerBin = sampleRate / (double)fftFrameSize;
expct = 2.0 * M_PI * (double)stepSize / (double)fftFrameSize;
inFifoLatency = fftFrameSize - stepSize;
if (gRover == 0) gRover = inFifoLatency;
/* main processing loop */
for (i = 0; i < numSampsToProcess; i++)
{
/* As long as we have not yet collected enough data just read in */
gInFIFO[(int) gRover] = indata[(int) i];
outdata[(int) i] = gOutFIFO[(int) (gRover - inFifoLatency)];
gRover++;
/* now we have enough data for processing */
if (gRover >= fftFrameSize)
{
gRover = inFifoLatency;
/* do windowing and re,im interleave */
for (k = 0; k < fftFrameSize; k++)
{
window = -.5 * Math.cos(2.0 * M_PI * (double)k / (double)fftFrameSize) + .5;
gFFTworksp[(int) (2 * k)] = (float)(gInFIFO[(int) k] * window);
gFFTworksp[(int) (2 * k + 1)] = 0.0F;
}
/* ***************** ANALYSIS ******************* */
/* do transform */
ShortTimeFourierTransform(gFFTworksp, fftFrameSize, -1);
/* this is the analysis step */
for (k = 0; k <= fftFrameSize2; k++)
{
/* de-interlace FFT buffer */
real = gFFTworksp[(int) (2 * k)];
imag = gFFTworksp[(int) (2 * k + 1)];
/* compute magnitude and phase */
magn = 2.0 * Math.sqrt(real * real + imag * imag);
phase = smbAtan2(imag, real);
/* compute phase difference */
tmp = phase - gLastPhase[(int) k];
gLastPhase[(int) k] = (float)phase;
/* subtract expected phase difference */
tmp -= (double)k * expct;
/* map delta phase into +/- Pi interval */
qpd = (long)(tmp / M_PI);
if (qpd >= 0) qpd += qpd & 1;
else qpd -= qpd & 1;
tmp -= M_PI * (double)qpd;
/* get deviation from bin frequency from the +/- Pi interval */
tmp = osamp * tmp / (2.0 * M_PI);
/* compute the k-th partials' true frequency */
tmp = (double)k * freqPerBin + tmp * freqPerBin;
/* store magnitude and true frequency in analysis arrays */
gAnaMagn[(int) k] = (float)magn;
gAnaFreq[(int) k] = (float)tmp;
}
/* ***************** PROCESSING ******************* */
/* this does the actual pitch shifting */
for (int zero = 0; zero < fftFrameSize; zero++)
{
gSynMagn[zero] = 0;
gSynFreq[zero] = 0;
}
for (k = 0; k <= fftFrameSize2; k++)
{
index = (long)(k * pitchShift);
if (index <= fftFrameSize2)
{
gSynMagn[(int) index] += gAnaMagn[(int) k];
gSynFreq[(int) index] = gAnaFreq[(int) k] * pitchShift;
}
}
/* ***************** SYNTHESIS ******************* */
/* this is the synthesis step */
for (k = 0; k <= fftFrameSize2; k++)
{
/* get magnitude and true frequency from synthesis arrays */
magn = gSynMagn[(int) k];
tmp = gSynFreq[(int) k];
/* subtract bin mid frequency */
tmp -= (double)k * freqPerBin;
/* get bin deviation from freq deviation */
tmp /= freqPerBin;
/* take osamp into account */
tmp = 2.0 * M_PI * tmp / osamp;
/* add the overlap phase advance back in */
tmp += (double)k * expct;
/* accumulate delta phase to get bin phase */
gSumPhase[(int) k] += (float)tmp;
phase = gSumPhase[(int) k];
/* get real and imag part and re-interleave */
gFFTworksp[(int) (2 * k)] = (float)(magn * Math.cos(phase));
gFFTworksp[(int) (2 * k + 1)] = (float)(magn * Math.sin(phase));
}
/* zero negative frequencies */
for (k = fftFrameSize + 2; k < 2 * fftFrameSize; k++) gFFTworksp[(int) k] = 0.0F;
/* do inverse transform */
ShortTimeFourierTransform(gFFTworksp, fftFrameSize, 1);
/* do windowing and add to output accumulator */
for (k = 0; k < fftFrameSize; k++)
{
window = -.5 * Math.cos(2.0 * M_PI * (double)k / (double)fftFrameSize) + .5;
gOutputAccum[(int) k] += (float)(2.0 * window * gFFTworksp[(int) (2 * k)] / (fftFrameSize2 * osamp));
}
for (k = 0; k < stepSize; k++) gOutFIFO[(int) k] = gOutputAccum[(int) k];
/* shift accumulator */
//memmove(gOutputAccum, gOutputAccum + stepSize, fftFrameSize * sizeof(float));
for (k = 0; k < fftFrameSize; k++)
{
gOutputAccum[(int) k] = gOutputAccum[(int) (k + stepSize)];
}
/* move input FIFO */
for (k = 0; k < inFifoLatency; k++) gInFIFO[(int) k] = gInFIFO[(int) (k + stepSize)];
}
}
}
//endregion
//region Private Static Methods
public static void ShortTimeFourierTransform(float[] fftBuffer, long fftFrameSize, long sign)
{
float wr, wi, arg, temp;
float tr, ti, ur, ui;
long i, bitm, j, le, le2, k;
for (i = 2; i < 2 * fftFrameSize - 2; i += 2)
{
for (bitm = 2, j = 0; bitm < 2 * fftFrameSize; bitm <<= 1)
{
if ((i & bitm) != 0) j++;
j <<= 1;
}
if (i < j)
{
temp = fftBuffer[(int) i];
fftBuffer[(int) i] = fftBuffer[(int) j];
fftBuffer[(int) j] = temp;
temp = fftBuffer[(int) (i + 1)];
fftBuffer[(int) (i + 1)] = fftBuffer[(int) (j + 1)];
fftBuffer[(int) (j + 1)] = temp;
}
}
long max = (long)(Math.log(fftFrameSize) / Math.log(2.0) + .5);
for (k = 0, le = 2; k < max; k++)
{
le <<= 1;
le2 = le >> 1;
ur = 1.0F;
ui = 0.0F;
arg = (float)M_PI / (le2 >> 1);
wr = (float)Math.cos(arg);
wi = (float)(sign * Math.sin(arg));
for (j = 0; j < le2; j += 2)
{
for (i = j; i < 2 * fftFrameSize; i += le)
{
tr = fftBuffer[(int) (i + le2)] * ur - fftBuffer[(int) (i + le2 + 1)] * ui;
ti = fftBuffer[(int) (i + le2)] * ui + fftBuffer[(int) (i + le2 + 1)] * ur;
fftBuffer[(int) (i + le2)] = fftBuffer[(int) i] - tr;
fftBuffer[(int) (i + le2 + 1)] = fftBuffer[(int) (i + 1)] - ti;
fftBuffer[(int) i] += tr;
fftBuffer[(int) (i + 1)] += ti;
}
tr = ur * wr - ui * wi;
ui = ur * wi + ui * wr;
ur = tr;
}
}
}
//endregion
private static double smbAtan2(double x, double y)
{
double signx;
if (x > 0.) signx = 1.;
else signx = -1.;
if (x == 0.) return 0.;
if (y == 0.) return signx * M_PI / 2.;
return Math.atan2(x, y);
}
}
this code working too but very consumption cpu usage.
pitchShift between 0.5 -2.0
call this class as below:
int maxValueOFShort = 32768;
short [] buffer = new short[800];
float[] inData = new float[buffer.length];
while (audiorackIsRun)
{
int m = recorder.read(buffer, 0, buffer.length);
for(int n=0; n<buffer.length;n++)
inData[n] = buffer[n]/(float)maxValueOFShort;
AudioPitch.PitchShift(1, buffer.length, 4096, 4, 44100, inData);
for(int n=0; n<buffer.length;n++)
buffer[n] = (short)(inData[n]*maxValueOFShort);
player.write(buffer, 0, buffer.length);
}

Categories

Resources