Вопрос по audio, java – Преобразование аудио формата

6

У меня возникли проблемы с преобразованием аудио формата файла WAV.

Я записываю звук со своего микрофона, и звук записывается в следующем формате: PCM_SIGNED 44100,0 Гц, 16 бит, моно, 2 байта / кадр

Я хочу преобразовать вышеуказанный формат в ULAW 8000,0 Гц, 8 бит, моно, 1 байт / кадр

Я использую следующий код,

InputStream is = request.getInputStream(); 
            AudioInputStream ais = AudioSystem.getAudioInputStream(is);
            AudioFormat oldFormat = ais.getFormat();
            AudioFormat newFormat = new AudioFormat(AudioFormat.Encoding.ULAW, 8000, 8, 1, 1, 8000, false) ;
AudioInputStream lowResAIS = AudioSystem.getAudioInputStream(newFormat, ais); //Getting the below Exception on this line

И я получаю следующую ошибку,

java.lang.IllegalArgumentException: неподдерживаемое преобразование: ULAW 8000,0 Гц, 8 бит, моно, 1 байт / кадр, из PCM_SIGNED 44100,0 Гц, 16 бит, моно, 2 байта / кадр, little-endian

Может кто-нибудь, пожалуйста, помогите мне решить эту проблему !!!

Благодаря тонну!!!

Ваш Ответ

2   ответа
3

документация?

Throws: IllegalArgumentException - if the conversion is not supported #see #getTargetEncodings(AudioFormat)

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

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

Я предполагаю, что, поскольку я получаю вышеприведенный вывод, моя система имеет кодеки для преобразования в формат ULAW. Что может быть другой причиной исключения? Любая идея? Vijay Suryawanshi
Он может не поддерживать какой-либо другой аспект преобразования, например частоту дискретизации или количество битов. Я не совсем в этом разбираюсь, но в том, что у вас "пониженная выборка" поднимает флаг для меня. (происходит от 44100 до 8000). Это обычно сложно, так как информация данных с частотами между 4000 и 22050 Гц будет иметь псевдоним, если вы не отфильтруете их из данных. Так что я думаю, что это не стандартное поддерживаемое преобразование. Но держу пари, что вы можете конвертировать в ULAW с частотой 44100 Гц, учитывая ваши результаты. (Моя лучшая догадка.)
Эй, Анджей! Спасибо за ответ. Я частично просмотрел документацию. Я использовал метод getTargetEncodings () следующим образомcode Encoding [] encArr = AudioSystem.getTargetEncodings (oldFormat); for (int i = 0; i & lt; encArr.length; i ++) {System.out.println (i + & quot; - & gt; + encArr [i]); }code И я получил следующий вывод: 0 -> PCM_SIGNED 1 -> PCM_UNSIGNED 2 -> ALAW 3 -> ULAW, что вы хотите сказать по этому поводу? Спасибо!! Vijay Suryawanshi
0

Вот:

package uk.co.mmscomputing.sound;

import java.io.*;

public class CompressInputStream extends FilterInputStream{

  /*
    Convert mono PCM byte stream into A-Law u-Law byte stream

    static AudioFormat alawformat= new AudioFormat(AudioFormat.Encoding.ALAW,8000,8,1,1,8000,false);
    static AudioFormat ulawformat= new AudioFormat(AudioFormat.Encoding.ULAW,8000,8,1,1,8000,false);

    PCM 8000.0 Hz, 16 bit, mono, SIGNED, little-endian
    static AudioFormat pcmformat = new AudioFormat(8000,16,1,true,false);

  */

  static private Compressor alawcompressor=new ALawCompressor();
  static private Compressor ulawcompressor=new uLawCompressor();

  private Compressor compressor=null;

  public CompressInputStream(InputStream in, boolean useALaw)throws IOException{
    super(in);
    compressor=(useALaw)?alawcompressor:ulawcompressor; 
  }

  public int read()throws IOException{
    throw new IOException(getClass().getName()+".read() :\n\tDo not support simple read().");
  }

  public int read(byte[] b)throws IOException{
    return read(b,0,b.length);
  }

  public int read(byte[] b, int off, int len)throws IOException{
    int     i,sample;
    byte[]  inb;

    inb=new byte[len<<1];          // get 16bit PCM data
    len=in.read(inb);
    if(len==-1){return -1;};

    i=0;
    while(i<len){
      sample   = (inb[i++]&0x00FF);
      sample  |= (inb[i++]<<8);
      b[off++]=(byte)compressor.compress((short)sample);
    }
    return len>>1;
  }
}

abstract class Compressor{
  protected abstract int compress(short sample);    
}

/*
    Mathematical Tools in Signal Processing with C++ and Java Simulations
        by  Willi-Hans Steeb
            International School for Scientific Computing
*/

class ALawCompressor extends Compressor{

  static final int cClip = 32635;

  static final int[] ALawCompressTable ={
    1,1,2,2,3,3,3,3,
    4,4,4,4,4,4,4,4,
    5,5,5,5,5,5,5,5,
    5,5,5,5,5,5,5,5,
    6,6,6,6,6,6,6,6,
    6,6,6,6,6,6,6,6,
    6,6,6,6,6,6,6,6,
    6,6,6,6,6,6,6,6,
    7,7,7,7,7,7,7,7,
    7,7,7,7,7,7,7,7,
    7,7,7,7,7,7,7,7,
    7,7,7,7,7,7,7,7,
    7,7,7,7,7,7,7,7,
    7,7,7,7,7,7,7,7,
    7,7,7,7,7,7,7,7,
    7,7,7,7,7,7,7,7
  };

  protected int compress(short sample){
    int sign;
    int exponent;
    int mantissa;
    int compressedByte;

    sign = ((~sample) >> 8) & 0x80;
    if(sign==0){ sample *= -1;}
    if(sample > cClip){ sample = cClip; }
    if(sample >= 256){
      exponent = ALawCompressTable[(sample >> 8) & 0x007F];
      mantissa = (sample >> (exponent + 3) ) & 0x0F;
      compressedByte = 0x007F & ((exponent << 4) | mantissa);
    }else{
      compressedByte = 0x007F & (sample >> 4);
    }
    compressedByte ^= (sign ^ 0x55);
    return compressedByte;
  }
}

class uLawCompressor extends Compressor{

  static final int cClip = 32635;
  static final int cBias = 0x84;

  int[] uLawCompressTable ={
    0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
    4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
    5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
    5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
  };

  protected int compress(short sample){
    int sign;
    int exponent;
    int mantissa;
    int compressedByte;

    sign = (sample >> 8) & 0x80;
    if(sign!=0){ sample *= -1;}
    if(sample > cClip){ sample = cClip; }
    sample += cBias;

    exponent = uLawCompressTable[(sample >> 7) & 0x00FF];
    mantissa = (sample >> (exponent + 3)) & 0x0F;
    compressedByte = ~(sign | (exponent << 4) | mantissa);
    return compressedByte&0x000000FF;
  }
}
Это, возможно, не ответило на OP, но это было полезно для меня для чего-то связанного.
Я не использовал его, но он претендует на преобразование «монофонического потока байтов PCM в поток байтов A-Law u-Law». Это похоже на то, что вы пытаетесь сделать. Похоже, что это преобразование не поддерживается напрямую в Java, вам нужно сделать свое собственное сжатие (как этот класс делает).
Оказывается, моя ошибка была в том, что я не мог использовать строку данных, которая уже использовалась (поэтому ошибка вводит в заблуждение). Использование звуковой библиотеки Beads решило все мои проблемы (beadsproject.net).
Что это делает? Поможет ли мне эта ошибка?line with format PCM_SIGNED 44100.0 Hz, 16 bit, mono, 2 bytes/frame, little-endian not supported

Похожие вопросы