преобразование PCM-16 в AMR с использованием AmrInputStream - PullRequest
4 голосов
/ 31 августа 2011

Я делаю преобразование из PCM-16 в AMR, используя AmrInputStream.Подробности для AmrInputStream можно найти здесь http://hi -android.info / src / android / media / AmrInputStream.java.html

Я довольно новичок в программировании, пока онЯ говорю о том, что такое JNI, и не думаю, что это необходимо для этого обсуждения.Приведенный выше AmrInputStream также явно не найден ни в SDK, ни в NDK, но я смог его использовать.

Я искал в Интернете, как использовать поток, но не нашел ни одного.Примеры.В конце я экспериментировал и обнаружил, что он похож на любой InputStream.Вот фрагмент кода

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();

Я проверил это, и это сработало (требуется добавление тега!! AMR \ n в выходной файл для воспроизведения.)\ n).

Мой вопрос касается того, что мне удалось заставить его работать только с файлом PCM-16, сэмплированным на частоте 8000 Гц.Любая (более высокая) частота, используемая для исходного файла PCM-16, приводит к выводу (с пониженной частотой дискретизации).В файле AmrInputStream.java есть переменная SAMPLES_PER_FRAME, с которой я пытался поиграть, но она, похоже, не влияет ни на что.

1 Ответ

3 голосов
/ 31 августа 2011

SAMPLES_PER_FRAME - это блок данных, с которым работает amrencoder за один раз (который отображается на 20 мсек звука).

из сигнатур функций кодировщика amr (внизу 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);

Кажется, что нет способа передать частоту дискретизации в кодировщик (gae - это родной дескриптор) частота дискретизации жестко запрограммирована как минимум до 8k с этим API

...