diff --git a/src/com/android/speechrecorder/MicrophoneInputStream.java b/src/com/android/speechrecorder/MicrophoneInputStream.java
new file mode 100644
index 0000000..ab1f475
--- /dev/null
+++ b/src/com/android/speechrecorder/MicrophoneInputStream.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.speechrecorder;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import android.media.AudioRecord;
+
+import static android.media.AudioFormat.CHANNEL_IN_MONO;
+import static android.media.AudioFormat.ENCODING_PCM_16BIT;
+import static android.media.MediaRecorder.AudioSource.VOICE_RECOGNITION;
+
+/**
+ * Provides an InputStream like API over {@code android.media.AudioRecord}.
+ *
+ * <b>Not thread safe.</b>
+ */
+public final class MicrophoneInputStream extends InputStream {
+
+    private final int mSampleRate;
+    private final int mBufferSize;
+    private final AudioRecord mAudioRecord;
+
+    private boolean mRecording;
+
+    public MicrophoneInputStream(int sampleRate) throws IOException {
+        mSampleRate = sampleRate;
+        mBufferSize = AudioRecord.getMinBufferSize(sampleRate,
+            CHANNEL_IN_MONO, ENCODING_PCM_16BIT);
+        mAudioRecord = createAudioRecord();
+        mRecording = false;
+    }
+
+    private AudioRecord createAudioRecord() throws IOException {
+        AudioRecord ar = new AudioRecord(VOICE_RECOGNITION,
+            mSampleRate, CHANNEL_IN_MONO, ENCODING_PCM_16BIT, mBufferSize);
+
+        if (ar.getState() != AudioRecord.STATE_INITIALIZED) {
+            ar.release();
+            throw new IOException("Unable to create AudioRecord");
+        }
+
+        return ar;
+    }
+
+    private void maybeStartRecording() throws IOException {
+        if (mRecording) {
+            return;
+        }
+
+        mAudioRecord.startRecording();
+
+        int recordingState = mAudioRecord.getRecordingState();
+        if (recordingState != AudioRecord.RECORDSTATE_RECORDING) {
+            throw new IOException("Unexpected recordingState: " + recordingState);
+        }
+        mRecording = true;
+    }
+
+    @Override
+    public int read() throws IOException {
+        throw new UnsupportedOperationException("Single byte read.");
+    }
+
+    @Override
+    public int read(byte[] b, int offset, int length) throws IOException {
+        maybeStartRecording();
+
+        final int ret = mAudioRecord.read(b, offset, length);
+        if (ret == AudioRecord.ERROR_INVALID_OPERATION ||
+                ret == AudioRecord.ERROR_BAD_VALUE) {
+            throw new IOException("AudioRecord.read returned: " + ret);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public void close() throws IOException {
+        mAudioRecord.stop();
+        mAudioRecord.release();
+    }
+}
diff --git a/src/com/android/speechrecorder/SpeechRecorderActivity.java b/src/com/android/speechrecorder/SpeechRecorderActivity.java
index 3ed77f2..6bedf69 100644
--- a/src/com/android/speechrecorder/SpeechRecorderActivity.java
+++ b/src/com/android/speechrecorder/SpeechRecorderActivity.java
@@ -19,9 +19,6 @@
 import android.app.Activity;
 import android.os.Bundle;
 import android.os.Handler;
-import android.speech.srec.Recognizer;
-import android.speech.srec.WaveHeader;
-import android.speech.srec.MicrophoneInputStream;
 import android.util.Log;
 import android.view.View;
 import android.view.View.OnClickListener;
@@ -155,7 +152,7 @@
                 11025;
         mBaos = new ByteArrayOutputStream(mSampleRate * 2 * 20);
         try {
-            mMicrophone = new MicrophoneInputStream(mSampleRate, mSampleRate * 15);
+            mMicrophone = new MicrophoneInputStream(mSampleRate);
 
 //            mMicrophone = logInputStream(mUtterance.toString(), mMicrophone, mSampleRate);
         } catch (IOException e) {
diff --git a/src/com/android/speechrecorder/WaveHeader.java b/src/com/android/speechrecorder/WaveHeader.java
new file mode 100644
index 0000000..1d0a19d
--- /dev/null
+++ b/src/com/android/speechrecorder/WaveHeader.java
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.speechrecorder;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * This class represents the header of a WAVE format audio file, which usually
+ * have a .wav suffix.  The following integer valued fields are contained:
+ * <ul>
+ * <li> format - usually PCM, ALAW or ULAW.
+ * <li> numChannels - 1 for mono, 2 for stereo.
+ * <li> sampleRate - usually 8000, 11025, 16000, 22050, or 44100 hz.
+ * <li> bitsPerSample - usually 16 for PCM, 8 for ALAW, or 8 for ULAW.
+ * <li> numBytes - size of audio data after this header, in bytes.
+ * </ul>
+ * 
+ * Not yet ready to be supported, so
+ * @hide
+ */
+public class WaveHeader {
+    
+    // follows WAVE format in http://ccrma.stanford.edu/courses/422/projects/WaveFormat
+
+    private static final String TAG = "WaveHeader";
+    
+    private static final int HEADER_LENGTH = 44;
+    
+    /** Indicates PCM format. */
+    public static final short FORMAT_PCM = 1;
+    /** Indicates ALAW format. */
+    public static final short FORMAT_ALAW = 6;
+    /** Indicates ULAW format. */
+    public static final short FORMAT_ULAW = 7;
+    
+    private short mFormat;
+    private short mNumChannels;
+    private int mSampleRate;
+    private short mBitsPerSample;
+    private int mNumBytes;
+    
+    /**
+     * Construct a WaveHeader, with all fields defaulting to zero.
+     */
+    public WaveHeader() {
+    }
+    
+    /**
+     * Construct a WaveHeader, with fields initialized.
+     * @param format format of audio data,
+     * one of {@link #FORMAT_PCM}, {@link #FORMAT_ULAW}, or {@link #FORMAT_ALAW}. 
+     * @param numChannels 1 for mono, 2 for stereo.
+     * @param sampleRate typically 8000, 11025, 16000, 22050, or 44100 hz.
+     * @param bitsPerSample usually 16 for PCM, 8 for ULAW or 8 for ALAW.
+     * @param numBytes size of audio data after this header, in bytes.
+     */
+    public WaveHeader(short format, short numChannels, int sampleRate, short bitsPerSample, int numBytes) {
+        mFormat = format;
+        mSampleRate = sampleRate;
+        mNumChannels = numChannels;
+        mBitsPerSample = bitsPerSample;
+        mNumBytes = numBytes;
+    }
+    
+    /**
+     * Get the format field.
+     * @return format field,
+     * one of {@link #FORMAT_PCM}, {@link #FORMAT_ULAW}, or {@link #FORMAT_ALAW}.
+     */
+    public short getFormat() {
+        return mFormat;
+    }
+    
+    /**
+     * Set the format field.
+     * @param format
+     * one of {@link #FORMAT_PCM}, {@link #FORMAT_ULAW}, or {@link #FORMAT_ALAW}.
+     * @return reference to this WaveHeader instance.
+     */
+    public WaveHeader setFormat(short format) {
+        mFormat = format;
+        return this;
+    }
+    
+    /**
+     * Get the number of channels.
+     * @return number of channels, 1 for mono, 2 for stereo.
+     */
+    public short getNumChannels() {
+        return mNumChannels;
+    }
+    
+    /**
+     * Set the number of channels.
+     * @param numChannels 1 for mono, 2 for stereo.
+     * @return reference to this WaveHeader instance.
+     */
+    public WaveHeader setNumChannels(short numChannels) {
+        mNumChannels = numChannels;
+        return this;
+    }
+    
+    /**
+     * Get the sample rate.
+     * @return sample rate, typically 8000, 11025, 16000, 22050, or 44100 hz.
+     */
+    public int getSampleRate() {
+        return mSampleRate;
+    }
+    
+    /**
+     * Set the sample rate.
+     * @param sampleRate sample rate, typically 8000, 11025, 16000, 22050, or 44100 hz.
+     * @return reference to this WaveHeader instance.
+     */
+    public WaveHeader setSampleRate(int sampleRate) {
+        mSampleRate = sampleRate;
+        return this;
+    }
+    
+    /**
+     * Get the number of bits per sample.
+     * @return number of bits per sample,
+     * usually 16 for PCM, 8 for ULAW or 8 for ALAW.
+     */
+    public short getBitsPerSample() {
+        return mBitsPerSample;
+    }
+    
+    /**
+     * Set the number of bits per sample.
+     * @param bitsPerSample number of bits per sample,
+     * usually 16 for PCM, 8 for ULAW or 8 for ALAW.
+     * @return reference to this WaveHeader instance.
+     */
+    public WaveHeader setBitsPerSample(short bitsPerSample) {
+        mBitsPerSample = bitsPerSample;
+        return this;
+    }
+    
+    /**
+     * Get the size of audio data after this header, in bytes.
+     * @return size of audio data after this header, in bytes.
+     */
+    public int getNumBytes() {
+        return mNumBytes;
+    }
+    
+    /**
+     * Set the size of audio data after this header, in bytes.
+     * @param numBytes size of audio data after this header, in bytes.
+     * @return reference to this WaveHeader instance.
+     */
+    public WaveHeader setNumBytes(int numBytes) {
+        mNumBytes = numBytes;
+        return this;
+    }
+    
+    /**
+     * Read and initialize a WaveHeader.
+     * @param in {@link java.io.InputStream} to read from.
+     * @return number of bytes consumed.
+     * @throws IOException
+     */
+    public int read(InputStream in) throws IOException {
+        /* RIFF header */
+        readId(in, "RIFF");
+        int numBytes = readInt(in) - 36;
+        readId(in, "WAVE");
+
+        /* fmt chunk */
+        readId(in, "fmt ");
+        if (16 != readInt(in)) throw new IOException("fmt chunk length not 16");
+        mFormat = readShort(in);
+        mNumChannels = readShort(in);
+        mSampleRate = readInt(in);
+        int byteRate = readInt(in);
+        short blockAlign = readShort(in);
+        mBitsPerSample = readShort(in);
+        if (byteRate != mNumChannels * mSampleRate * mBitsPerSample / 8) {
+            throw new IOException("fmt.ByteRate field inconsistent");
+        }
+        if (blockAlign != mNumChannels * mBitsPerSample / 8) {
+            throw new IOException("fmt.BlockAlign field inconsistent");
+        }
+
+        /* data chunk */
+        readId(in, "data");
+        mNumBytes = readInt(in);
+        
+        return HEADER_LENGTH;
+    }
+
+    private static void readId(InputStream in, String id) throws IOException {
+        for (int i = 0; i < id.length(); i++) {
+            if (id.charAt(i) != in.read()) throw new IOException( id + " tag not present");
+        }
+    }
+
+    private static int readInt(InputStream in) throws IOException {
+        return in.read() | (in.read() << 8) | (in.read() << 16) | (in.read() << 24);
+    }
+
+    private static short readShort(InputStream in) throws IOException {
+        return (short)(in.read() | (in.read() << 8));
+    }
+
+    /**
+     * Write a WAVE file header.
+     * @param out {@link java.io.OutputStream} to receive the header.
+     * @return number of bytes written.
+     * @throws IOException
+     */
+    public int write(OutputStream out) throws IOException {
+        /* RIFF header */
+        writeId(out, "RIFF");
+        writeInt(out, 36 + mNumBytes);
+        writeId(out, "WAVE");
+
+        /* fmt chunk */
+        writeId(out, "fmt ");
+        writeInt(out, 16);
+        writeShort(out, mFormat);
+        writeShort(out, mNumChannels);
+        writeInt(out, mSampleRate);
+        writeInt(out, mNumChannels * mSampleRate * mBitsPerSample / 8);
+        writeShort(out, (short)(mNumChannels * mBitsPerSample / 8));
+        writeShort(out, mBitsPerSample);
+
+        /* data chunk */
+        writeId(out, "data");
+        writeInt(out, mNumBytes);
+        
+        return HEADER_LENGTH;
+    }
+
+    private static void writeId(OutputStream out, String id) throws IOException {
+        for (int i = 0; i < id.length(); i++) out.write(id.charAt(i));
+    }
+
+    private static void writeInt(OutputStream out, int val) throws IOException {
+        out.write(val >> 0);
+        out.write(val >> 8);
+        out.write(val >> 16);
+        out.write(val >> 24);
+    }
+
+    private static void writeShort(OutputStream out, short val) throws IOException {
+        out.write(val >> 0);
+        out.write(val >> 8);
+    }
+    
+    @Override
+    public String toString() {
+        return String.format(
+                "WaveHeader format=%d numChannels=%d sampleRate=%d bitsPerSample=%d numBytes=%d",
+                mFormat, mNumChannels, mSampleRate, mBitsPerSample, mNumBytes);
+    }
+
+}
