converting PCM-16 to AMR using AmrInputStream

白昼怎懂夜的黑 提交于 2019-12-10 17:35:10

问题


I'm doing a conversion from PCM-16 to AMR using AmrInputStream. The details for the AmrInputStream can be found here http://hi-android.info/src/android/media/AmrInputStream.java.html

I'm quite new to programming to while it talks about using JNI and stuff, I have no idea what JNI is and I don't think it is required for this discussion. The AmrInputStream above is also apparently not found in the SDK nor the NDK, but I have been able to use it.

I've been searching around the internet for how to use the stream, but have not found any examples. In the end I experimented and found it to be similar to just any InputStream. Here's a code snippet

InputStream inStream;
    inStream = new FileInputStream("abc.wav");
    AmrInputStream aStream = new AmrInputStream(inStream);

    File file = new File("xyz.amr");        
    file.createNewFile();
    OutputStream out = new FileOutputStream(file); 

    byte[] x = new byte[1024];
    int len;
    while ((len=aStream.read(x)) > 0) {
        out.write(x,0,len);
    }

    out.close();

I have tested this and it has worked (requiring adding the #!AMR\n tag to the output file for playing.) (Edit: The AMR tag must be #!AMR\n).

My question pertains to that I have only managed to get this to work on a PCM-16 file sampled at 8000Hz. Any (higher) frequency used for the original PCM-16 file results in an (undersampled) output. There is a SAMPLES_PER_FRAME variable in the AmrInputStream.java file which I have tried playing with but it does not seem to affect anything.

Any advise or related discussion is welcomed!


回答1:


SAMPLES_PER_FRAME is the block of data the amrencoder acts on in one go(which is mapped to 20 msec of audio).

from the signatures of the amr encoder functions (at the bottom of http://hi-android.info/src/android/media/AmrInputStream.java.html)

private static native int GsmAmrEncoderNew();

private static native void GsmAmrEncoderInitialize(int gae);

private static native int GsmAmrEncoderEncode(int gae,
        byte[] pcm, int pcmOffset, byte[] amr, int amrOffset) throws IOException;

private static native void GsmAmrEncoderCleanup(int gae);

private static native void GsmAmrEncoderDelete(int gae);

There doesnt seem to be a way to pass samplerate to the encoder.(gae is native handle) the sample rate is hardcoded to 8k atleast with this api



来源:https://stackoverflow.com/questions/7252040/converting-pcm-16-to-amr-using-amrinputstream

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!