-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMp3Decoder.java
More file actions
70 lines (60 loc) · 2.63 KB
/
Copy pathMp3Decoder.java
File metadata and controls
70 lines (60 loc) · 2.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package me.tamkungz.codecmedia.internal.audio.mp3;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;
import me.tamkungz.codecmedia.CodecMediaException;
/**
* MP3 decoder that decodes into PCM signed 16-bit little-endian samples.
* <p>
* The implementation relies on Java Sound SPI available at runtime.
*/
public final class Mp3Decoder {
private Mp3Decoder() {
}
public static DecodedPcm decodeToPcm(byte[] encodedMp3Data) throws CodecMediaException {
if (encodedMp3Data == null || encodedMp3Data.length == 0) {
throw new CodecMediaException("MP3 data is empty");
}
try (AudioInputStream source = AudioSystem.getAudioInputStream(new ByteArrayInputStream(encodedMp3Data))) {
AudioFormat sourceFormat = source.getFormat();
int channels = Math.max(1, sourceFormat.getChannels());
float sampleRate = sourceFormat.getSampleRate() > 0 ? sourceFormat.getSampleRate() : 44_100f;
AudioFormat pcmFormat = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
sampleRate,
16,
channels,
channels * 2,
sampleRate,
false
);
try (AudioInputStream pcmStream = AudioSystem.getAudioInputStream(pcmFormat, source)) {
byte[] pcmBytes = readAll(pcmStream);
return new DecodedPcm(pcmBytes, (int) sampleRate, channels, 16);
} catch (IllegalArgumentException e) {
throw new CodecMediaException("Runtime does not provide MP3->PCM conversion via Java Sound", e);
}
} catch (UnsupportedAudioFileException e) {
throw new CodecMediaException("Runtime does not provide an MP3 decoder via Java Sound", e);
} catch (IOException e) {
throw new CodecMediaException("Failed to decode MP3 stream", e);
}
}
private static byte[] readAll(AudioInputStream in) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[8192];
int read;
while ((read = in.read(buffer)) != -1) {
if (read > 0) {
out.write(buffer, 0, read);
}
}
return out.toByteArray();
}
public record DecodedPcm(byte[] pcmS16Le, int sampleRate, int channels, int bitsPerSample) {
}
}