2013-04-21 9 views
3

Мое приложение. вычисляет уровень шума и пик частоты входного звука. Я использовал FFT, чтобы получить массив шорты [] буфера, и это код: BufferSize = 1024, SAMPLERATE = 44100Как проверить уровень шума RMS-алгоритм

int bufferSize = AudioRecord.getMinBufferSize(sapleRate, 
       channelConfiguration, audioEncoding); 
     AudioRecord audioRecord = new AudioRecord(
       MediaRecorder.AudioSource.DEFAULT, sapleRate, 
       channelConfiguration, audioEncoding, bufferSize); 

и это преобразование кода:

short[] buffer = new short[blockSize]; 
     try { 
      audioRecord.startRecording(); 
     } catch (IllegalStateException e) { 
      Log.e("Recording failed", e.toString()); 
     } 
     while (started) { 
      int bufferReadResult = audioRecord.read(buffer, 0, blockSize); 

      /* 
      * Noise level meter begins here 
      */ 
      // Compute the RMS value. (Note that this does not remove DC). 
      double rms = 0; 
      for (int i = 0; i < buffer.length; i++) { 
       rms += buffer[i] * buffer[i]; 
      } 
      rms = Math.sqrt(rms/buffer.length); 
      mAlpha = 0.9; mGain = 0.0044; 
      /*Compute a smoothed version for less flickering of the 
      // display.*/ 
      mRmsSmoothed = mRmsSmoothed * mAlpha + (1 - mAlpha) * rms; 
      double rmsdB = 20.0 * Math.log10(mGain * mRmsSmoothed); 

Теперь я хочу знать, работает ли этот алгоритм правильно, или что-то не хватает? И я хочу знать, было ли это правильно, и у меня есть звук в дБ, отображаемый на мобильном телефоне, как его проверить? Мне нужна помощь, спасибо заранее.

+0

Я думаю, что это будет трудно получить надежную абсолютную величину дБ, из-за аппаратных различий в конвертерах и микрофоны/A D. Вам придется откалибровать его на источник звука известной громкости. Также почему вы умножаете 'log10' на коэффициент 20.0? Разве это не должно быть '10' (потому что это _deci_bel)? Кроме того, возможно, вам нужно применить коэффициент усиления до вычисления RMS, а не после, в зависимости от того, что именно означает «выигрыш». – Thomas

+2

@Thomas: '20 * log10' верен в этом случае, так как мы имеем дело с * напряжением *. '10 * log10' используется для * мощности *. (Обратите внимание, что вы также можете добиться того же результата более эффективно, не принимая «sqrt» величины, а затем используйте '10 * log10'.) –

ответ

1

Код выглядит правильно, но вам, вероятно, следует обработать случай, когда вначале буфер содержит нули, что может привести к сбою Math.log10, например. изменение:

 double rmsdB = 20.0 * Math.log10(mGain * mRmsSmoothed); 

к:

 double rmsdB = mGain * mRmsSmoothed >.0 0 ? 
          20.0 * Math.log10(mGain * mRmsSmoothed) : 
          -999.99; // choose some appropriate large negative value here for case where you have no input signal 
+0

Большое спасибо за ваш ответ, у меня вопрос .. как я могу проверить результат? , или как я могу откалибровать устройство? – Fareed

+0

Вам нужен справочный источник звука - они довольно дороги, но вы можете нанять их у компаний по прокату электронного оборудования на неделю или месяц. –

+0

Обратите внимание, что в приведенном выше комментарии предполагается, что вы говорите об измерении dB SPL через вход микрофона. Если вы просто хотите, чтобы dBV или dBm от ввода линейного уровня сказали, это намного проще. –