Créez un analyseur de spectre avec une application Android qui capture le son d'un microphone, analyse la fréquence et affiche le spectre. (Je ne l'ai pas publié, car je ne peux pas faire quelque chose qui sortira) ** De plus, le problème demeure. ** **
La bibliothèque de dessins graphiques [MPAndroidChart] est utilisée.
Modifiez build.gradle pour installer MPAndroidChart. Il existe deux types de build.gradle, directement sous la racine du projet et dans le dossier de l'application. Ajoutez ce qui suit à build.gradle directement sous la racine
build.gradle(Project)
allprojects {
repositories {
maven {
url "https://jitpack.io"
}
}
}
Ajoutez ce qui suit à build.gradle dans le dossier de l'application
build.gradle(app)
dependencies {
implementation 'com.github.PhilJay:MPAndroidChart:v3.0.3'
}
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
//Dans MainActivity
public LineChart lineChart;
//dans onCreate
lineChart = findViewById(R.id.line_chart);
initChart();
//À l'intérieur onCheckedChanged (car j'utilise Switch)
fft = new Thread(new Runnable() {
@Override
public void run() {
//Après traitement comme la transformation de Fourier
setData(decibelFrequencySpectrum);
}
});
fft.start();
Méthode InitChart pour initialiser le graphique
initChart
public void initChart() {
lineChart.setTouchEnabled(true);
lineChart.setDragEnabled(false);
//Couleur d'arrière-plan de la grille
lineChart.setDrawGridBackground(true);
// no description text
lineChart.getDescription().setEnabled(true);
lineChart.setBackgroundColor(Color.LTGRAY);
LineData data = new LineData();
data.setValueTextColor(Color.BLACK);
// add empty data
lineChart.setData(data);
//L'axe vertical de la grille est interrompu
XAxis xAxis = lineChart.getXAxis();
xAxis.setAxisMaximum(2048);
xAxis.setAxisMinimum(0);
xAxis.enableGridDashedLine(10f, 10f, 0f);
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
YAxis leftAxis = lineChart.getAxisLeft();
//Réglage maximum / minimum de l'axe Y
leftAxis.setAxisMaximum(0f);
leftAxis.setAxisMinimum(-150f);
//L'axe horizontal de la grille est interrompu
leftAxis.enableGridDashedLine(10f, 10f, 0f);
leftAxis.setDrawZeroLine(true);
//Échelle à droite
lineChart.getAxisRight().setEnabled(false);
}
Méthode SetData qui enregistre avec un microphone et dessine des données transformées de Fourier
setData
public void setData(double[] data) {
ArrayList<Entry> values = new ArrayList<>();
for (int i = 0; i < data.length; i++) {
values.add(new Entry(i, (int)data[i], null, null));
}
LineDataSet set1;
if (lineChart.getData() != null && lineChart.getData().getDataSetCount() > 0) {
set1 = (LineDataSet) lineChart.getData().getDataSetByIndex(0);
set1.setValues(values);
lineChart.getData().notifyDataChanged();
lineChart.notifyDataSetChanged();
} else {
// create a dataset and give it a type
set1 = new LineDataSet(values, "Spectrum");
set1.setDrawIcons(false);
set1.setColor(Color.rgb(0, 0, 240));
set1. setDrawCircles(false);
set1.setLineWidth(0.5f);
set1.setValueTextSize(0f);
set1.setDrawFilled(false);
set1.setFormLineWidth(1f);
set1.setFormLineDashEffect(new DashPathEffect(new float[]{10f, 5f}, 0f));
set1.setFormSize(15.f);
set1.setDrawValues(true);
ArrayList<ILineDataSet> dataSets = new ArrayList<>();
dataSets.add(set1); // add the datasets
// create a data object with the datasets
LineData lineData = new LineData(dataSets);
// set data
lineChart.setData(lineData);
}
}
Le graphique s'affiche correctement. Appuyez sur Switch en haut à gauche pour démarrer l'enregistrement et dessiner le spectre.
Lorsque j'appuie sur Switch, l'enregistrement démarre, mais le graphique n'est pas dessiné. Pourquoi?
Il a été dessiné. Le graphique ne bouge pas lorsque vous relâchez votre main. Si vous la touchez, le graphique sera mis à jour. Pourquoi?
J'ai changé lineChart.setTouchEnabled (True)
en False
dans initChart, mais cette fois il a disparu du tout. Il n'y a aucun changement même si vous touchez le graphique.
~~ Veuillez me dire comment améliorer ~~
Ajout de lineChart.invalidate ()
pour mettre à jour le graphique avec la méthode setData dans le thread fft.
J'ai toujours une erreur. La cause est une erreur provoquée par la tentative de modification de l'interface utilisateur dans un thread autre que le thread principal.
Par conséquent, il est résolu en demandant au thread principal de traiter la méthode setData en utilisant Handler
.
Cliquez ici pour le nouveau code
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
//Dans MainActivity
public LineChart lineChart;
//dans onCreate
lineChart = findViewById(R.id.line_chart);
initChart();
//À l'intérieur onCheckedChanged (car j'utilise Switch)
fft = new Thread(new Runnable() {
@Override
public void run() {
//Après traitement comme la transformation de Fourier
handler.post(new Runnable() {
@Override
public void run() {
setData(decibelFrequencySpectrum);
}
});
}
});
fft.start();
setData
public void setData(double[] data) {
ArrayList<Entry> values = new ArrayList<>();
for (int i = 0; i < data.length; i++) {
values.add(new Entry(i, (int)data[i], null, null));
}
LineDataSet set1;
if (lineChart.getData() != null && lineChart.getData().getDataSetCount() > 0) {
set1 = (LineDataSet) lineChart.getData().getDataSetByIndex(0);
set1.setValues(values);
lineChart.getData().notifyDataChanged();
lineChart.notifyDataSetChanged();
lineChart.invalidate();
} else {
// create a dataset and give it a type
set1 = new LineDataSet(values, "Spectrum");
set1.setDrawIcons(false);
set1.setColor(Color.rgb(0, 0, 240));
set1. setDrawCircles(false);
set1.setLineWidth(0.5f);
set1.setValueTextSize(0f);
set1.setDrawFilled(false);
set1.setFormLineWidth(1f);
set1.setFormLineDashEffect(new DashPathEffect(new float[]{10f, 5f}, 0f));
set1.setFormSize(15.f);
set1.setDrawValues(true);
ArrayList<ILineDataSet> dataSets = new ArrayList<>();
dataSets.add(set1); // add the datasets
// create a data object with the datasets
LineData lineData = new LineData(dataSets);
// set data
lineChart.setData(lineData);
}
}
Recommended Posts