Home | History | Annotate | Download | only in srec
      1 /*---------------------------------------------------------------------------*
      2  *  MicrophoneInputStream.java                                               *
      3  *                                                                           *
      4  *  Copyright 2007 Nuance Communciations, Inc.                               *
      5  *                                                                           *
      6  *  Licensed under the Apache License, Version 2.0 (the 'License');          *
      7  *  you may not use this file except in compliance with the License.         *
      8  *                                                                           *
      9  *  You may obtain a copy of the License at                                  *
     10  *      http://www.apache.org/licenses/LICENSE-2.0                           *
     11  *                                                                           *
     12  *  Unless required by applicable law or agreed to in writing, software      *
     13  *  distributed under the License is distributed on an 'AS IS' BASIS,        *
     14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
     15  *  See the License for the specific language governing permissions and      *
     16  *  limitations under the License.                                           *
     17  *                                                                           *
     18  *---------------------------------------------------------------------------*/
     19 
     20 
     21 package android.speech.srec;
     22 
     23 import java.io.IOException;
     24 import java.io.InputStream;
     25 import java.lang.IllegalStateException;
     26 
     27 
     28 /**
     29  * PCM input stream from the microphone, 16 bits per sample.
     30  */
     31 public final class MicrophoneInputStream extends InputStream {
     32     static {
     33         System.loadLibrary("srec_jni");
     34     }
     35 
     36     private final static String TAG = "MicrophoneInputStream";
     37     private int mAudioRecord = 0;
     38     private byte[] mOneByte = new byte[1];
     39 
     40     /**
     41      * MicrophoneInputStream constructor.
     42      * @param sampleRate sample rate of the microphone, typically 11025 or 8000.
     43      * @param fifoDepth depth of the real time fifo, measured in sampleRate clock ticks.
     44      * This determines how long an application may delay before losing data.
     45      */
     46     public MicrophoneInputStream(int sampleRate, int fifoDepth) throws IOException {
     47         mAudioRecord = AudioRecordNew(sampleRate, fifoDepth);
     48         if (mAudioRecord == 0) throw new IOException("AudioRecord constructor failed - busy?");
     49         int status = AudioRecordStart(mAudioRecord);
     50         if (status != 0) {
     51             close();
     52             throw new IOException("AudioRecord start failed: " + status);
     53         }
     54     }
     55 
     56     @Override
     57     public int read() throws IOException {
     58         if (mAudioRecord == 0) throw new IllegalStateException("not open");
     59         int rtn = AudioRecordRead(mAudioRecord, mOneByte, 0, 1);
     60         return rtn == 1 ? ((int)mOneByte[0] & 0xff) : -1;
     61     }
     62 
     63     @Override
     64     public int read(byte[] b) throws IOException {
     65         if (mAudioRecord == 0) throw new IllegalStateException("not open");
     66         return AudioRecordRead(mAudioRecord, b, 0, b.length);
     67     }
     68 
     69     @Override
     70     public int read(byte[] b, int offset, int length) throws IOException {
     71         if (mAudioRecord == 0) throw new IllegalStateException("not open");
     72         // TODO: should we force all reads to be a multiple of the sample size?
     73         return AudioRecordRead(mAudioRecord, b, offset, length);
     74     }
     75 
     76     /**
     77      * Closes this stream.
     78      */
     79     @Override
     80     public void close() throws IOException {
     81         if (mAudioRecord != 0) {
     82             try {
     83                 AudioRecordStop(mAudioRecord);
     84             } finally {
     85                 try {
     86                     AudioRecordDelete(mAudioRecord);
     87                 } finally {
     88                     mAudioRecord = 0;
     89                 }
     90             }
     91         }
     92     }
     93 
     94     @Override
     95     protected void finalize() throws Throwable {
     96         if (mAudioRecord != 0) {
     97             close();
     98             throw new IOException("someone forgot to close MicrophoneInputStream");
     99         }
    100     }
    101 
    102     //
    103     // AudioRecord JNI interface
    104     //
    105     private static native int AudioRecordNew(int sampleRate, int fifoDepth);
    106     private static native int AudioRecordStart(int audioRecord);
    107     private static native int AudioRecordRead(int audioRecord, byte[] b, int offset, int length) throws IOException;
    108     private static native void AudioRecordStop(int audioRecord) throws IOException;
    109     private static native void AudioRecordDelete(int audioRecord) throws IOException;
    110 }
    111