Как записать голос на Android Things
Я работаю над Предварительным просмотром 2 SDK Android Things на RPi3. Пробовал Audio Recorder, а также Media Recorder, все еще не в состоянии захватить звук. Я пытаюсь преобразовать свою речь в текст. Обычное распознавание речи не поддерживается. У меня есть USB MIC, подключенный напрямую к RPi3, а также наушники MIC, подключенные к RPi3 через звуковую карту USB.
Код MediaRecorder:
private void startRecording() {
Log.d(TAG, "startRecording....");
mRecorder = new MediaRecorder();
Log.d(TAG, "startRecording: Audio Source"+MediaRecorder.getAudioSourceMax());
mRecorder.setAudioSource(MediaRecorder.AudioSource.UNPROCESSED);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.RAW_AMR);
mRecorder.setOutputFile(mFileName);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
try {
mRecorder.prepare();
} catch (IOException e) {
Log.e(TAG, "prepare() failed");
}
mRecorder.start();
}
private void stopRecording() {
// stops the recording activity
if (mRecorder != null) {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
}
}
Манифест Разрешения:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
Ошибка:
03-09 17:17:38.662 3970 3970 D MainActivity: onCreate
03-09 17:17:38.668 3970 3970 D MainActivity: startRecording....
03-09 17:17:38.672 3970 3970 D MainActivity: startRecording: Audio Source9
03-09 17:17:38.678 161 161 E AudioSystem: AudioSystem::getInputBufferSize failed sampleRate 8000 format 0x1 channelMask 10
03-09 17:17:38.678 161 161 E AudioRecord: AudioSystem could not query the input buffer size for sampleRate 8000, format 0x1, channelMask 0x10; status -22
03-09 17:17:38.678 161 161 E StagefrightRecorder: audio source is not initialized
03-09 17:17:38.678 3970 3970 E MediaRecorder: start failed: -2147483648
03-09 17:17:38.680 3970 3970 D AndroidRuntime: Shutting down VM
03-09 17:17:38.683 3970 3970 E AndroidRuntime: FATAL EXCEPTION: main
03-09 17:17:38.683 3970 3970 E AndroidRuntime: Process: com.example.androidthings.myproject, PID: 3970
03-09 17:17:38.683 3970 3970 E AndroidRuntime: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.androidthings.myproject/com.example.androidthings.myproject.MainActivity}: java.lang.RuntimeException: start failed.
03-09 17:17:38.683 3970 3970 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646)
03-09 17:17:38.683 3970 3970 E AndroidRuntime: at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707)
03-09 17:17:38.683 3970 3970 E AndroidRuntime: at android.app.ActivityThread.-wrap12(ActivityThread.java)
03-09 17:17:38.683 3970 3970 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
03-09 17:17:38.683 3970 3970 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:102)
03-09 17:17:38.683 3970 3970 E AndroidRuntime: at android.os.Looper.loop(Looper.java:154)
03-09 17:17:38.683 3970 3970 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6077)
03-09 17:17:38.683 3970 3970 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
03-09 17:17:38.683 3970 3970 E AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
03-09 17:17:38.683 3970 3970 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
03-09 17:17:38.683 3970 3970 E AndroidRuntime: Caused by: java.lang.RuntimeException: start failed.
03-09 17:17:38.683 3970 3970 E AndroidRuntime: at android.media.MediaRecorder.start(Native Method)
03-09 17:17:38.683 3970 3970 E AndroidRuntime: at com.example.androidthings.myproject.MainActivity.startRecording(MainActivity.java:181)
03-09 17:17:38.683 3970 3970 E AndroidRuntime: at com.example.androidthings.myproject.MainActivity.onCreate(MainActivity.java:63)
03-09 17:17:38.683 3970 3970 E AndroidRuntime: at android.app.Activity.performCreate(Activity.java:6662)
03-09 17:17:38.683 3970 3970 E AndroidRuntime: at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
03-09 17:17:38.683 3970 3970 E AndroidRuntime: at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
03-09 17:17:38.683 3970 3970 E AndroidRuntime: ... 9 more
3 ответа
Я начну с простой части. Поскольку службы распознавания речи недоступны в текущем предварительном просмотре, вам может потребоваться поиск альтернативных методов обработки речи в тексте в вашем приложении. Вот сообщение в блоге, которое может указать вам на некоторые варианты.
Что касается аудио записи, вот пара мыслей. Возможно, вам повезет больше, используя AudioSource.MIC
вместо этого в вашем коде. Я не проверял MediaRecorder
напрямую, но другое предложение будет использовать AudioRecord
непосредственно. Тем более что ваша цель - передать аудиоданные другому сервису для обработки (и, возможно, не просто сохранить их в файл). Это даст вам возможность работать с каждым сэмплированным аудиобуфером. Ниже приведен пример чего-то, что должно работать на устройстве Android Things для инициализации аудиозаписи:
// Audio recording parameters
private static final int SAMPLE_RATE = 44100;
private static final int ENCODING_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
private static final int CHANNEL_FORMAT = AudioFormat.CHANNEL_IN_MONO;
private AudioRecord mRecorder;
private final int mBufferSize = AudioRecord
.getMinBufferSize(SAMPLE_RATE, CHANNEL_FORMAT, ENCODING_FORMAT);
public void initAudioRecorder() {
if (mRecorder == null) {
try {
mRecorder = new AudioRecord.Builder()
.setAudioSource(MediaRecorder.AudioSource.MIC)
.setAudioFormat(new AudioFormat.Builder()
.setEncoding(ENCODING_FORMAT)
.setSampleRate(SAMPLE_RATE)
.setChannelMask(CHANNEL_FORMAT)
.build())
.setBufferSizeInBytes(2*mBufferSize)
.build();
mRecorder.startRecording();
} catch (UnsupportedOperationException e) {
Log.w(TAG, "Unable to initialize recording", e);
}
}
}
Каждое устройство может иметь разные настройки инициализации, поэтому вам нужно будет создать метод, который перебирает все возможные комбинации скоростей передачи, кодирование...:
private static int[] mSampleRates = new int[] { 8000, 11025, 22050, 44100 };
public AudioRecord findAudioRecord() {
for (int rate : mSampleRates) {
for (short audioFormat : new short[] { AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT }) {
for (short channelConfig : new short[] { AudioFormat.CHANNEL_IN_MONO, AudioFormat.CHANNEL_IN_STEREO }) {
try {
Log.d(C.TAG, "Attempting rate " + rate + "Hz, bits: " + audioFormat + ", channel: "
+ channelConfig);
int bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat);
if (bufferSize != AudioRecord.ERROR_BAD_VALUE) {
// check if we can instantiate and have a success
AudioRecord recorder = new AudioRecord(AudioSource.DEFAULT, rate, channelConfig, audioFormat, bufferSize);
if (recorder.getState() == AudioRecord.STATE_INITIALIZED)
return recorder;
}
} catch (Exception e) {
Log.e(C.TAG, rate + "Exception, keep trying.",e);
}
}
}
}
return null;
}
AudioRecord recorder = findAudioRecord();
recorder.release();
Я получил распознавание речи, работая с RPi 3 / Things Preview 2 / USB mic / Kõnele ( https://github.com/Kaljurand/K6nele), другими словами: Things Preview 2 поддерживает аудиозапись и SpeechRecognition (я полагаю, вы имею ввиду SpeechRecognizer).
Kõnele узнает эстонский язык из коробки. Если вам нужен другой язык, вам нужно изменить URL-адрес сервера в настройках Kõnele (или переопределить его с помощью "ee.ioc.phon.android.extra.SERVER_URL" EXTRA) и настроить сервер распознавания по этому URL-адресу. Самый простой способ запустить сервер описан здесь: https://github.com/jcsilva/docker-kaldi-gstreamer-server