MediaRecorder recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile("/dev/null");
recorder.prepare();
recorder.start();
for(int i=0; i<10; i++) {
System.err.println("current amplitude is:"+recorder.getMaxAmplitude());
try {
Thread.sleep(1000);
} catch (Exception e) {}
}
recorder.stop();
recorder.reset();
recorder.release();
В этом фрагменте мы теоретически должны получить 10 отметок максимальной амплитуды сигнала за периоды чтения по секунде с первой до десятой. Для этого мы читаем сигнал с микрофона в "никуда", и используем getMaxAmplitude(), который согласно документации должен возвращать значение максимальной амплитуды за период с последнего вызова метода до данного момента. В чём проблема? На моём LG P500 этот метод всегда возвращает ноль :(Исследования на тему "Почему" дали немного. Гораздо интереснее ответ на вопрос
Как всё-таки получать амплитуду сигнала?
Класс MediaRecorder крайне неудобен для работы с сигналом напрямую. Даже если бы я смог его использовать, запись данных в файл - далеко не всё, что обычно нужно при захвате звука. Для наложения фильтров и анализа сигнала удобнее получить сигнал в массив и работать с ним "на лету". К счастью есть ещё один класс в Android SDK, который нас выручит. Это AudioRecord.
Работать с ним несколько сложнее, но мы не боимся трудностей :)
public class AmplitudeReader extends Thread { private AudioRecord audioRecord; private int bufflen; private static final int SAMPPERSEC = 48000; public AmplitudeReader() { android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_DEFAULT; int audioEncoding = AudioFormat.ENCODING_PCM_16BIT; bufflen = AudioRecord.getMinBufferSize(SAMPPERSEC, channelConfiguration, audioEncoding); audioRecord = new AudioRecord(android.media.MediaRecorder.AudioSource.MIC, SAMPPERSEC, channelConfiguration, audioEncoding, bufflen); audioRecord.startRecording(); } private short getMax(short[] arr, int count) { short m = 0; for (int i = 0; i < count; i++) { short c = (short) Math.abs(arr[i]); if (m < c) { m = c; } } return m; } @Override public void run() { for(int i=0; i<11; i++) { short[] curr = new short[bufflen]; int currread = audioRecord.read(curr, 0, bufflen); System.err.println("current amplitude is:" + getMax(curr, currread)); } audioRecord.stop(); audioRecord.release(); } }
В этом примере мы выводим в лог десять значений амплитуды, снятые "на лету" с каждого буфера чтения. Размер буфера система нам установит сама исходя из настроек. Обычно это 4Кb. Понятно, что получением амплитуды мы можем не ограничиться. Сигнал после считывания представлен у нас в массиве байтов (или short, смотря какой метод использовать для чтения). Совершая с элементами этого массива различные действия мы можем усиливать сигнал, подавлять постоянную составляющую, сглаживать и т.п.
И ещё одна особенность: для использования MediaRecorder нам понадобятся 2 разрешения: на чтение и на запись звука на карту: android.permission.RECORD_AUDIO и android.permission.WRITE_EXTERNAL_STORAGE, для использования AudioRecord - только первое из них.
Не очень понятно, что есть AudioReader1 и когда выполняется код внутри него
ОтветитьУдалитьСпасибо за замечание. Поправил исходник. Теперь, надеюсь понятнее :)
ОтветитьУдалитьНе могли бы Вы дать рекомендации по портированию с С# на андроид. Написана программа для обработки речи, но как ее запустить в эклипсе?
ОтветитьУдалитьподвешивает приложение ..
ОтветитьУдалитьwhile (count < 10)
почему такое вырожение, если переменная count у нас не меняется?
если надо зациклить намертово то
while (true){...}
А можно пример простого плеера то есть функции для воспроизведения 1го аудиофайла!?
ОтветитьУдалитьнеужели вы думаете, что максимальный (или минимальный) элемент массива, это и есть показатель амплитуды? Если да (а судя по исходникам, так и есть), то вынужден вас огорчить, это не так ))
ОтветитьУдалить