AudioRecord.StartRecording () - это исключение Java.Lang.IllegalException, говорящее, что неинициализированный AudioRecorder - PullRequest
0 голосов
/ 28 мая 2019

Я пытаюсь прочитать аудио как 16-битные целые числа в моем приложении для Android. Я написал это приложение, используя Xamarin.android. Я использую AudioRecord библиотеки низкого уровня для этого, потому что мне нужно читать необработанные байты с микрофона телефона, а не операции высокого уровня.

В функции StartRecording () есть исключение из Java, говорящее, что Uninitialized AudioRecord.

AudioRecord au = new AudioRecord(AudioSource.Mic, 44100, ChannelIn.Mono, Android.Media.Encoding.Pcm16bit, buffer.Length);
au.StartRecording(); //<-- Here 
                     //(Java.Lang.IllegalStateException: startRecording() 
                     // called on an uninitialized AudioRecord.)

Я бросил несколько qns в переполнение стека и попытался освободить все предыдущие выделения в блоке try catch. Проблема все еще сохраняется.

AudioRecord au = new AudioRecord(AudioSource.Mic, 44100, ChannelIn.Mono, Android.Media.Encoding.Pcm16bit, buffer.Length);
            try {
                au.StartRecording();
                au.Read(buffer, 0, buffer.Length);
            }
            catch (Java.Lang.IllegalStateException e ) {
                au.Release();
                au = new AudioRecord(AudioSource.Mic, 44100, ChannelIn.Mono, Android.Media.Encoding.Pcm16bit, buffer.Length);
                au.StartRecording();
                au.Read(buffer, 0, buffer.Length);
            }

Это мой полный код в отдельном кодовом файле.

using System;
using System.Text;
using System.Collections.Generic;
using Android.Media;
namespace core
{
    public static class RawAudioInput
    {
        public static List<short> Listen()
        {
            int bufferSizeInBytes = AudioRecord
            .GetMinBufferSize(44100, ChannelIn.Mono,
                    Android.Media.Encoding.Pcm16bit);
            byte[] buffer = new byte[bufferSizeInBytes];
            AudioRecord au = new AudioRecord(AudioSource.Mic, 44100, ChannelIn.Mono, Android.Media.Encoding.Pcm16bit, buffer.Length);
            try {
                au.StartRecording();
                au.Read(buffer, 0, buffer.Length);
            }
            catch (Java.Lang.IllegalStateException e ) {
                au.Release();
                au = new AudioRecord(AudioSource.Mic, 44100, ChannelIn.Mono, Android.Media.Encoding.Pcm16bit, buffer.Length);
                au.StartRecording();//<-- (Java.Lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord.)
                au.Read(buffer, 0, buffer.Length);
            }
            au.Stop();
            List<short> result = new List<short>();
            for (int i = 0; i < buffer.Length; i += 2)
            {
                result.Add(BitConverter.ToInt16(buffer, i));
            }
            au.Release();
            return result;
        }
    }

}

Я не понимаю, где я делаю что-то не так. Пожалуйста, помогите мне решить эту проблему.

Редактировать Мне удалось получить полную трассировку стека исключения из System.Diagnostics.Debug.WriteLine () Вот оно:

[0:] Java.Lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord.
  at Java.Interop.JniEnvironment+InstanceMethods.CallVoidMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x00069] in <286213b9e14c442ba8d8d94cc9dbec8e>:0 
  at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeVirtualVoidMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue* parameters) [0x0002a] in <286213b9e14c442ba8d8d94cc9dbec8e>:0 
  at Android.Media.AudioRecord.StartRecording () [0x0000a] in <b781ed64f1d743e7881ac038e0fbdf85>:0 
  at core.RawAudioInput.Listen () [0x00028] in C:\Users\aditya_nadig\source\repos\RawAudio\RawAudio\RawAudioInput.cs:17 
  at RawAudio.MainActivity.OnRecordButtonClick (System.Object sender, System.EventArgs e) [0x00004] in C:\Users\aditya_nadig\source\repos\RawAudio\RawAudio\MainActivity.cs:31 
  --- End of managed Java.Lang.IllegalStateException stack trace ---
java.lang.IllegalStateException: startRecording() called on an uninitialized AudioRecord.
    at android.media.AudioRecord.startRecording(AudioRecord.java:1011)
    at mono.android.view.View_OnClickListenerImplementor.n_onClick(Native Method)
    at mono.android.view.View_OnClickListenerImplementor.onClick(View_OnClickListenerImplementor.java:30)
    at android.view.View.performClick(View.java:6993)
    at android.widget.TextView.performClick(TextView.java:12752)
    at android.view.View$PerformClick.run(View.java:26512)
    at android.os.Handler.handleCallback(Handler.java:790)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:7025)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)

1 Ответ

0 голосов
/ 29 мая 2019

StartRecording следует вызывать в отдельном потоке. Вы должны использовать Async Task.it и достичь AudioManager в своем коде. Вот простая демонстрация, вы можете обратиться к ней. https://developer.xamarin.com/samples/monodroid/Example_WorkingWithAudio/

обновление

И не забудьте запросить эти разрешения в AndroidManifest ,

"android.permission.MODIFY_AUDIO_SETTINGS" "Android.permission.READ_EXTERNAL_STORAGE" "Android.permission.WRITE_EXTERNAL_STORAGE"
"Android.permission.RECORD_AUDIO"

...