質問

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!

役に立ちましたか?

解決

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top