- Работа с потоковым аудио
- Введение
- How to Record System Audio on Android
- Record System Audio Android Apps:
- [box type=”download” align=”aligncenter” width=””]Voice & Audio Recorder – ASR App[/box]
- [box type=”download” align=”aligncenter” width=””]HiFiCorder Record Android App[/box]
- Полный список
- Сколько байт занимает секунда звука
- Слушатель отданных фреймов
Работа с потоковым аудио
Введение
Конструктор
Для создания объекта нужно указать:
audioSource | Откуда ведётся запись. В нашем случае это MediaRecorder.AudioSource.MIC |
---|---|
sampleRateInHz | Частота дискретизации в герцах. Документация утверждает, что 44100Гц поддерживается всеми устройствами |
channelConfig | Конфигурация каналов. Может быть CHANNEL_IN_MONO или CHANNEL_IN_STEREO . Моно работает везде. Важно: эти константы не совпадают с количеством каналов, которое они обозначают. В этот параметр нельзя передавать 1 или 2. |
audioFormat | Формат входных данных, более известный как кодек. Может быть ENCODING_PCM_16BIT или ENCODING_PCM_8BIT |
bufferSizeInBytes | Размер того самого внутреннего буфера. Из него можно считывать аудиопоток. Размер порции считывания не должен превышать эту величину. У этого параметра есть минимально допустимое значение, которое можно получить через getMinBufferSize() . |
При своём создании объект пытается получить нужные ему ресурсы системы. Насколько удачно у него это получилось, можно узнать, вызвав функцию getState() . Если она вернёт STATE_INITIALIZED , то всё нормально, если STATE_UNINITIALIZED — значит, произошла ошибка.
Причин ошибки может быть две: слишком маленький буфер и недопустимый формат. Первого нужно избегать вызовом getMinBufferSize() . Второго, на самом деле, им же.
getMinBufferSize()
Этот статический метод выдаёт минимальный размер внутреннего буфера, при котором объект AudioRecord сможет работать. Параметры имеют тот же смысл, что и для конструктора. Следует заметить, что использование именно этой величины для записи — не лучшая идея. Если система будет ещё чем-то занята, то программа всё равно может не успевать считывать все данные подряд, и в записи будут дырки. Мне встречался совет брать размер в десять раз больше.
Получение списка форматов
Метод getMinBufferSize() имеет приятную особенность — ругаться на недопустимые для данного устройства параметры, возвращая ERROR_BAD_VALUE или ERROR . Это означает, что перебирая все возможные сочетания, можно узнать, какие форматы поддерживает устройство.
Считывание данных
Для получения данных из внутреннего буфера служит метод read() . Он существует в трёх вариантах:
- read(byte[] audioData, int offsetInBytes, int sizeInBytes)
- read(short[] audioData, int offsetInShorts, int sizeInShorts)
- read(ByteBuffer audioBuffer, int sizeInBytes)
Их параметры:
audioData | массив, в который будут записаны данные |
---|---|
audioBuffer | буфер, в который будут записаны данные |
offsetInBytes / offsetInShorts | индекс, с которого начнётся запись |
sizeInShorts | размер запрашиваемого блока данных. В байтах для ByteBuffer и byte[] , в коротких целых для short[] |
Если всё нормально, то метод вернёт количество прочитанных байт, если это вариант с ByteBuffer или byte[] , или прочитанных коротких целых для short[] . Если на момент вызова объект не был правильно инициализирован, то выдаст ERROR_INVALID_OPERATION, а если что-то не так с параметрами — ERROR_BAD_VALUE
Важно: метод блокирует вызывающий поток до тех пор, пока не считает запрошенное количество данных. Если во внутреннем буфере их недостаточно, то read() будет ожидать, пока они придут от микрофона. Поэтому метод следует вызывать из отдельного потока, иначе приложение будет висеть.
Подход, отход, фиксация
Чтобы программа могла получать данные от микрофона, нужно указать в файле AndroidManifest,xml соответствующее разрешение:
Чтобы начать запись, нужно вызвать метод startRecording() , а чтобы закончить — stop() . Запускать и останавливать запись можно сколько угодно раз.
После того, как работа с объектом закончена, следует вызвать метод release() . Он освободит все системные ресурсы, захваченные объектом. После этого объект нельзя использовать, а ссылающуюся на него переменную следует установить в null .
Важно: эти три метода, в отличие от упоминавшихся ранее, выбросят IllegalStateException , если их вызвать для неинициализированного (ну и слово. ) объекта или не в том порядке. Поэтому обращаться с ними нужно «аккуратно», т.е. через блок try .
Пример использования
Приведённый ниже класс делает всё то, о чём сказано выше. Кроме того, он посылает зарегистрированным у него Handler -ам сообщения о принятых данных. Эти данные будут обрабатываться в другом потоке, поэтому, чтобы не затереть ещё не обработанные данные новыми, использован циклический буфер.
В коде использован класс AudioFormatInfo . Он представляет собой POJO с тремя полями, описывающими формат записи: sampleRateInHz , channelConfig и audioFormat .
Источник
How to Record System Audio on Android
Nowadays, most of the smartphone devices are coming with the feature of call recording feature. By using which, you can record any calls from your phone. Some devices also allow you to record system audio using this feature. More than that, the Google Play Store also offers some audio recording apps to all the Android devices. We will also discuss here two best of the record system audio apps. Now, have a look at the discussion of the sound recording apps and keep using it on your device.
Record System Audio Android Apps:
[box type=”download” align=”aligncenter” width=””]Voice & Audio Recorder – ASR App[/box]
The Voice and Audio Recorder ASR is one of the apps which allows you to record the audio on your phone. This Android app is readily available on the Google Play Store for all the Android users.
This app supports for the most of the android phones and tablet devices. This app is one of the best voice recording apps among most of the apps. It comes without limitations for the recording time. It means you can record the sound for an unlimited time of recording.
The Voice and Audio Recorder app come with so many recording formats like WAV, OGG, FLAC, MP4, 3GP and more. So, by using this app, as per your wish, you can record the voice in any recording formats. It will record the sound with the better control of recording quality.
This audio recording app also has dedicated pause and discard button. It allows you to pause the recording anywhere and anytime. After recording the contents, you can also customize the folder in which the recorded files are saved.
The recording app will also allow you to share that recorded files to other using the social networking sites. By using the app, you can share multiple recording files in once.
You can also delete more than one files at a time using the delete option. It also has Echo cancellation mode, by activating which, you can cancel the echo mode. For the quick access to the app, it also has recording widget.
If you want to find any recorded files, by using the search option you can find it easily. It will also support multiple languages. The app has good users review ratings which are about of 4.0 out of 5.0.
Features of the Voice & Audio Recorder – ASR App
- One of the Best Voice Recording Apps
- No limitations for the recording time, you can record the sound for an unlimited time
- So many recording formats like WAV, OGG, FLAC, MP4, 3GP and more
- Record the sound with the better control of recording quality
- Dedicated Pause & Discard button for easy to use
- Allows you to customize recording folder
- Easy Sharing option to share the multiple recording files using the social networking sites
- Echo cancellation mode and Recording Widget for its easy access
[box type=”download” align=”aligncenter” width=””]HiFiCorder Record Android App[/box]
The HiFiCorder Record Android app is one of the excellent sound recording apps. It is designed with the simple interface as the audio recorder for the Android devices. Also of that, this app also allows you to edit the recorded audio after the recording. The editing of the recorded audio will take place along with the Visual Audio Editing.
In editing, you can graphically select any part of the recording. You can also use this audio recording app as a ringtone maker app and ringtone editor app. It can record the music and sound along with the high quality.
With the help of this android app, you can record the sounds in various sound quality. By choosing the recording quality from 48000 KHz to 44.1 MHz, you can record the high sounds. You can also record with the lowest quality of 8000 KHz. This app can record the sounds by staying in the background.
By which, you can use the app to listen to recordings while using the phone for other purposes. It permits you to save the recordings in such formats like OGG, AAC, and WAV formats.
After recording the sounds, you can also edit the title of it by choosing an option of Edit Title. As we discussed ago, you can also edit the recording using the Edit option. If you want to share the recording with others, then you can also do it using the Share option. It allows you to share the files via social sites and Email as well.
The app also provides you the backup option of the recording files. It allows you to backup the files from the Dropbox. It will help you when you delete any recording files by mistakenly.
This app is also one of the great apps to record some important voice notes. For the students, it is also useful to record the lecture notes.
On the Google Play Store, all the Android users can easily find this app. To use this Android app, you do not have to pay anything, because it is a free Android app. It is easily compatible with all of the Android smart mobiles as well as tablet devices.
Features of the HiFiCorder Record Android App
- Designed with the simple interface as the audio recorder for the Android Smartphones
- Allows you to edit the recorded audio using Visual Audio Editing
- Use this app as a Ringtone Maker App and Ringtone Editor App
- Sound Recording Quality from 48000 KHz to 44.1 MHz
- Save the recordings in formats like OGG, AAC, and WAV formats
- Share the recording files via Social Networking Sites and Email
- Auto Backup option using the Dropbox
So, now we are going to complete this discussion which is about of Record System Audio Android Apps. In which, we have discussed two best voice recording apps. As per your wish, you can use any of the apps from above mentioned.
We hope that this discussion will be very useful to you more than the recording feature. If it works for you, then also share it with your friends. Also of that, share with those, who really have need of it.
Источник
Полный список
— пишем звук с помощью AudioRecorder
Рассмотренный на прошлом уроке MediaRecorder записывал звук сразу в файл. AudioRecorder не пишет данные, а позволяет нам их получать в приложении. т.е. является посредником между приложением и микрофоном. Когда мы стартуем запись, AudioRecorder начинает получать данные с микрофона и хранит их у себя во внутреннем буфере. Мы можем при создании AudioRecorder указать желаемый размер этого буфера и далее запрашивать из него данные методом read.
Т.е. AudioRecorder будет полезен, если вы хотите как-то обработать данные перед записью в файл или, если вы хотите отправлять данные не в файл, а куда-либо еще.
Напишем приложение, в котором рассмотрим основные методы работы с AudioRecorder.
Project name: P1301_AudioRecorder
Build Target: Android 2.3.3
Application name: AudioRecorder
Package name: ru.startandroid.develop.p1301audiorecorder
Create Activity: MainActivity
Добавим строки в strings.xml:
Нарисуем экран main.xml:
Верхние кнопки стартуют/останавливают запись звука с микрофона в AudioRecorder, нижние – чтение данных из AudioRecorder в наш буфер.
В манифесте добавьте разрешение на запись звука: android.permission.RECORD_AUDIO.
В onCreate мы вызываем свой метод создания AudioRecorder и выводим в лог состояние созданного объекта. Состояние можно получить методом getState. Может быть всего два состояния: STATE_INITIALIZED и STATE_UNINITIALIZED. Означают они соответственно то, что AudioRecorder к работе готов или не готов.
В createAudioRecorder создаем AudioRecorder. Для этого нам понадобится несколько входных параметров:
— источник звука
— сэмплрейт
— режим каналов моно/стерео
— формат аудио
— размер буфера
Сэмплрейт мы ставим 8000. Режим — моно. Формат аудио – 16 бит. Чтобы узнать размер буфера, есть метод getMinBufferSize. Он, исходя из переданных ему на вход данных о формате аудио, возвращает минимально-возможный размер буфера, с которым сможет работать AudioRecorder. Мы получаем минимальный размер и в переменную internalBufferSize помещаем этот размер, умноженный на 4. Такой размер буфера будет в созданном AudioRecord.
Далее создаем AudioRecord. В качестве источника звука указываем микрофон. Также указываем сэмплрейт, режим каналов, формат и размер буфера.
В методе recordStart стартуем запись методом startRecording. С помощью метода getRecordingState получаем статус — идет запись или нет. Вариантов тут два: RECORDSTATE_RECORDING (запись идет) и RECORDSTATE_STOPPED (запись остановлена).
В recordStop останавливаем запись методом stop.
В readStart ставим метку isReading в true. Она будет означать, что мы сейчас находимся в режиме чтения данных из AudioRecorder. Далее создаем новый поток и чтение выполняем в нем, чтобы не занимать основной поток. Мы создаем свой буфер размером myBufferSize и читаем в него данные методом read. Это происходит в цикле, который проверяет, что мы в режиме чтения. Метод read на вход принимает массив (в который будут помещены данные), отступ (если вам надо прочесть данные не сначала, а с какой-то позиции), и размер порции получаемых данных. В readCount метод read возвращает число байт, которые он нам отдал. В totalCount мы суммируем общее количество полученных байтов.
У метода read кстати есть еще несколько реализаций, если эта вам не подходит. Подробнее смотрите в хелпе.
В методе readStop мы выключаем режим чтения, присваивая переменной isReading значение false. Поток из readStart прочтет это значение, выйдет из цикла и завершит свою работу.
В onDestroy выключаем режим чтения и методом release освобождаем ресурсы, занятые AudioRecord.
Все сохраняем, запускаем приложение.
В логах мы видим
minInternalBufferSize = 1024, internalBufferSize = 4096, myBufferSize = 8192
init state = 1
Мы видим, что минимальный размер буфера AudioRecorder насчитал равным 1024. Внутренний буфер будет 4096. Размер нашего буфера будет 8192. Состояние рекордера = 1, это значение переменной STATE_INITIALIZED, значит все ок, к работе готов.
Жмем Start record.
record start
recordingState = 3
Состояние записи рекордера = 3, это значение переменной RECORDSTATE_RECORDING, значит все ок, запись идет.
AudioRecorder сейчас получает данные с микрофона и держит их в своем буфере. Попробуем прочесть эти данные. Жмем Start read, и через несколько секунд Stop read
14:03:48.519: D/myLogs(14361): read start
14:03:48.519: D/myLogs(14361): readCount = 4096, totalCount = 4096
14:03:48.779: D/myLogs(14361): readCount = 4096, totalCount = 8192
14:03:49.039: D/myLogs(14361): readCount = 4096, totalCount = 12288
14:03:49.289: D/myLogs(14361): readCount = 4096, totalCount = 16384
14:03:49.549: D/myLogs(14361): readCount = 4096, totalCount = 20480
14:03:49.809: D/myLogs(14361): readCount = 4096, totalCount = 24576
14:03:50.069: D/myLogs(14361): readCount = 4096, totalCount = 28672
14:03:50.319: D/myLogs(14361): readCount = 4096, totalCount = 32768
14:03:50.569: D/myLogs(14361): readCount = 4096, totalCount = 36864
14:03:50.829: D/myLogs(14361): readCount = 4096, totalCount = 40960
14:03:51.079: D/myLogs(14361): readCount = 4096, totalCount = 45056
14:03:51.179: D/myLogs(14361): read stop
14:03:51.339: D/myLogs(14361): readCount = 4096, totalCount = 49152
Видим, что прошло несколько чтений буфера. Таким образом, мы получали данные с микрофона с помощью AudioRecorder.
Сколько байт занимает секунда звука
Разберемся, как подсчитать сколько места занимает звук, когда его пишешь. Вспоминаем наши параметры, которые мы задавали при создании AudioRecorder: сэмплрейт (как часто считывается звук) = 8000 Hz, формат (сколько места занимает одна запись) = 16 бит, канал = моно. Эти параметры означают, что одна секунда звука будет занимать 8000 * 16 * 1 = 128 000 бит = 16 000 байт.
Теперь посмотрим на логи. Первое чтение звука было в 14:03:48.519, а последнее в 14:03:51.339. Т.е. мы писали звук примерно три секунды. Три секунды – это 16 000 * 3 = 48 000 байт.
Снова смотрим логи, последнее значение totalCount = 49 152. Как видите, расчетная и реальная цифры похожи.
Давайте поменяем параметры в методе createAudioRecorder:
и снова посчитаем:
22 050 (сэмплрейт) * 16 (формат) * 2 (стерео) = 705 600 бит = 88 200 байт занимает теперь секунда звука. Как видите, при улучшении качества увеличились размеры.
Все сохраним, запускаем приложение. Жмем Start record, затем Start read и секунды через три Stop read.
14:15:29.959: D/myLogs(14567): read start
14:15:29.969: D/myLogs(14567): readCount = 8192, totalCount = 8192
14:15:29.969: D/myLogs(14567): readCount = 8192, totalCount = 16384
14:15:30.069: D/myLogs(14567): readCount = 8192, totalCount = 24576
…
14:15:32.479: D/myLogs(14567): readCount = 8192, totalCount = 237568
14:15:32.579: D/myLogs(14567): readCount = 8192, totalCount = 245760
14:15:32.659: D/myLogs(14567): read stop
14:15:32.669: D/myLogs(14567): readCount = 8192, totalCount = 253952
Видим, что примерно за 3 секунды мы считали 253 952 байта. Смотрим наши подсчеты 88 200 * 3 = 264 600. Цифры снова близки.
Это было небольшое отступление от темы урока, чтобы вы имели представление о взаимосвязи таких параметров как время, сэмплрейт, формат, каналы, байты.
Слушатель отданных фреймов
Когда AudioRecorder отдает нам данные, он ведет подсчет отданных фреймов. Фрейм – это единица записи звука. Сколько байт занимает один фрейм? Это мы уже считали чуть раньше – формат * режим каналов. Т.е. если мы пишем звук в формате 16 бит/моно, то фрейм займет 16 * 1 = 16 бит = 2 байта.
Мы можем на AudioRecorder повесить слушателя с парой методов. Один метод будет срабатывать периодически через каждое указанное кол-во отданных фреймов, а другой разово по достижению определенного кол-ва отданных фреймов.
Метод setRecordPositionUpdateListener устанавливает слушателя с методами onPeriodicNotification и onMarkerReached, которые я описал выше. Метод setPositionNotificationPeriod устанавливает кол-во фреймов для срабатывания onPeriodicNotification, а setNotificationMarkerPosition – для срабатывания onMarkerReached.
Т.е. метод onPeriodicNotification будет срабатывать каждые 1000 отданных фреймов. А onMarkerReached – по достижению 10000 отданных фреймов. В onMarkerReached мы остановим чтение.
Все сохраним, запустим приложение и жмем Start record, затем Start read. В этот раз мы можем вручную не останавливать процесс чтения, т.к. он остановится сам по достижении 10000 фреймов.
read start
readCount = 4096, totalCount = 4096
onPeriodicNotification
onPeriodicNotification
onPeriodicNotification
readCount = 4096, totalCount = 8192
onPeriodicNotification
onPeriodicNotification
onPeriodicNotification
readCount = 4096, totalCount = 12288
onPeriodicNotification
onPeriodicNotification
readCount = 4096, totalCount = 16384
onPeriodicNotification
onMarkerReached
onPeriodicNotification
readCount = 4096, totalCount = 20480
Видим, что onPeriodicNotification срабатывал примерно каждые 2000 байт, а onMarkerReached сработал около получения 20000 байт.
Вспоминаем, что один фрейм при текущих настройках занимает два байта. А значит, как мы и указали, метод onPeriodicNotification срабатывал каждые 1000 фреймов, а onMarkerReached – как только было получено 10000 фреймов
На следующем уроке:
— получаем фото и видео, используя системное приложение
Присоединяйтесь к нам в Telegram:
— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.
— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование
— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня
— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме
Источник