A small sample tool to encode pcm audio data to amr, decode it again and play it. Some changes to OMXCodec to properly configure the AMR decoder(s).
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index 5b55252..100af89 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -43,4 +43,26 @@
 
 include $(BUILD_EXECUTABLE)
 
+################################################################################
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:=         \
+        SineSource.cpp    \
+        audioloop.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libstagefright
+
+LOCAL_C_INCLUDES:= \
+	$(JNI_H_INCLUDE) \
+	frameworks/base/media/libstagefright \
+	$(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include
+
+LOCAL_CFLAGS += -Wno-multichar
+
+LOCAL_MODULE:= audioloop
+
+include $(BUILD_EXECUTABLE)
+
 endif
diff --git a/cmds/stagefright/SineSource.cpp b/cmds/stagefright/SineSource.cpp
index e272a65..021f636 100644
--- a/cmds/stagefright/SineSource.cpp
+++ b/cmds/stagefright/SineSource.cpp
@@ -52,6 +52,7 @@
     meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
     meta->setInt32(kKeyChannelCount, mNumChannels);
     meta->setInt32(kKeySampleRate, mSampleRate);
+    meta->setInt32(kKeyMaxInputSize, kBufferSize);
 
     return meta;
 }
diff --git a/cmds/stagefright/audioloop.cpp b/cmds/stagefright/audioloop.cpp
new file mode 100644
index 0000000..70ab559
--- /dev/null
+++ b/cmds/stagefright/audioloop.cpp
@@ -0,0 +1,81 @@
+#include "SineSource.h"
+
+#include <binder/ProcessState.h>
+#include <media/stagefright/AudioPlayer.h>
+#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/OMXClient.h>
+#include <media/stagefright/OMXCodec.h>
+
+using namespace android;
+
+int main() {
+    // We only have an AMR-WB encoder on sholes...
+    static bool outputWBAMR = false;
+    static const int32_t kSampleRate = outputWBAMR ? 16000 : 8000;
+    static const int32_t kNumChannels = 1;
+
+    android::ProcessState::self()->startThreadPool();
+
+    OMXClient client;
+    CHECK_EQ(client.connect(), OK);
+
+    sp<MediaSource> source = new SineSource(kSampleRate, kNumChannels);
+
+    sp<MetaData> meta = new MetaData;
+
+    meta->setCString(
+            kKeyMIMEType,
+            outputWBAMR ? MEDIA_MIMETYPE_AUDIO_AMR_WB
+                        : MEDIA_MIMETYPE_AUDIO_AMR_NB);
+
+    meta->setInt32(kKeyChannelCount, kNumChannels);
+    meta->setInt32(kKeySampleRate, kSampleRate);
+
+    int32_t maxInputSize;
+    if (source->getFormat()->findInt32(kKeyMaxInputSize, &maxInputSize)) {
+        meta->setInt32(kKeyMaxInputSize, maxInputSize);
+    }
+
+    sp<OMXCodec> encoder = OMXCodec::Create(
+            client.interface(),
+            meta, true /* createEncoder */,
+            source);
+
+    sp<OMXCodec> decoder = OMXCodec::Create(
+            client.interface(),
+            meta, false /* createEncoder */,
+            encoder);
+
+#if 1
+    AudioPlayer *player = new AudioPlayer(NULL);
+    player->setSource(decoder);
+
+    player->start();
+
+    sleep(10);
+
+    player->stop();
+
+    delete player;
+    player = NULL;
+#else
+    CHECK_EQ(decoder->start(), OK);
+
+    MediaBuffer *buffer;
+    while (decoder->read(&buffer) == OK) {
+        // do something with buffer
+
+        putchar('.');
+        fflush(stdout);
+
+        buffer->release();
+        buffer = NULL;
+    }
+
+    CHECK_EQ(decoder->stop(), OK);
+#endif
+
+    return 0;
+}
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 4c60623..4199252 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -146,8 +146,7 @@
 
     void setComponentRole();
 
-    void setAMRFormat();
-    void setAMRWBFormat();
+    void setAMRFormat(bool isWAMR);
     void setAACFormat(int32_t numChannels, int32_t sampleRate);
 
     status_t setVideoPortFormatType(
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index c5e935d..670f748 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -416,10 +416,10 @@
     }
 
     if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) {
-        codec->setAMRFormat();
+        codec->setAMRFormat(false /* isWAMR */);
     }
     if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
-        codec->setAMRWBFormat();
+        codec->setAMRFormat(true /* isWAMR */);
     }
     if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
         int32_t numChannels, sampleRate;
@@ -1900,54 +1900,24 @@
     CHECK_EQ(err, OK);
 }
 
-void OMXCodec::setAMRFormat() {
-    if (!mIsEncoder) {
-        OMX_AUDIO_PARAM_AMRTYPE def;
-        InitOMXParams(&def);
-        def.nPortIndex = kPortIndexInput;
+void OMXCodec::setAMRFormat(bool isWAMR) {
+    OMX_U32 portIndex = mIsEncoder ? kPortIndexOutput : kPortIndexInput;
 
-        status_t err =
-            mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
+    OMX_AUDIO_PARAM_AMRTYPE def;
+    InitOMXParams(&def);
+    def.nPortIndex = portIndex;
 
-        CHECK_EQ(err, OK);
+    status_t err =
+        mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
 
-        def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
-        def.eAMRBandMode = OMX_AUDIO_AMRBandModeNB0;
+    CHECK_EQ(err, OK);
 
-        err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
-        CHECK_EQ(err, OK);
-    }
+    def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
+    def.eAMRBandMode =
+        isWAMR ? OMX_AUDIO_AMRBandModeWB0 : OMX_AUDIO_AMRBandModeNB0;
 
-    ////////////////////////
-
-    if (mIsEncoder) {
-        sp<MetaData> format = mSource->getFormat();
-        int32_t sampleRate;
-        int32_t numChannels;
-        CHECK(format->findInt32(kKeySampleRate, &sampleRate));
-        CHECK(format->findInt32(kKeyChannelCount, &numChannels));
-
-        setRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
-    }
-}
-
-void OMXCodec::setAMRWBFormat() {
-    if (!mIsEncoder) {
-        OMX_AUDIO_PARAM_AMRTYPE def;
-        InitOMXParams(&def);
-        def.nPortIndex = kPortIndexInput;
-
-        status_t err =
-            mOMX->getParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
-
-        CHECK_EQ(err, OK);
-
-        def.eAMRFrameFormat = OMX_AUDIO_AMRFrameFormatFSF;
-        def.eAMRBandMode = OMX_AUDIO_AMRBandModeWB0;
-
-        err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
-        CHECK_EQ(err, OK);
-    }
+    err = mOMX->setParameter(mNode, OMX_IndexParamAudioAmr, &def, sizeof(def));
+    CHECK_EQ(err, OK);
 
     ////////////////////////