Pracowałem nad tym trochę więcej. Korzystając z niektórych testów wykonanych za pomocą skalibrowanych mierników SPL i smartfonów z różnymi czystymi częstotliwościami, białego szumu i różowego szumu, teraz wiem, że mikrofony telefonu komórkowego nie nadają się do niczego, co powinno zarejestrować się w dowolnym miejscu powyżej 90 do 100 dB (SPL) w zależności od telefonu .
Zakładając, że 90 dB (SPL) jest maksymalną, można obliczyć, że odpowiada to ciśnieniu 0,6325 Pa przy mikrofonie. Przyjmując teraz, że p0 = 0,0002 Pa jest minimalnym punktem odniesienia i zakładamy, że zarejestruje to jako 0 (co nigdy by się nie stało) z getMaxAmplitude(), możemy wyznaczyć wartości z funkcji getMaxAmplitude() z maksymalnym ciśnieniem na mikrofonie. Oznacza to, że wynik 16375 z funkcji getMaxAmplitude() odpowiadałby maksymalnemu ciśnieniu 0,3165 Pa. To oczywiście nie jest zbyt naukowe, ponieważ wartości maksymalne i minimalne są czyste, ale daje nam to punkt wyjścia.Można teraz obliczyć P z
p = getMaxAmplitude()/51805.5336
Jeżeli ciśnienie w MIC można obliczyć dB (SPL) -wartość ze znanego wzoru
X = 20 log_10 (p/p0)
To nadal daje wartość, która jest wysoka, ponieważ w obliczeniach używana jest tylko maksymalna amplituda. Aby rozwiązać ten nie musi korzystać getMaxAmplitude(), a jednocześnie jest to nieco spokojniejsza poza naciskiem tej kwestii, będę umieścić kod w każdym razie w nadziei, że pomaga
public class NoiseRecorder
{
private final String TAG = SoundOfTheCityConstants.TAG;
public static double REFERENCE = 0.00002;
public double getNoiseLevel() throws NoValidNoiseLevelException
{
Logging.e(TAG, "start new recording process");
int bufferSize = AudioRecord.getMinBufferSize(44100,AudioFormat.CHANNEL_IN_DEFAULT,AudioFormat.ENCODING_PCM_16BIT);
//making the buffer bigger....
bufferSize=bufferSize*4;
AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
44100, AudioFormat.CHANNEL_IN_DEFAULT, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
short data [] = new short[bufferSize];
double average = 0.0;
recorder.startRecording();
//recording data;
recorder.read(data, 0, bufferSize);
recorder.stop();
Logging.e(TAG, "stop");
for (short s : data)
{
if(s>0)
{
average += Math.abs(s);
}
else
{
bufferSize--;
}
}
//x=max;
double x = average/bufferSize;
Logging.e(TAG, ""+x);
recorder.release();
Logging.d(TAG, "getNoiseLevel() ");
double db=0;
if (x==0){
NoValidNoiseLevelException e = new NoValidNoiseLevelException(x);
throw e;
}
// calculating the pascal pressure based on the idea that the max amplitude (between 0 and 32767) is
// relative to the pressure
double pressure = x/51805.5336; //the value 51805.5336 can be derived from asuming that x=32767=0.6325 Pa and x=1 = 0.00002 Pa (the reference value)
Logging.d(TAG, "x="+pressure +" Pa");
db = (20 * Math.log10(pressure/REFERENCE));
Logging.d(TAG, "db="+db);
if(db>0)
{
return db;
}
NoValidNoiseLevelException e = new NoValidNoiseLevelException(x);
throw e;
}
}
Wartości te są obecnie pochodzi z średnia wszystkich amplitud w próbce 4-sekundowej, a zatem dokładniejsza. Następnie wykonuje się powyższe obliczenia. To da bardziej realistyczną wartość decybeli. Zwróć uwagę, że mikrofony z telefonu komórkowego wciąż nie są w stanie zasysać i że ten algorytm nie wytworzy rzeczywistego dB (SPL), ale tylko trochę lepiej zbliżone niż poprzednio.
Aby uzyskać wydajność niektórych aplikacji, trzeba zrobić więcej. Większość z tych aplikacji używa przesuwanych okien, co oznacza, że nagrywają i przesuwają okno o wartości x sekund, aby móc ocenić poziom dźwięku. Również dokonam oceny, która wartość db najlepiej nadaje się do użycia jako max, teraz jest to 90 dB (SPL)/0,6325 Pa, co jest po prostu rozsądnym domysłem, prawdopodobnie będzie nieco powyżej tego.
Jak tylko będę mieć więcej, zaktualizuję informacje.
To zadziałało, dzięki za wyjaśnienie, co robi getMaxAmplitude. Ale nie jestem pewien, czy są to dokładne wartości dB. Kiedy testuję w niektórych przypadkach i próbuję porównać wartości do tego: http://www.newton.dep.anl.gov/askasci/phy99/phy99405.htm, brakuje 30dB. Czy masz jakiś pomysł, dlaczego? – Wissem
Może być kilka przyczyn: 1. Ten algorytm wykorzystuje metodę getMaxAmplitude jako podstawę do obliczeń, co oznacza, że wszystkie mniej głośne zdarzenia w okresie są ignorowane. Prowadzi to do wyników, które mogą być powyżej rzeczywistego poziomu dB (i zwykle w naturalnych środowiskach) 2. Mikrofony telefonów są różne. Niektóre są bardziej wrażliwe niż inne. Algorytm ten nie bierze tego pod uwagę, wykonując te same obliczenia na dowolnym telefonie. Z powodu tych różnic niektóre telefony mogą dawać znacznie wyższe lub niższe wartości. –
Ponadto, ze względu na czynnik ograniczający (wartość wzrasta do 32767), bardzo głośne dźwięki nie są dokładnie wykrywane. Zwykle granica wynosi około 100 dB. –