Android PCM в кодировку Ulaw wav - PullRequest
6 голосов
/ 03 ноября 2011

Я пытаюсь закодировать необработанные данные PCM как uLaw для экономии полосы пропускания, необходимой для передачи речевых данных.

Я столкнулся с классом UlawEncoderInputStream на Эта страница , но нет документации! (

Конструктор принимает входной поток и значение максимального pcm (что бы это ни было).

  /**
     * Create an InputStream which takes 16 bit pcm data and produces ulaw data.
     * @param in InputStream containing 16 bit pcm data.
     * @param max pcm value corresponding to maximum ulaw value.
     */
    public UlawEncoderInputStream(InputStream in, int max) {

После просмотра кода я подозреваю, что мне следует рассчитать это «максимальное» значение, используя предоставленную функцию: maxAbsPcm . Проблема в том, что я не совсем понимаю, что я собираюсь передать! Я записываю свой необработанный PCM в файл на SD-карте, поэтому у меня нет одного массива данных, постоянно находящегося в памяти, для передачи на него.

  /**
     * Compute the maximum of the absolute value of the pcm samples.
     * The return value can be used to set ulaw encoder scaling.
     * @param pcmBuf array containing 16 bit pcm data.
     * @param offset offset of start of 16 bit pcm data.
     * @param length number of pcm samples (not number of input bytes)
     * @return maximum abs of pcm data values
     */
    public static int maxAbsPcm(byte[] pcmBuf, int offset, int length) {

Другая проблема, с которой я сталкиваюсь при использовании этого кода, заключается в том, что я не уверен, какие значения выписать для заголовка для данных uLaw. Как определить, сколько меньше байтовых данных после кодирования с помощью uLaw?

Я прослушал один из (потенциально) кодированных файлов uLaw, который я создал в медиаплеере VLC (единственный плеер, который у меня есть, который будет пытаться прочитать файл), и его звуки противные, сломанные и щелкающие, но все еще можно разобрать голос.

Я пишу свой волновой заголовок, используя код, похожий на класс, который я нашел под названием WaveHeader, который можно найти Здесь !

Если у кого-то есть мысли по этому поводу, я был бы очень признателен, если бы их услышали! :) 1025 *

Большое спасибо Dexter

Ответы [ 2 ]

4 голосов
/ 08 февраля 2012

max в конструкторе - максимальная амплитуда в данных PCM.Он используется для масштабирования ввода перед генерацией вывода.Если входной сигнал очень громкий, вам нужно более высокое значение, если тихий, вам нужно более низкое.Если вы введете 0, кодер будет использовать 8192 по умолчанию, что может быть достаточно.

* В другом методе length указано количество 16-битных выборок, из которых вы хотитенайти максимальную амплитуду.Этот класс предполагает, что входные данные PCM всегда кодируются 16-битными выборками, что означает, что каждая выборка занимает два байта: если ваш вход имеет длину 2000 байтов, у вас есть 1000 выборок.

Кодер в этом классе производитодна 8-битная выборка µ-Law для каждой 16-битной выборки PCM, поэтому размер в байтах уменьшается вдвое.

0 голосов
/ 18 июля 2013

Это противоположно тому, что вы пытаетесь сделать, но я подумал, что это может быть полезно для кого-то.Вот пример метода, который преобразует 8-битный двоичный файл в кодировке uLaw в 16-битный WAV-файл, используя встроенные методы Java.

public static void convertULawFileToWav(String filename) {
    File file = new File(filename);
    if (!file.exists())
        return;
    try {
        long fileSize = file.length();
        int frameSize = 160;
        long numFrames = fileSize / frameSize;
        AudioFormat audioFormat = new AudioFormat(Encoding.ULAW, 8000, 8, 1, frameSize, 50, true);
        AudioInputStream audioInputStream = new AudioInputStream(new FileInputStream(file), audioFormat, numFrames);
        AudioSystem.write(audioInputStream, Type.WAVE, new File("C:\\file.wav"));
    } catch (IOException e) {
        e.printStackTrace();
    }
}
...