Android AudioRecord.read returns an array of 0 items
Asked Answered
B

0

8

What I'm trying to do: I'm trying to write a program that reads audio from the android microphone (without recording) and captures some measure of how loud it is using a service. For now I'm sending a pulse from my activity to my service to get a quick sound reading and checking the Logcat printout of the amplitude as my volumeter.

My problem: The read method of AudioRecord returns 0.

What I've tried: Recording full audio instead of using the NullOutputStream does not make a difference. Some earlier versions randomly started working after some trivial changes like a logcat call was added and then stopped working later.

My thoughts: I thought originally that maybe the microphone was being used by another application, but it still returns 0 even when this is the only notable service running.

my service:

import org.apache.commons.io.output.NullOutputStream;


public class RecordingService extends Service {

public static final int SAMPLE_RATE = 16000;

private AudioRecord mRecorder;
private File mRecording;
private short[] mBuffer;

public static final NullOutputStream NULL_OUTPUT_STREAM = new NullOutputStream();

public double amplitude = 0.0;

public String TAG = "TAG";

public void onCreate() {
    super.onCreate();
}

public int onStartCommand(Intent intent, int flags, int startId){

    initRecorder();
    mRecorder.startRecording();
    mRecording = getFile("raw");
    startBufferedWrite(mRecording, intent);
    mRecorder.stop();
    mRecorder.release();
    stopSelf();

    return START_STICKY;
}

private void initRecorder() {
    int bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO,
            AudioFormat.ENCODING_PCM_16BIT);
    mBuffer = new short[bufferSize];
    mRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO,
            AudioFormat.ENCODING_PCM_16BIT, bufferSize);
}

private void startBufferedWrite(final File file, Intent intent) {
    Log.i(TAG, "WRITING");
    new Thread(new Runnable() {
        @Override
        public void run() {
            DataOutputStream output = null;
            Log.i(TAG, "running");
            try {
                output = new DataOutputStream(NULL_OUTPUT_STREAM);
                Log.i(TAG, "outputset");
                double sum = 0;
                //problems!
                Log.i(TAG, "mBufferlength= " + mBuffer.length);
                int readSize = mRecorder.read(mBuffer, 0, mBuffer.length);
                Log.i(TAG, "readSize1= " + readSize);
                Log.i(TAG, mBuffer.toString());
                //problems!
                Log.i(TAG, "read");
                for (int i = 0; i < readSize; i++) {
                    output.writeShort(mBuffer[i]);
                    sum += mBuffer[i] * mBuffer[i];
                }
                Log.i(TAG, "summed up");
                if (readSize > 0) {
                    Log.i(TAG, "readSize2= "+readSize);

                    Log.i(TAG, "setting progress");
                    amplitude = sum / readSize;
                    Log.i(TAG, "amplitude= " + amplitude);
                    Log.i(TAG, "sqrt= " + Math.sqrt(amplitude));

                }
                else {
                    Log.i(TAG, "readsize <= 0");

                }

            } catch (IOException e) {
                Log.e(TAG, e.getMessage());
            } finally {
                if (output != null) {
                    try {
                        output.flush();
                    } catch (IOException e) {
                        Log.e(TAG, e.getMessage());

                    } finally {
                        try {
                            output.close();
                        } catch (IOException e) {
                            Log.e(TAG, e.getMessage());
                        }
                    }
                }
            }
        }
    }).start();
}

private File getFile(final String suffix) {
    Time time = new Time();
    time.setToNow();
    return new File(Environment.getExternalStorageDirectory(), time.format("%Y%m%d%H%M%S") + "." + suffix);
}

public void onDestroy() {
    super.onDestroy();
}

@Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return null;
}
}

my activity:

public class RecordingActivity extends Activity {

private final String startRecordingLabel = "Start recording";

public String TAG = "TAG";

@Override
public void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    final Button button = (Button) findViewById(R.id.button);
    button.setText(startRecordingLabel);

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(final View v) {
                Intent intent = new Intent(RecordingActivity.this, RecordingService.class);
                Toast.makeText(RecordingActivity.this, "started", Toast.LENGTH_SHORT).show();
                RecordingActivity.this.startService(intent);                
                }

    });
}


@Override
public void onDestroy() {
    super.onDestroy();
}

}

It's my first post, but I'm hoping that it's easy to follow. Thank you!

Balsaminaceous answered 27/5, 2013 at 1:33 Comment(1)
Full file for the working project can be found here -> github.com/TitaniumJellyfish/StudyBuddy/blob/…. My guess is that the problem was that I was stopping audio recorder immediately after starting the thread. I moved the thread to a daemon using a state system to manage whether the recorder was running or not.Balsaminaceous

© 2022 - 2024 — McMap. All rights reserved.