2011-11-03 18 views
6

Tôi đang cố gắng mã hóa dữ liệu nguyên pcm dưới dạng uLaw để tiết kiệm băng thông cần thiết để truyền dữ liệu giọng nói.Android PCM để Ulaw mã hóa tệp wav

Tôi đã bắt gặp một lớp được gọi là UlawEncoderInputStream trên This page nhưng không có tài liệu nào! :(

Các nhà xây dựng phải mất thêm một input stream và một giá trị pcm max (bất kể đó là).

/** 
    * 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) { 

Sau khi xem qua đoạn code, tôi nghi ngờ rằng tôi nên tính toán giá trị này "tối đa" bằng cách sử dụng cung cấp vấn đề là, tôi không thực sự hiểu những gì tôi có nghĩa là để vượt qua vào nó! Tôi đang ghi pcm nguyên của tôi vào một tập tin trên sdcard vì vậy tôi không có một mảng bộ nhớ liên tục cư trú của dữ liệu để vượt qua để điều này .

/** 
    * 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) { 

Một vấn đề khác tôi đã sử dụng mã này là tôi không chắc chắn những giá trị để viết ra cho tiêu đề cho dữ liệu uLaw. Làm thế nào để tôi xác định có bao nhiêu dữ liệu byte ít hơn sau khi mã hóa với uLaw?

Tôi đã nghe một trong các tệp mã hóa uLaw (có thể) mà tôi đã tạo trong trình phát đa phương tiện VLC (trình phát duy nhất tôi có sẽ đọc tệp) và âm thanh khó chịu, bị hỏng và nhấp chuột nhưng vẫn có thể thực hiện ra giọng nói.

Tôi đang viết tiêu đề wave của mình bằng mã tương tự với lớp tôi tìm thấy có tên WaveHeader có thể tìm thấy Here!

Nếu ai có bất kỳ suy nghĩ về vấn đề này, tôi sẽ biết ơn nhất để nghe họ! :)

Rất cám ơn Dexter

+0

Nếu bạn đang tạo tệp .wav. Lưu trữ tập tin tiêu đề sóng trong đầu và thay đổi nó trở lại vào cuối ghi âm của bạn. Thông thường, bạn sẽ không biết kích thước (số lượng hồ sơ) cho đến khi bạn đạt đến kết thúc. Giá trị tối đa của bạn phải là 0x7f. –

Trả lời

4

Các max trong constructor là biên độ tối đa trong các dữ liệu PCM. Nó được sử dụng để mở rộng đầu vào trước khi tạo đầu ra. Nếu đầu vào là rất lớn, bạn cần một giá trị cao hơn, nếu nó là yên tĩnh, bạn cần một thấp hơn. Nếu bạn vượt qua trong 0 bộ mã hóa sẽ sử dụng 8192 theo mặc định, điều này có thể đủ tốt.

Phương thức khác là số mẫu 16 bit mà bạn muốn tìm biên độ tối đa. Lớp này giả định rằng dữ liệu PCM đầu vào luôn được mã hóa với các mẫu 16 bit, có nghĩa là mỗi mẫu kéo dài hai byte: nếu đầu vào của bạn dài 2000 byte, bạn có 1000 mẫu.

Bộ mã hóa trong lớp này tạo ra một mẫu e-bit 8-bit cho mỗi mẫu PCM 16 bit, do đó kích thước tính theo byte bị giảm đi một nửa.

+0

Cảm ơn rất nhiều Joni –

0

Điều này trái ngược với những gì bạn đang cố gắng làm, nhưng tôi nghĩ rằng nó có thể hữu ích cho ai đó. Đây là một phương thức exmple sẽ chuyển đổi một tệp nhị phân được mã hóa uLaw 8 bit thành một tệp WAV 16-bit bằng cách sử dụng các phương thức Java dựng sẵn.

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