Опубликован: 06.05.2014 | Доступ: свободный | Студентов: 2640 / 618 | Длительность: 10:33:00
Лекция 6:

Работа с аудио и видеоинформацией в приложениях для смартфона, использование 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.