Transpiled version (4118L) is out of date.
1 | // https://github.com/s4l4x/audio-analysis/blob/master/src/com/badlogic/audio/io/WaveDecoder.java |
2 | |
3 | /** |
4 | * A simple class that can read in the PCM data from a |
5 | * Wav file, converting the data to signed 32-bit floats |
6 | * in the range [-1,1], merging stereo channels to a mono |
7 | * channel for processing. This only supports 16-bit signed |
8 | * stereo and mono Wav files with a sampling rate of 44100. |
9 | * |
10 | * @author mzechner |
11 | * |
12 | */ |
13 | sclass WAVDecoder /*implements com.badlogic.audio.io.Decoder*/ implements AutoCloseable { |
14 | /** the input stream we read from **/ |
15 | EndianDataInputStream in; |
16 | |
17 | /** number of channels **/ |
18 | int channels; |
19 | |
20 | /** sample rate in Herz**/ |
21 | float sampleRate; |
22 | |
23 | bool ignoreSampleRate = true; |
24 | bool twentyFourBit; |
25 | |
26 | // data length in bytes according to header |
27 | int specifiedDataLength; |
28 | |
29 | int remainingDataBytes; |
30 | |
31 | static int defaultBufferSize = 128*1024; //1024*1024 |
32 | |
33 | *(File wavFile) { |
34 | this(fileInputStream(wavFile)); |
35 | } |
36 | |
37 | *(InputStream stream) ctex { |
38 | in = new EndianDataInputStream( new BufferedInputStream( stream, defaultBufferSize) ); |
39 | if( !in.read4ByteString().equals( "RIFF" ) ) |
40 | throw new IllegalArgumentException( "not a wav" ); |
41 | |
42 | in.readIntLittleEndian(); |
43 | |
44 | if( !in.read4ByteString().equals( "WAVE" ) ) |
45 | throw new IllegalArgumentException( "expected WAVE tag" ); |
46 | |
47 | S s = in.read4ByteString(); |
48 | if (eq(s, "bext")) { // skip extension block |
49 | in.skip(in.readIntLittleEndian()); |
50 | s = in.read4ByteString(); |
51 | } |
52 | |
53 | if (!s.equals("fmt ")) |
54 | throw new IllegalArgumentException( "expected fmt tag, got: " + s); |
55 | |
56 | if( in.readIntLittleEndian() != 16 ) |
57 | throw new IllegalArgumentException( "expected wave chunk size to be 16" ); |
58 | |
59 | int format; |
60 | if ((format = in.readShortLittleEndian()) != 1) |
61 | throw new IllegalArgumentException( "expected format to be 1, got: " + format); |
62 | |
63 | channels = in.readShortLittleEndian(); |
64 | //print("Channels: " + channels); |
65 | sampleRate = in.readIntLittleEndian(); |
66 | if (sampleRate != 44100) |
67 | if (ignoreSampleRate) { |
68 | // print("Sample rate: " + sampleRate); |
69 | } else |
70 | fail("Not 44100 sampling rate: " + sampleRate); |
71 | in.readIntLittleEndian(); |
72 | in.readShortLittleEndian(); |
73 | int fmt = in.readShortLittleEndian(); |
74 | |
75 | if (fmt == 24) twentyFourBit = true; |
76 | else if (fmt != 16) |
77 | fail("Only 16/24-bit samples supported: " + fmt); |
78 | |
79 | S tag; |
80 | while (!(tag = in.read4ByteString()).equals("data")) { |
81 | //print("Skipping tag " + tag); |
82 | //fail( "expected data tag, got: " + tag); |
83 | int len = in.readIntLittleEndian(); |
84 | in.skip(len); |
85 | } |
86 | |
87 | remainingDataBytes = specifiedDataLength = in.readIntLittleEndian(); |
88 | } |
89 | |
90 | /** |
91 | * Tries to read in samples.length samples, merging stereo to a mono |
92 | * channel by averaging and converting non float formats to float 32-bit. |
93 | * Returns the number of samples actually read. Guarantees that samples.length |
94 | * samples are read in if there was enough data in the stream. |
95 | * |
96 | * @param samples The samples array to write the samples to |
97 | * @return The number of samples actually read. |
98 | */ |
99 | public int readMonoSamples(short[] samples, int n default samples.length) { |
100 | int readSamples = 0; |
101 | for (int i = 0; i < n && remainingDataBytes > 0; i++) { |
102 | double sample = 0; |
103 | try { |
104 | for j to channels: |
105 | sample += readSample(); |
106 | sample /= channels; |
107 | samples[i] = (short) iround(max(-32768, min(32767, sample))); |
108 | readSamples++; |
109 | } |
110 | catch (Exception ex) { break; } // ouch |
111 | } |
112 | |
113 | ret readSamples; |
114 | } |
115 | |
116 | public int readStereoSamples(short[] samples, int n default samples.length) { |
117 | int readSamples = 0; |
118 | for (int i = 0; i < n && remainingDataBytes > 0; i += 2) { |
119 | double sample = 0; |
120 | try { |
121 | short left = readSample(); |
122 | short right; |
123 | if (channels > 1) |
124 | right = readSample(); |
125 | else |
126 | right = left; |
127 | samples[i] = left; |
128 | samples[i+1] = right; |
129 | readSamples += 2; |
130 | } |
131 | catch (Exception ex) { break; } // ouch |
132 | } |
133 | |
134 | ret readSamples; |
135 | } |
136 | |
137 | short readSample() ctex { |
138 | if (twentyFourBit) { --remainingDataBytes; in.read(); } |
139 | remainingDataBytes -= 2; |
140 | ret in.readShortLittleEndian(); |
141 | } |
142 | |
143 | int bytesPerValue() { ret twentyFourBit ? 3 : 2; } |
144 | |
145 | int totalValues() { ret specifiedDataLength/bytesPerValue(); } |
146 | |
147 | // skips this number of samples (what is the terminology again |
148 | // for 1 value vs <channels> values) |
149 | public void skipSamples(long samples) ctex { |
150 | long bytesToSkip = samples*channels*bytesPerValue(); |
151 | remainingDataBytes -= bytesToSkip; |
152 | in.skip(bytesToSkip); |
153 | } |
154 | |
155 | public void close() ctex { in.close(); } |
156 | } |
download show line numbers debug dex old transpilations
Travelled to 16 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, ekrmjmnbrukm, gwrvuhgaqvyk, irmadwmeruwu, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv
No comments. add comment
Snippet ID: | #1016681 |
Snippet name: | WAVDecoder |
Eternal ID of this version: | #1016681/36 |
Text MD5: | 9995b9fd715a983c92ae1388a30c1600 |
Author: | stefan |
Category: | javax / sound |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2021-10-17 19:15:36 |
Source code size: | 4956 bytes / 156 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 522 / 1167 |
Version history: | 35 change(s) |
Referenced in: | [show references] |