2012-05-09 55 views
5

Tôi gặp sự cố khi chuyển đổi định dạng âm thanh của tệp WAV.Chuyển đổi định dạng âm thanh

Tôi đang ghi âm từ micro của tôi và âm thanh được ghi lại trong các định dạng sau: PCM_SIGNED 44100,0 Hz, 16 bit, mono, 2 byte/khung

Tôi muốn chuyển đổi định dạng trên để, ULAW 8000,0 Hz, 8 bit, mono, 1 byte/khung

tôi đang sử dụng đoạn mã sau,

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 

Và tôi nhận được lỗi sau,

java.lang.IllegalArgumentException: chuyển đổi được hỗ trợ: ULAW 8000,0 Hz, 8 bit, mono, 1 byte/khung, từ PCM_SIGNED 44100,0 Hz, 16 bit, mono, 2 byte/khung, ít về cuối nhỏ

một người nào đó có thể vui lòng giúp tôi giải quyết vấn đề này !!!

Cảm ơn một tấn !!!

Trả lời

3

Bạn có xem qua số documentation không?

Ném: IllegalArgumentException - nếu việc chuyển đổi không được hỗ trợ #getTargetEncodings #see (AudioFormat)

Không phải mọi hệ thống sẽ có đủ codec cài đặt để chuyển đổi sang định dạng cụ thể mà bạn đã hỏi cho. Bạn đã giả định của bạn, nhưng nó ném ngoại lệ vì nó không thể chuyển đổi sang định dạng đó.

Bạn có thể sử dụng getTargetEncodings để kiểm tra tính phù hợp của một định dạng nhất định, mà không dựa vào ngoại lệ và có thể thực hiện hành động thích hợp nếu bạn muốn định dạng đầu ra không có sẵn (ví dụ: với phản hồi rằng điều này là không thể, v.v.).

+0

Hey Andrzej! Cảm ơn vi đa trả lơi. Tôi đã từng đi qua tài liệu. Tôi đã sử dụng phương thức getTargetEncodings() theo cách sau đây 'code' Encoding [] encArr = AudioSystem.getTargetEncodings (oldFormat); \t \t \t \t for (int i = 0; i " + encArr [i]); \t \t \t \t} 'code' Và tôi đã nhận ra sau đây: 0 -> PCM_SIGNED 1 -> PCM_UNSIGNED 2 -> ALAW 3 -> ULAW, bạn có gì để nói về điều này? Cảm ơn!! –

+0

Vì tôi nhận được đầu ra ở trên, hệ thống của tôi có các codec để chuyển thành định dạng ULAW, tôi đoán vậy. Điều gì có thể là lý do khác cho ngoại lệ? Bất kỳ ý tưởng? –

+1

Nó có thể không hỗ trợ một số khía cạnh khác của chuyển đổi, chẳng hạn như tỷ lệ mẫu hoặc số bit. Tôi không hoàn toàn dựa trên điều này, nhưng thực tế là bạn đang "downsampling" đặt ra một lá cờ cho tôi. (đi từ 44100 đến 8000).Điều này thường phức tạp, vì thông tin dữ liệu với tần số từ 4000 đến 22050 Hz sẽ bí danh trừ khi bạn lọc chúng ra khỏi dữ liệu. Vì vậy, tôi đoán đó không phải là một chuyển đổi được hỗ trợ chuẩn. Nhưng tôi đặt cược bạn có thể chuyển đổi sang ULAW với 44100 Hz cho đầu ra của bạn. (Tôi đoán tốt nhất.) –

0

Lớp học này có thể giúp bạn. Tôi tìm thấy nó 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

Điều đó làm gì? Nó sẽ giúp tôi với lỗi sau đây? 'dòng với định dạng PCM_SIGNED 44100.0 Hz, 16 bit, mono, 2 byte/khung, ít hỗ trợ không được hỗ trợ' – trusktr

+0

Tôi chưa sử dụng, nhưng nó tuyên bố chuyển đổi" luồng byte PCM mono thành luồng byte U-Law A-Law . " Điều đó trông giống như những gì bạn đang cố gắng làm. Dường như chuyển đổi này không được hỗ trợ trực tiếp trong Java, bạn phải thực hiện nén của riêng bạn (như lớp này). – 11101101b

+1

Hóa ra lỗi của tôi là vì tôi không thể sử dụng dòng dữ liệu đã được sử dụng (vì vậy lỗi này gây hiểu lầm). Sử dụng thư viện âm thanh hạt giải quyết tất cả các vấn đề của tôi (http://beadsproject.net). – trusktr

Các vấn đề liên quan