аудиозапись значений износа Android 0

Я пытаюсь получить громкость от своих часов Android Wear: MOTO 360. Но я получаю только 0 значений PCM от Audiorecord.read .....

Я запускаю процесс записи в отдельном потоке. Ниже приведен фрагмент моего кода, вы знаете, что я делаю неправильно?

Большое спасибо за вашу помощь

jn.

REREDIT: новый результат с MOTO. Выглядит действительно очень странно!

03-15 20:38:08.740 1420-3994/? W/mot_vr_audio_hw﹕ Не разрешать wake(), так как DSP отключен

ПОВТОРНОЕ РЕДАКТИРОВАНИЕ: я попробовал свой код с другими ЧАСАМИ (Sony). Журналы более явные

03-08 22:11:40.342 1165-1650/? D/MICRO﹕ БУДЕТ ЗАПИСАТЬ НА ЧАСТОТЕ 44100 Гц В БУФЕРЕ 15052

03-08 22:11:40.343 153-153/? E/AudioPolicyManager﹕ startInput(21) не удалось: другой ввод 19 уже запущен

03-08 22:11:40.343 1165-1650/? Статус E/AudioRecord﹕ start() -38

Эта ошибка, по-видимому, возникает, когда одновременно активны 2 объекта аудиозаписи. Но я совершенно уверен, что мой запускается только один раз. Как вы думаете, это может быть объект System Audiorecord, который препятствует запуску моего?

РЕДАКТИРОВАТЬ: у меня есть это в моем манифесте износа, использует разрешение android:name=android.permission.RECORD_AUDIO

private int sampleRateInHz = 8000;
private int channelConfig = AudioFormat.CHANNEL_IN_MONO;
private int audioFormat = AudioFormat.ENCODING_PCM_16BIT;

public void run(){

    running=true;
    bufferSize = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
    recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,sampleRateInHz, channelConfig, audioFormat, bufferSize);
    Log.d(TAG,"WILL RECORD AT "+sampleRateInHz+"Hz IN A BUFFER OF "+bufferSize);
    recording=true;

    try{
        while (recording){

            if ((recorder.getState()==android.media.AudioRecord.STATE_INITIALIZED)&&(recorder.getRecordingState()==android.media.AudioRecord.RECORDSTATE_STOPPED)){
                recorder.startRecording();
                Log.d(TAG,"START RECORDING DUDE");
            }

            int theVolume = getVolume(sampleRateInHz, bufferSize);

            Thread.sleep(10);
        }
        if (!recording){
            Thread.currentThread().interrupt();
            Log.d(TAG,"MIC THREAD STOPPED");
        }

    }catch (InterruptedException e){
        e.printStackTrace();
    }

private int getVolume(int sampleRate, int bufferSize){
    short[] audioData = new short [bufferSize];

    int nbOfSamples = recorder.read(audioData,0,bufferSize);

    int numSamples = audioData.length;
    int numCrossing = 0;
    double volume = 0;
    for (int p = 0; p < numSamples-1; p++){
        volume += audioData[p]*audioData[p];
    }

    Log.d(TAG,"volume from pcm: "+volume);
    volume = Math.sqrt(volume/nbOfSamples);


    currentVolume = (int) (0.5*currentVolume+ 0.5*volume);
    Log.d(TAG,"currentVolume: "+currentVolume);

    return currentVolume;
}

person bisonfute    schedule 06.03.2015    source источник


Ответы (1)


Больше вашего кода было бы полезно. Но похоже, что микрофон уже используется. Я тоже столкнулся с некоторыми из этих проблем. Если вы запускаете это в потоке, вы можете случайно запустить несколько потоков. Кроме того, если вы используете это в службе, вы можете запускать несколько служб. Теперь, если вы выполните поиск в Google «могут ли работать несколько экземпляров одной и той же службы», вы найдете много людей, которые скажут «нет». Но дело в том, что да, у вас может быть несколько экземпляров одной и той же службы, работающих одновременно. Мой совет: Log.d произвольное число в каждом цикле записи. Чтобы убедиться, что одновременно работает только один поток

public void run(){
    int randThreadNumber = randInt(0,100);
    while (recording) {
        Log.d("MYTAG", "Rand number " + randThreadNumber);
        ..........more code.............
    }
    ..........more code.............
}

public static int randInt(int min, int max) {
    Random rand = new Random();
    int randomNum = rand.nextInt((max - min) + 1) + min;

    return randomNum;
}

Еще одна вещь, которая может привести к тому, что вы не сможете получить доступ к диктофону на Android Wear, — это если часы прослушивают «OK Google». Поэтому, если вы попытаетесь записать звук, когда часы находятся в состоянии, которое будет реагировать на «OK Google», аудиозапись не работает.

Вот хороший способ узнать, доступен ли микрофон

while(recording)
{
    readResult = audio_recorder.read(buf, 0, buf.length);

    //See if read worked
    if(readResult != -3) {
        // yay it worked. Do stuff
    } else {
        // if result is -3 then the watch's mic was inaccessible, wait then retry
        Log.d(TAG, "Waiting for Watch to give up Microphone");
        try {
            Thread.sleep(100, 0);
            audio_recorder.startRecording(); // restart audio recording
        } catch(Exception e) {
            Log.e(TAG, "exception", e); // Error trying to sleep thread
        }
    }
}

EDIT Также вызов Thread.sleep(10); между каждым вызовом чтения бесполезен, так как метод чтения блокируется. Если ему нечего предложить, оно подождет и вернется, когда будет готово.

person Benjamin    schedule 13.03.2015
comment
спасибо за отличный ответ! Я попробую ваш совет по случайным числам, это очень хороший совет. Я также запишу readresult=-3, чтобы не уловить эту проблему. Я сообщу вам результаты. Интересным моментом является то, что я пробовал использовать тот же код на другом устройстве (Sony SmartWatch 3), и у меня НЕТ ПРОБЛЕМ с доступом к микрофону». - person bisonfute; 15.03.2015
comment
Я не понял смысла вашего EDIT. Я заставляю поток спать ПОСЛЕ read(). Потому что мне не нужна очень высокая частота дискретизации микрофона. Я read() блокирует, хорошо, но я хочу сделать паузу на минимальное время (может быть больше, если read() блокирует) перед повторным запуском read() ). Я где-то ошибся? - person bisonfute; 15.03.2015
comment
Я попытался прочитать результат audiorecord.read(), и он дает мне большое положительное число, например 1323. Я думаю, это означает, что все вроде бы правильно. Но сегодня у меня новая ОШИБКА: 03-15 20:38:08.740 1420-3994/? W/mot_vr_audio_hw﹕ Не разрешать wake(), так как DSP отключен - person bisonfute; 15.03.2015
comment
@bisonfute Если у вас все еще есть проблемы, вы можете написать мне в google plus plus.google.com/+BenjaminNykiel и я могу отправить вам приложение, которое я сделал, которое использует AudioRecord, если хотите, просто чтобы посмотреть, работает ли мое приложение. Если да, то я знаю, что могу тебе помочь. Однако я не тестировал свое приложение на Moto 360, поэтому оно может не работать на ваших часах. В таком случае я не смогу помочь. В любом случае это поможет нам обоим, так как я хотел бы знать, не работает ли мое приложение на Moto. - person Benjamin; 21.03.2015