bisonfute
bisonfute

Reputation: 101

audiorecord android wear values 0

I am trying to get the volume from my Android Wear watch : MOTO 360. But, I only get 0 PCM values from Audiorecord.read.....

I run the record process in a separate thread. Below is an extract of my code, do you have any idea what I am doing wrong ?

A big thank for your help

jn.

REREDIT : new result with the MOTO. It looks really really weird!

03-15 20:38:08.740 1420-3994/? W/mot_vr_audio_hw﹕ Not allowing wake() since DSP is disabled

RE-EDIT : I tried my code with a different WATCH (Sony). The logs are more explicit

03-08 22:11:40.342 1165-1650/? D/MICRO﹕ WILL RECORD AT 44100Hz IN A BUFFER OF 15052

03-08 22:11:40.343 153-153/? E/AudioPolicyManager﹕ startInput(21) failed: other input 19 already started

03-08 22:11:40.343 1165-1650/? E/AudioRecord﹕ start() status -38

This error seems to be triggered when 2 audiorecord objects are active at the same time. But I am quite sure mine is only started once. Do you think it could be a System Audiorecord object that prevents mine from being launched?

EDIT : I do have this in my wear manifest uses-permission 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;
}

Upvotes: 0

Views: 741

Answers (1)

Benjamin
Benjamin

Reputation: 76

More of your code would be helpful. But it sounds like the mic is already in use. I ran into some of these problems as well. If you are running this in a thread you might accidentally be starting multiple threads. Also if you are running this in a service you might be starting multiple services. Now if you do a Google search, "can multiple instances of the same service be running", you will find a lot of people who say no. But the fact of the matter is yes, you can have multiple instances of the same service running at the same time. My advice is to Log.d a random number on each record loop. To make sure only one thread is working at a time

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;
}

Another thing which can cause you to be unable to access the recorder on android Wear is if the watch is listening for "OK Google" So if you try to capture audio while the watch is in a state that will respond to "OK Google" the audio record won't work.

Here is a good way to see if the Mic is available

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 Also calling Thread.sleep(10); in between each read call is useless as the read method is blocking. If it has nothing to offer it will wait and then return when it is ready.

Upvotes: 1

Related Questions