Holen Frequenz wav-audio mit FFT und Komplexe Klasse
Es wurde eine Menge gefragt, aber ich immer noch nicht über die Umsetzung der FFT-Klasse auf Android
Ich brauche um meine audio-Daten, die mit FFT...
Ich schon gelesen die fast gleiche Frage hier Wie kann ich die Frequenz die Daten von PCM unter Verwendung von FFT
und hier Wie man die Frequenz von der fft-Ergebnis?
und noch mehr Fragen, aber finde immer noch keine Antwort, auch nachdem ich versuchte die gegebenen Antworten...
FFT-Klasse, die ich verwende:
http://www.cs.princeton.edu/introcs/97data/FFT.java
Der komplexen Klasse mit ihm zu gehen: http://introcs.cs.princeton.edu/java/97data/Complex.java.html
Hier ist mein code
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
public class Latihan extends Activity{
private static final int RECORDER_BPP = 16;
private static final String AUDIO_RECORDER_FILE_EXT_WAV = ".wav";
private static final String AUDIO_RECORDER_FOLDER = "AudioRecorder";
private static final String AUDIO_RECORDER_TEMP_FILE = "record_temp.raw";
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;
short[] audioData;
private AudioRecord recorder = null;
private int bufferSize = 0;
private Thread recordingThread = null;
private boolean isRecording = false;
Complex[] fftTempArray;
Complex[] fftArray;
int[] bufferData;
int bytesRecorded;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.p1);
setButtonHandlers();
enableButtons(false);
bufferSize = AudioRecord.getMinBufferSize
(RECORDER_SAMPLERATE,RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING)*3;
audioData = new short [bufferSize]; //short array that pcm data is put into.
}
private void setButtonHandlers() {
((Button)findViewById(R.id.btStart)).setOnClickListener(btnClick);
((Button)findViewById(R.id.btStop)).setOnClickListener(btnClick);
}
private void enableButton(int id,boolean isEnable){
((Button)findViewById(id)).setEnabled(isEnable);
}
private void enableButtons(boolean isRecording) {
enableButton(R.id.btStart,!isRecording);
enableButton(R.id.btStop,isRecording);
}
private String getFilename(){
String filepath = Environment.getExternalStorageDirectory().getPath();
File file = new File(filepath,AUDIO_RECORDER_FOLDER);
if(!file.exists()){
file.mkdirs();
}
return (file.getAbsolutePath() + "/" + System.currentTimeMillis() + AUDIO_RECORDER_FILE_EXT_WAV);
}
public void convert(){
}
public void calculate(){
Complex[] fftTempArray = new Complex[bufferSize];
for (int i=0; i<bufferSize; i++)
{
fftTempArray[i] = new Complex(audioData[i], 0);
}
Complex[] fftArray = FFT.fft(fftTempArray);
double[] micBufferData = new double[bufferSize];
final int bytesPerSample = 2;
final double amplification = 100.0;
for (int index = 0, floatIndex = 0; index < bytesRecorded - bytesPerSample + 1; index += bytesPerSample, floatIndex++) {
double sample = 0;
for (int b = 0; b < bytesPerSample; b++) {
int v = bufferData[index + b];
if (b < bytesPerSample - 1 || bytesPerSample == 1) {
v &= 0xFF;
}
sample += v << (b * 8);
}
double sample32 = amplification * (sample / 32768.0);
micBufferData[floatIndex] = sample32;
}
}
private String getTempFilename(){
String filepath = Environment.getExternalStorageDirectory().getPath();
File file = new File(filepath,AUDIO_RECORDER_FOLDER);
if(!file.exists()){
file.mkdirs();
}
File tempFile = new File(filepath,AUDIO_RECORDER_TEMP_FILE);
if(tempFile.exists())
tempFile.delete();
return (file.getAbsolutePath() + "/" + AUDIO_RECORDER_TEMP_FILE);
}
private void startRecording(){
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
RECORDER_SAMPLERATE, RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING, bufferSize);
recorder.startRecording();
isRecording = true;
recordingThread = new Thread(new Runnable() {
public void run() {
writeAudioDataToFile();
}
},"AudioRecorder Thread");
recordingThread.start();
}
private void writeAudioDataToFile(){
byte data[] = new byte[bufferSize];
String filename = getTempFilename();
FileOutputStream os = null;
try {
os = new FileOutputStream(filename);
} catch (FileNotFoundException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
int read = 0;
if(null != os){
while(isRecording){
read = recorder.read(data, 0, bufferSize);
if(AudioRecord.ERROR_INVALID_OPERATION != read){
try {
os.write(data);
} catch (IOException e) {
e.printStackTrace();
}
}
}
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void stopRecording(){
if(null != recorder){
isRecording = false;
recorder.stop();
recorder.release();
recorder = null;
recordingThread = null;
}
copyWaveFile(getTempFilename(),getFilename());
//deleteTempFile();
}
private void deleteTempFile() {
File file = new File(getTempFilename());
file.delete();
}
private void copyWaveFile(String inFilename,String outFilename){
FileInputStream in = null;
FileOutputStream out = null;
long totalAudioLen = 0;
long totalDataLen = totalAudioLen + 36;
long longSampleRate = RECORDER_SAMPLERATE;
int channels = 2;
long byteRate = RECORDER_BPP * RECORDER_SAMPLERATE * channels/8;
byte[] data = new byte[bufferSize];
try {
in = new FileInputStream(inFilename);
out = new FileOutputStream(outFilename);
totalAudioLen = in.getChannel().size();
totalDataLen = totalAudioLen + 36;
AppLog.logString("File size: " + totalDataLen);
WriteWaveFileHeader(out, totalAudioLen, totalDataLen,
longSampleRate, channels, byteRate);
while(in.read(data) != -1){
out.write(data);
}
in.close();
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void WriteWaveFileHeader(
FileOutputStream out, long totalAudioLen,
long totalDataLen, long longSampleRate, int channels,
long byteRate) throws IOException {
//another code
}
private View.OnClickListener btnClick = new View.OnClickListener() {
public void onClick(View v) {
switch(v.getId()){
case R.id.btStart:{
AppLog.logString("Start Recording");
enableButtons(true);
startRecording();
break;
}
case R.id.btStop:{
AppLog.logString("Stop Recording");
enableButtons(false);
stopRecording();
calculate();
break;
}
}
}
};
}
Ich nehme an, das von Audiodateien array enthält die rohen audio-Daten,aber mein code exception fangen und return "N ist keine Potenz von 2"
Ist es etwas falsch mit meinem code ??
Wie gebe ich es zu FFT.java Klasse und Holen Sie sich die fftResult ??
Oder gibt es einen anderen Weg, um zu konvertieren time-domain-Daten zu Häufigkeit, Daten, einfacher ?
Es ist schon ein paar Monate her, seit ich stecken mit diesem... Mein Projekt ist zu vergleichen 2 audio *.wav-Dateien,
Jede Hilfe würde geschätzt... 🙂
InformationsquelleAutor raisa_ | 2013-07-02
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich schon die Antwort gefunden... 🙂
Ich die create-Methode zu berechnen, array Wert aus audio -...
Dann rief ich in der Klasse Schreiben, Audio -..
InformationsquelleAutor raisa_
Es klingt wie Ihre unmittelbare problem ist "N ist keine Potenz von 2." In diesem Fall ist N bezieht sich wohl auf die Größe der Daten, die Sie setzen in Ihrem FFT. Die meisten FFT-algorithmen arbeiten nur auf Blöcke von Daten, die eine Größe haben, die eine Potenz von 2 ist.
Sind Sie versuchen, die gesamte Datei in eine FFT auf einmal? Wenn dem so ist, müssen Sie möglicherweise Lesen Sie mehr hintergrund-material zu verstehen, was Sie tun. Vielleicht beginnen Sie hier: http://blog.bjornroche.com/2012/07/frequency-detection-using-fft-aka-pitch.html
Ja, das ist mein blog. Der vollständige code für dieses Beispiel verknüpft ist, von diesem post. github.com/bejayoharen/guitartuner
Ich nicht wirklich verstehe,,,, aber ich werde es versuchen, 🙂 thanks 4 ur reccomendation...
Hi, @Silviya. Ich brauche auch Holen zwei vorgegebenen Frequenzen aus einer wave-Datei. Ich habe auch geprüft paar posts, blogs und auch StackOverflow-Frage, aber ich war nicht in der Lage zu finden keine passende Antwort. Ich bin nicht mit android. Nur will ich es in Java. Ich bin wirklich neu in audio, deshalb habe ich keine Erfahrung. Können Sie bitte helfen mir mit, dass? Ich werde es wirklich schätzen. Danke.
Hi, die FFT und komplexe Klasse, die ich verwende basiert auf java als auch android. Sie können die Spur wieder meine Fragen auf stackoverflow, da jede Frage schon beantwortet wurde. Und dieser blog - blog.bjornroche.com/2012/07/... von BjornRoche ist sehr hilfreich. Bitte Kontaktieren Sie mich per E-Mail für weitere Fragen.
InformationsquelleAutor Bjorn Roche