2012-06-16 3 views
0

Я пытаюсь создать какой-то звуковой метр на платформе Android. (я использую HTC wildfire). Я использую класс AudioRecord для этой цели, однако кажется, что значения , возвращаемые из «прочитанного», не являются разумными.Чтение AudioRecord возвращает странные значения

Это, как я создал объект AudioRecord:

int minBufferSize = 
     AudioRecord.getMinBufferSize(sampleRateInHz, 
             android.media.AudioFormat.CHANNEL_IN_MONO, 
             android.media.AudioFormat.ENCODING_PCM_16BIT); 

audioRecored = new AudioRecord(MediaRecorder.AudioSource.MIC,   
           44100, 
           android.media.AudioFormat.CHANNEL_IN_MONO, 
           android.media.AudioFormat.ENCODING_PCM_16BIT, 
           minBufferSize); 

Это, как я пытаюсь читать данные из него:

short[] audioData = new short[bufferSize]; 
    int offset =0; 
    int shortRead = 0; 
    int sampleToReadPerGet = 1000;//some value in order to avoid momentaraly nosies. 

    //start tapping into the microphone 
    audioRecored.startRecording(); 

    //start reading from the microphone to an internal buffer - chuck by chunk 
    while (offset < sampleToReadPerGet) 
    { 
      shortRead = audioRecored.read(audioData, offset ,sampleToReadPerGet - offset); 
      offset += shortRead; 
    } 

    //stop tapping into the microphone 
    audioRecored.stop(); 

    //average the buffer 
    int averageSoundLevel = 0; 
    for (int i = 0 ; i < sampleToReadPerGet ; i++) 
    { 
     averageSoundLevel += audioData[i];   
    } 
    averageSoundLevel /= sampleToReadPerGet;  

Каковы эти ценности? они децибелы?

Редактировать: Значения от -200 до 3000. Значение shortRead - sampleToReadPerGet (1000).

+1

Какие ценности вы получаете? Конечно, вы просто возвращаете 16-битные образцы PCM. – Brad

+1

Какова ценность «shortRead» после вызова для чтения? –

+0

Добавлены значения к вопросу. – talel

ответ

1

Не знаете, на какие «эти значения» вы ссылаетесь, на необработанный вывод или усредненные значения, но необработанный вывод - это мгновенные уровни амплитуды. Важно понимать, что такие ценности не относятся ни к чему конкретно. То есть, только потому, что вы читаете 20, не говорит вам о чем.

Принимая среднее значение этих значений, не имеет никакого смысла, поскольку эти значения качаются выше и ниже нуля. Сделайте это достаточно долго, и вы просто получите нуль.

Возможно, имеет смысл принять среднее значение квадратов, а затем найти квадратный корень из среднего. Это называется RMS. Тем не менее, без фиксированного размера буфера в среднем, это в лучшем случае опасно.

Для измерения дБ вам необходимо использовать формулу dB = 20 log_10 (| A |/A_r), где A - амплитуда, а A_r - эталонная амплитуда - очевидно, вы должны решить, что вы указываете (вы может откалибровать HTC или измерять максимальный уровень или что-то в этом роде).

0

Вы не должны получать отрицательные значения. Значения составляют 16 или 8 бит, поэтому ваш макс составляет около 32000 или что-то в этом роде. Значения не имеют единиц.

Кроме того, я рекомендую среднеквадратичное значение вместо среднего для определения тома. Он более стабилен.

Что вы должны попробовать:

  • Увеличение размера буфера на 3: Ваше приложение не может читать его быстро достаточно, чтобы вам необходимо некоторое пространство. В противном случае вы можете получать некоторые ошибки переполнения буфера (которые вы не проверяли в коде)

  • Попробуйте код в gast-lib: Это позволяет периодически записывать звук, а также предоставляет вам AsyncTask.

  • Среднее квадратическое:

public static double rootMeanSquared(short[] nums) 
{ 
    double ms = 0; 
    for (int i = 0; i < nums.length; i++) 
    { 
     ms += nums[i] * nums[i]; 
    } 
    ms /= nums.length; 
    return Math.sqrt(ms); 
} 
+0

код из гастриба не строит – Mirko

+0

на самом деле он делает после часовых настроек;) – Mirko

Смежные вопросы