Tôi đang cố gắng trích xuất mảng biên độ từ tệp âm thanh (tệp WAV). Tôi sẽ sử dụng mảng biên độ này để biên độ âm mưu so với đồ thị thời gian cho tệp wav đã cho. Tôi có thể vẽ đồ thị bản thân mình nhưng không biết làm thế nào để trích xuất biên độ từ tập tin âm thanh (wav) nhất định trong java?Trích xuất mảng biên độ từ tệp wav bằng cách sử dụng JAVA
Trả lời
Đây là lớp trợ giúp mà bạn có thể sử dụng. Phương pháp getSampleInt()
là những gì bạn cần để có được biên độ:
File file = ...;
WavFile wav = new WavFile(file);
int amplitudeExample = wav.getSampleInt(140); // 140th amplitude value.
for (int i = 0; i < wav.getFramesCount(); i++) {
int amplitude = wav.getSampleInt(i);
// Plot.
}
Nó cũng có thể chơi các tập tin để bạn có thể kiểm tra nó, nhưng chỉ có 8 bit, hoặc các tập tin 16bit. Đối với các trường hợp khác, bạn chỉ có thể đọc chúng.
Ngoài ra, hãy xem these diagrams để xem tệp WAV bao gồm và hiểu rõ hơn về những gì lớp này làm.
public class WaveFile {
public final int NOT_SPECIFIED = AudioSystem.NOT_SPECIFIED; // -1
public final int INT_SIZE = 4;
private int sampleSize = NOT_SPECIFIED;
private long framesCount = NOT_SPECIFIED;
private int sampleRate = NOT_SPECIFIED;
private int channelsNum;
private byte[] data; // wav bytes
private AudioInputStream ais;
private AudioFormat af;
private Clip clip;
private boolean canPlay;
public WaveFile(File file) throws UnsupportedAudioFileException, IOException {
if (!file.exists()) {
throw new FileNotFoundException(file.getAbsolutePath());
}
ais = AudioSystem.getAudioInputStream(file);
af = ais.getFormat();
framesCount = ais.getFrameLength();
sampleRate = (int) af.getSampleRate();
sampleSize = af.getSampleSizeInBits()/8;
channelsNum = af.getChannels();
long dataLength = framesCount * af.getSampleSizeInBits() * af.getChannels()/8;
data = new byte[(int) dataLength];
ais.read(data);
AudioInputStream aisForPlay = AudioSystem.getAudioInputStream(file);
try {
clip = AudioSystem.getClip();
clip.open(aisForPlay);
clip.setFramePosition(0);
canPlay = true;
} catch (LineUnavailableException e) {
canPlay = false;
System.out.println("I can play only 8bit and 16bit music.");
}
}
public boolean isCanPlay() {
return canPlay;
}
public void play() {
clip.start();
}
public void stop() {
clip.stop();
}
public AudioFormat getAudioFormat() {
return af;
}
public int getSampleSize() {
return sampleSize;
}
public double getDurationTime() {
return getFramesCount()/getAudioFormat().getFrameRate();
}
public long getFramesCount() {
return framesCount;
}
/**
* Returns sample (amplitude value). Note that in case of stereo samples
* go one after another. I.e. 0 - first sample of left channel, 1 - first
* sample of the right channel, 2 - second sample of the left channel, 3 -
* second sample of the rigth channel, etc.
*/
public int getSampleInt(int sampleNumber) {
if (sampleNumber < 0 || sampleNumber >= data.length/sampleSize) {
throw new IllegalArgumentException(
"sample number can't be < 0 or >= data.length/"
+ sampleSize);
}
byte[] sampleBytes = new byte[4]; //4byte = int
for (int i = 0; i < sampleSize; i++) {
sampleBytes[i] = data[sampleNumber * sampleSize * channelsNum + i];
}
int sample = ByteBuffer.wrap(sampleBytes)
.order(ByteOrder.LITTLE_ENDIAN).getInt();
return sample;
}
public int getSampleRate() {
return sampleRate;
}
public Clip getClip() {
return clip;
}
}
Tôi đã thử mã của bạn và với một vài thay đổi nhỏ mà nó tạo ra kết quả. Có gì sai với dữ liệu mã đặt ra?
tôi thay đổi những dòng sau:
// create file input stream
DataInputStream fis = new DataInputStream(new FileInputStream(wavFile));
// create byte array from file
arrFile = new byte[(int) wavFile.length()];
fis.readFully(arrFile); // make sure you always read the full file, you did not check its return value, so you might be missing some data
Điều thứ hai tôi đã thay đổi là:
System.out.println(Arrays.toString(s.extractAmplitudeFromFile(f)));
Trong phương pháp chính của bạn, vì bạn chỉ được in ra các địa chỉ của arary. Sau khi những thay đổi đó, mã đưa ra một mảng có giá trị, dường như tương quan với dữ liệu mong muốn.
bạn thiếu gì, hoặc bạn mong đợi gì về dữ liệu? Bạn có thể làm rõ câu hỏi thêm một chút không?
điều tôi muốn làm là vẽ đồ thị giữa biên độ và thời gian cho tệp wav cụ thể .... thời gian liên quan đến thời điểm/thời gian hiện tại của tệp wav âm thanh đang được phát ..... vì vậy làm thế nào tôi có thể trích xuất biên độ từ tập tin wav tại những khoảnh khắc khác nhau? PS: Xin vui lòng bỏ qua mã của tôi .... tôi không nghĩ rằng nó có thể là chính xác – Jason
thực sự, mã đã làm việc khá tốt. Tại sao bạn xóa nó? Bạn đã nhận được một mảng chứa số nguyên. Đó là những giá trị biên độ. thời gian được biết vì tỷ lệ lấy mẫu. bạn có thể giải nén nó từ đối tượng audioformat. của nó trong hz, nói rằng bạn có 44100, có nghĩa là 44100 giá trị của mảng là 1 giây. thats cách bạn tính toán thời gian cho một mẫu –
Tôi đã thử nghiệm mã mà bạn đã đăng trước đó với PCM_SIGNED 44100.0 Hz, 16 bit, âm thanh nổi, 4 byte/khung, tệp WAV nhỏ của Windows (ir_begin.wav), nó đã cho tôi giá trị chính xác –
- 1. Cách trích xuất các tần số bán chính xác từ tệp WAV bằng cách sử dụng Biến đổi Fourier
- 2. Trích xuất tọa độ từ tệp KML trong Java
- 3. Trích xuất tọa độ từ tệp KML BatchGeo bằng Python
- 4. Trích xuất hai giá trị kép từ Chuỗi bằng cách sử dụng RegEx trong Java
- 5. Cách phân tích và trích xuất thông tin từ mảng json bằng cách sử dụng json4s
- 6. cách trích xuất các byte cụ thể từ một tệp bằng cách sử dụng unix
- 7. Trích xuất tất cả hình ảnh từ HTML bằng cách sử dụng JAVA
- 8. cách lấy mẫu wav từ tệp wav?
- 9. cách trích xuất dữ liệu từ tệp xml bằng notepad ++?
- 10. Trích xuất văn bản từ tệp pdf bằng cách sử dụng javascript
- 11. Trích xuất nhiều khóa từ một tệp .p12 bằng cách sử dụng OpenSSL ruby
- 12. Trích xuất bảng biểu tượng bằng cách sử dụng clang
- 13. Tham gia hai tệp WAV từ Java?
- 14. cách trích xuất thuộc tính name từ mảng chuỗi?
- 15. Trích xuất giá trị lang bằng cách sử dụng JavaScript
- 16. Trích xuất văn bản từ HTML Java
- 17. Trích xuất văn bản PDF bằng cách sử dụng iText
- 18. Cách phát tệp .wav với java
- 19. Trích xuất mã VB.NET từ tệp exe
- 20. trích xuất các từ từ một tệp
- 21. Trích xuất URL từ một chuỗi bằng cách sử dụng PHP
- 22. Trích xuất các liên kết từ một trang web bằng cách sử dụng Go lang
- 23. Trích xuất biểu tượng ứng dụng từ tệp APK
- 24. Trích xuất hình ảnh phụ từ một hình ảnh bằng cách sử dụng C#
- 25. Trích xuất 1 tệp từ tar.gz bằng bash
- 26. Cách trích xuất tên tệp từ tên đường dẫn tệp?
- 27. trích xuất âm thanh từ một fla
- 28. Trích xuất N dòng từ tập tin bằng cách sử dụng lệnh cửa sổ đơn
- 29. Cách chuyển đổi .wav sang .mp3 bằng Java?
- 30. Cách trích xuất thuộc tính nút từ XML bằng cách sử dụng DOM Parser
sự khác nhau giữa kích thước mẫu 8 bit, 16 bit ... tôi đang sử dụng âm thanh 24 bit ... làm cách nào để sửa đổi mã cho âm thanh 24 bit? và nó cũng cung cấp cho dòng không có ngoại lệ .... và xin vui lòng bạn có thể giải thích các mã chi tiết ... i am mới này api âm thanh và điều âm thanh ... PS: Cảm ơn rất nhiều – Jason
@ Jason nó là một chất lượng. Bạn nên đọc những gì WAV là, trước khi cố gắng đọc nó :) Google, hoặc đăng một câu hỏi khác ở đây. Tôi đã xóa một vài dòng thừa từ ví dụ của tôi - có thể đọc bất kỳ tệp WAV nào, nhưng không thử chơi bất kỳ thứ gì khác ngoài 8bit hoặc 16bit. Java không hỗ trợ điều này, bạn chỉ có thể đọc chúng và vẽ đồ họa theo ý muốn. –
cùng một mã không thể được sử dụng cho tập tin mp3? ... coz các định dạng khác nhau – Jason