2012-05-09 19 views
5

Mam problemy z konwertowaniem formatu audio pliku WAV.Konwersja formatu audio

jestem nagrywania dźwięku z mojego mikrofonu i dźwięk jest zapisywany w następującym formacie: PCM_SIGNED 44100,0 Hz, 16 bit, mono, 2 bajty/rama

Chcę przekształcić powyższy format do, ulaw 8000,0 Hz, 8-bitowy, mono- 1 bajtów/ramki

ja zastosowaniem kodu,

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 

i otrzymuję następujące błędu

java.lang.IllegalArgumentException: NieobsĹ,ugiwana konwersja: ulaw 8000,0 Hz, 8-bitowy, mono- 1 bajtów/ramki z PCM_SIGNED 44100,0 Hz, 16-bitowy, mono, 2 bajtów/ramki ostrokońcej

ktoś mógłby pomóż mi rozwiązać ten problem !!!

Dzięki za tonę !!!

Odpowiedz

3

Czy spojrzałeś na documentation?

Zgłasza: IllegalArgumentException - jeśli konwersja nie jest obsługiwana #getTargetEncodings #see (AudioFormat)

Nie każdy system będzie posiadać wystarczającą kodeki zainstalowane przekształcić do określonego formatu Prosisz dla. Założono, że to robi, ale rzuca wyjątek, ponieważ nie może przekształcić się w ten format.

Możesz użyć programu getTargetEncodings, aby sprawdzić przydatność danego formatu programowo, bez polegania na wyjątku, a następnie może podjąć odpowiednie działanie, jeśli żądany format wyjściowy nie jest dostępny (np. Wrócić do innego, przedstawić użytkownika ze stwierdzeniem, że jest to niemożliwe, itp.).

+0

Hej, Andrzej! Dziękuję za odpowiedź. Częściowo przejrzałem dokumentację. Użyłem metody getTargetEncodings() w następujący sposób: 'code' Encoding [] encArr = AudioSystem.getTargetEncodings (oldFormat); \t \t \t \t do (int i = 0; i " + encArr [i]); \t \t \t \t} 'code' i mam następujący wynik: 0 -> PCM_SIGNED 1 -> PCM_UNSIGNED 2 -> alaw 3 -> ulaw, co masz do powiedzenia na ten temat? Dzięki!! –

+0

Ponieważ otrzymuję powyższe wyjście, mój system ma kodeki do przekształcenia do formatu ULAW, zgaduję. Jaki może być inny powód wyjątku? Dowolny pomysł? –

+1

Może to nie obsługiwać innego aspektu konwersji, takiego jak częstotliwość próbkowania lub liczba bitów. Nie jestem na tym w pełni, ale fakt, że jesteś "próbą obniżenia", podnosi dla mnie flagę. (przejście z 44100 do 8000).Zazwyczaj jest to trudne, ponieważ dane o częstotliwościach od 4000 do 22050 Hz będą aliasami, chyba że odfiltrujesz je z danych. Domyślam się, że nie jest to standardowa konwersja obsługiwana. Ale założę się, że możesz zamienić się na ULAW z 44100 Hz, biorąc pod uwagę twoje wyniki. (Moje najlepsze przypuszczenie.) –

0

Ta klasa może ci pomóc. Znalazłem go: here:

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; 
    } 
} 
+0

Co to oznacza? Czy pomoże mi to z następującym błędem? 'linia z formatem PCM_SIGNED 44100.0 Hz, 16 bitów, mono, 2 bajty/ramka, little-endian nie jest obsługiwana' – trusktr

+0

Nie użyłem go, ale twierdzi on, że konwertuje strumień bajtów" mono PCM "do strumienia bajtów u-Law A-Law . " To wygląda na to, co próbujesz zrobić. Wygląda na to, że ta konwersja nie jest obsługiwana bezpośrednio w Javie, musisz zrobić własną kompresję (jak robi to ta klasa). – 11101101b

+1

Okazało się, że mój błąd wynika z tego, że nie mogłem użyć linii danych, która była już używana (więc błąd jest mylący). Korzystanie z biblioteki dźwięków z perełkami rozwiązało wszystkie moje problemy (http://beadsproject.net). – trusktr

Powiązane problemy