2012-06-12 48 views
9

Có một chút rắc rối trong vài ngày qua để cố gắng thực hiện điều này. Nhưng điều tôi muốn là chúng tôi có một ứng dụng gửi dữ liệu thô qua mạng. Sau đó tôi đọc dữ liệu nhị phân này và muốn lưu nó vào tệp wav (bất kỳ âm thanh) nào. Có thể xem xét nén sau.Lưu byte âm thanh [] vào tập tin wav

Vì vậy, các mã có vấn đề:

byte[] allBytes = ... 
InputStream b_in = new ByteArrayInputStream(allBytes); 

try 
{ 
    AudioFormat format = new AudioFormat(8000f, 16, 1, true, true); 
    AudioInputStream stream = new AudioInputStream(b_in, format, allBytes.length); 
    //AudioInputStream stream = AudioSystem.getAudioInputStream(b_in);     

đã cố gắng sử dụng các tuyên bố trên cũng nhưng tôi có được ngoại lệ: javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from stream. Vì vậy, những gì tôi nghĩ là xảy ra là bởi vì dòng của tôi là dữ liệu âm thanh thô và không có một tiêu đề sóng này là ném một ngoại lệ?

File newPath = new File(SystemConfiguration.getLatest().voiceNetworkPathDirectory + currentPhoneCall.fileName); 
if (!AudioSystem.isFileTypeSupported(Type.WAVE, stream)) 
{ 
    Logger.error("Audio System file type not supported"); 
} 

AudioSystem.write(stream, Type.WAVE, newPath); 

Các tập tin không viết thành công nhưng đó là tất cả tĩnh, Tôi có cần phải tạo ra một tiêu đề sóng trên đầu ra bằng cách sử dụng một cái gì đó giống như this. Khi tôi nhìn vào tập tin wav outputted trong notepad và nó dường như có một tiêu đề khi nó bắt đầu với 'RIFF'.

Tôi có cần thêm tiêu đề giả vào luồng nhập liệu của mình không? Tôi có nên tạo tiêu đề đầu ra của riêng mình và chỉ lưu nó với một trình ghi nhị phân không?

+0

Đã xảy ra sự cố với bài đăng của bạn. Bạn đang thiếu dữ liệu/định dạng. – user845279

+1

Cách so sánh với các tệp WAVE hợp lệ khác? Khi bạn chọn một trong số chúng, sao chép dữ liệu sau tiêu đề và sau đó đặt dữ liệu thô lên mã vào mảng allBytes của bạn. Sau khi chạy mã của bạn, bạn có thể chỉ cần so sánh 2 tệp sóng. Nếu nó không giống nhau, thì một trong hai mã là xấu hoặc bạn cần phải hiểu định dạng sóng. –

+0

đối số 'length' trong hàm tạo của' AudioInputStream' phải là giá trị độ dài khung thay vì độ dài dữ liệu. 'frame-length = data-length/channel/sample-size-in-byte' –

Trả lời

2

Vì vậy, tôi đã kết thúc nhận nó làm việc, không thực sự chắc chắn lý do tại sao nhưng điều này là mã mà đang làm việc:

InputStream b_in = new ByteArrayInputStream(resultArray); 
try { 
     DataOutputStream dos = new DataOutputStream(new FileOutputStream(
       "C:\\filename.bin")); 
     dos.write(resultArray); 
     AudioFormat format = new AudioFormat(8000f, 16, 1, true, false); 
     AudioInputStream stream = new AudioInputStream(b_in, format, 
       resultArray.length); 
     File file = new File("C:\\file.wav"); 
     AudioSystem.write(stream, Type.WAVE, file); 
     Logger.info("File saved: " + file.getName() + ", bytes: " 
       + resultArray.length) 

Vì vậy, đó phải là cài đặt đã ký/chưa ký/ít của tôi. Những gì tôi đã kết thúc làm là lưu dữ liệu vào một tệp nhị phân. Sau đó, nhập tệp đó dưới dạng dữ liệu thô ở mức độ tin cậy. Điều này nói với tôi tất cả mọi thứ ngoại trừ tỷ lệ mà tôi đã mới. Vấn đề duy nhất tôi có bây giờ là làm với tính toán tiêu đề. Tôi lưu các dữ liệu nhị phân mà tạo ra một wav 4 giây nhưng nó chỉ bao giờ có 2 giây của âm thanh. Nó như thể nó đang tính toán tiêu đề của tôi sai. Tôi không chắc liệu nó có liên quan đến độ dài khung hình mà LiuYan đã đề cập hay không.

Nếu tôi có độ dài mảng là 160. Điều này có nghĩa là tôi có độ dài sóng là 10? 160/1/16. Nếu tôi làm điều này thì tôi chỉ lưu trữ 10 byte dữ liệu vào tệp nhị phân của tôi.

+0

Ok nếu có khác được vấn đề với âm thanh tôi đã giả định rằng chiều dài khung là 16 .... Nhưng khi tôi kiểm tra format.getFrameSize() giá trị là 2 Vì vậy, bạn cần phải có các sau đây AudioInputStream stream = new AudioInputStream (b_in, format, \t \t \t \t \t resultArray.length/1/format.getFrameSize()); – user1434177

1

Thật khó để biết từ mô tả của bạn khi có lỗi, nhưng để trả lời câu hỏi của bạn, khi bạn thấy 'RIFF' khi bạn mở tệp có nghĩa là tệp có tiêu đề. Cố gắng xây dựng tiêu đề của riêng bạn là có thể nhưng tốn một chút thời gian (và không cần thiết vì bạn đã có một).

Bây giờ, khi đọc, an toàn nhất là lấy định dạng từ chính tệp đó, thay vì cố gắng xác định nó theo cách thủ công - điều đó sẽ ít bị lỗi hơn. Có mẫu mã cho rằng ở đây:

http://www.jsresources.org/examples/SimpleAudioPlayer.java.html

Khi viết, bạn nói "Các tập tin không viết thành công nhưng đó là tất cả tĩnh" - bạn đã xác nhận rằng với một cái gì đó khác hơn so với mã java của riêng bạn? Có lẽ tôi không hiểu chính xác, nhưng có vẻ như bạn đang cố gắng ghi lại và phát lại các tệp WAV bằng mã java mới và nếu đúng như vậy, thật khó để biết liệu có sự cố nào xảy ra với bản ghi hay phát lại không.

Bạn nên bắt đầu với định dạng vani (16 bit, âm thanh nổi, không nén, 44,100 kHz) để bạn có thể mở tệp trong trình phát đa phương tiện hoặc quicktime hoặc gì đó và xác minh rằng bản ghi đã hoạt động. Sau khi hoạt động, bạn có thể thử thay đổi SR và cứ tiếp tục như vậy. Đây là một số mã mẫu để ghi. Bắt đầu với điều đó, xác minh rằng nó hoạt động, và sau đó chuyển sang một cái gì đó phức tạp hơn:

http://www.jsresources.org/examples/SimpleAudioRecorder.java.html

0

Thử đặt mã hóa và kích thước khung hình và tốc độ khung hình của AudioFormat.

new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 
        8000f, 
        16, 
        1, 
        2, // frameSize 
        8000f,// frameRate 
        false); 
Các vấn đề liên quan