Работа с аудио и видеоинформацией в приложениях для смартфона, использование Intel Perceptual Computing SDK
Работа с несжатым звуком
Android API предоставляет классы AudioTrack и AudioRecord, позволяющие напрямую записывать аудио и воспроизводить аудиопоток в формате PCM, используя аппаратные возможности устройства. Рассмотрим процесс записи и воспроизведения "сырых" данных в формате PCM.
Для записи аудиоданных непосредственно с аппаратных буферов используется класс AudioRecord. Необходимо создать новый объект AudioRecord, указав источник, частоту, настройки каналов, кодировщик для аудио и размер буфера. Значения частоты, кодировщика аудио и настроек каналов повлияют на размер и качество записанного аудиофайла.
int frequency = 11025; //частота int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO; int audioEncoding = AudioFormat.ENCODING_PCM_16BIT; //кодировщик //размер буфера int bufferSize = AudioRecord.getMinBufferSize(frequency, channelConfiguration, audioEncoding); AudioRecord audioRecord = new AudioRecord( MediaRecorder.AudioSource.MIC, frequency, channelConfiguration, audioEncoding, bufferSize);
Необходимо в манифест приложения добавить полномочие RECORD_AUDIO.
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
После инициализации объекта AudioRecord необходимо вызвать метод startRecording(), чтобы начать асинхронную запись. Для добавления необработанных аудиоданных в записываемый буфер используется метод read():
short[] buffer = new short[bufferSize]; audioRecord.startRecording(); while (isRecording) { //заполнение буфера данными int bufferReadResult = audioRecord.read(buffer, 0, bufferSize); }
Для обработки входящего аудиопотока и воспроизведения его практически в режиме реального времени, используется класс AudioTrack. Этот класс дает возможность манипулировать входящим и исходящим звуком, обрабатывая на устройстве несжатые аудиоданные.
Необходимо создать новый объект AudioTrack, указав потоковый режим, частоту, параметры каналов, тип кодировщика и длину аудио.
//частота, увеличивает скорость проигрывания вдвое int frequency = 11025/2; int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO; int audioEncoding = AudioFormat.ENCODING_PCM_16BIT; AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, frequency, channelConfiguration, audioEncoding, audioLength, AudioTrack.MODE_STREAM);
Поскольку аудиоданные необработанные, отсутствует метаинформация, связанная с ними. Поэтому важно установить корректные свойства, чтобы они совпадали с теми, которые были использованы при записи файла.
File file = new File(Environment.getExternalStorageDirectory(), "raw.pcm"); //для хранения аудиоданных массив типа short //(звук 16-битный, поэтому выделяем по 2 байта на значение) int audioLength = (int)(file.length()/2); short[] audio = new short[audioLength]; DataInputStream dis = new DataInputStream( new BufferedInputStream(new FileInputStream(file))); int i = 0; while (dis.available() > 0) { audio[audioLength] = dis.readShort(); i++; } // Закрытие входящих потоков dis.close();
После инициализации объекта AudioTrack, чтобы начать асинхронное воспроизведение, необходимо вызвать метод play(). Метод write() позволяет добавить "сырые" аудиоданные в буфер проигрывателя.
audioTrack.play(); audioTrack.write(audio, 0, audioLength);
Запись в буфер объекта AudioTrack можно начать, как до вызова метода play, так и после. В первом случае воспроизведение пойдет сразу после вызова, во втором — звук станет проигрываться, как только данные запишутся в буфер AudioTrack.
Распознавание речи
Начиная с версии 1.5 (API Level 3) Android поддерживает голосовой ввод и распознавание речи и позволяет встраивать в приложения голосовой ввод.
Для распознавания речи необходимо создать intent-объект, используя константу ACTION_RECOGNIZE_SPEECH класса RecognizerIntent:
Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
зададим языковую модель распознавания входящего звука:
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
зададим строку, которая будет отображаться в окне голосового ввода, она должна предлагать пользователю сказать что-нибудь в микрофон:
intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "speak now");
ограничим количество результатов, которые могут быть возвращены при распознавании, зададим 1:
intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 1);
укажем языковую константу из класса Locale, чтобы задать язык для ввода, отличный от языка по умолчанию на данном устройстве:
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.ENGLISH);
Можно получить текущее значение по умолчанию, вызвав статический метод getDefault() из класса Locale.
После формирования intent-объекта передадим его в качестве параметра в метод startActivityForResult(), который вызывает стандартное диалоговое окно для распознавания речи:
startActivityForResult(intent, VOICE_RECOGNITION);
После завершения голосового ввода, движок для распознавания речи проанализирует и обработает записанный звук. Для получения результатов необходимо переопределить метод onActivityResult() активности, из которой был отправлен запрос на распознавание речи. В примере 11.6 показано переопределение метода onActivityResult().
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data){ if (requestCode == VOICE_RECOGNITION && resultCode == RESULT_OK){ ArrayList<String> results; results = data.getStringArrayListExtra( RecognizerIntent.EXTRA_RESULTS); // TODO Выполнить какие-то действия с распознанными строками } super.onActivityResult(requestCode, resultCode, data); }Пример 11.6.