I start record a sound from AudioRecord with some parameters.
private static final int RECORDER_SAMPLERATE = 44100;
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_STEREO;
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
this.recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
RECORDER_SAMPLERATE, RECORDER_CHANNELS,
RECORDER_AUDIO_ENCODING, this.bufferSize);
I store the data into an ArrayList< byte[] > soundRecord;
while (this.isRecording) {
read = this.recorder.read(data, 0, this.bufferSize);
if (AudioRecord.ERROR_INVALID_OPERATION != read) {
try {
soundRecord.add(data);
os.write(data);
} catch (IOException e) {
e.printStackTrace();
}
}
}
This is my method for compute my sound into a complex array FFT. Before doing it, I convert byte into double.
public ArrayList<double[]> computeFFT(byte[] audioSignal) {
final int fftPoint = 65536;
ArrayList<double[]> result;
double tmp;
Complex[] y;
Complex[] complexAudioSignal = new Complex[fftPoint];
double[] magnitude = new double[fftPoint / 2];
for (int i = 0; i < fftPoint; i++) {
if (i >= 22050) tmp = 0;
else tmp = (double) ((audioSignal[2 * i] & 0xFF) | (audioSignal[2 * i + 1] << 8) / 32768.0F;
complexAudioSignal[i] = new Complex(tmp, 0.0);
}
y = FFF.fft(complexAudioSignal);
// Calculate magnitude values from fft[]
for (int i = 0; (fftPoint / 2); i++) {
magnitude[i] = y[i].abs();
}
// get only values over mid value
result = showFrequencies(magnitude, fftPoint);
return result;
}
My problem is, I test a constant sound with 440Hz (A4 from the piano). I get in my array "magnitude" a peak, but the frequency for this peak is 220Hz. Everytime I try a sample sound with only one frequency (I use n-track), the frequency is the real frequency / 2.
I know the frequency is f = index * SAMPLE_RATE / fftPoint.
Someone can help me please. I have this problem since 3 days...
Edit One :
I modify my conversion loop like you suggest. It's look like that :
int bytePerSample =2;
int j = 0;
for (int i = 0; i < audioSignal.length / 2; i++) {
if (( i % 8 == 0 || i % 8 == 2 ) && i < 22050) {
tmp = (double) ((audioSignal[bytesPerSample * i] & 0xFF) | audioSignal[bytePerSample * i + 1] << 8)) / 32768.0F;
complexAudioSignal[j] = new Complex(tmp, 0.0);
j++;
}
}
The problem right now is FrequencyIWant = FreqIObtain / 2. I really don't know what to do now :'(.