Skip to content

Commit e95cdb8

Browse files
committed
Support decoding of AAC/M4A/ALAC files
1 parent d72ef49 commit e95cdb8

File tree

5 files changed

+25
-22
lines changed

5 files changed

+25
-22
lines changed

Cargo.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,17 @@ name = "my_benchmark"
5050
harness = false
5151

5252
[features]
53-
default = ["mp3", "ogg", "flac", "wav", "cpal"]
53+
default = ["mp3", "ogg", "flac", "wav", "m4a", "alac", "cpal"]
5454
mp3 = ["symphonia/mp3", "creek/decode-mp3"]
5555
ogg = ["symphonia/ogg", "symphonia/vorbis", "creek/decode-ogg", "creek/decode-vorbis"]
5656
flac = ["symphonia/flac", "creek/decode-flac"]
5757
wav = ["symphonia/wav", "symphonia/pcm", "creek/decode-wav", "creek/decode-pcm"]
58+
# TODO(m4a): Add "creek/decode-aac" after <https://github.com/MeadowlarkDAW/creek/pull/22> has been merged
59+
aac = ["symphonia/aac"]
60+
# TODO(m4a): Add "creek/decode-isomp4" after <https://github.com/MeadowlarkDAW/creek/pull/22> has been merged
61+
m4a = ["aac", "symphonia/isomp4"]
62+
# TODO(alac): Add "creek/decode-alac" and "creek/decode-isomp4" after <https://github.com/MeadowlarkDAW/creek/pull/22> has been merged
63+
alac = ["symphonia/alac", "symphonia/isomp4"]
5864
cpal = ["dep:cpal"]
5965
cubeb = ["dep:cubeb"]
6066
cpal-jack = ["cpal", "cpal/jack"]

examples/decoding.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ fn main() {
2222
"samples/sample.flac",
2323
"samples/sample.ogg",
2424
"samples/sample.mp3",
25+
"samples/sample-aac.m4a",
26+
"samples/sample-alac.m4a",
2527
// cannot decode, format not supported or file corrupted
2628
"samples/empty_2c.wav",
2729
"samples/corrupt.wav",

samples/sample-aac.m4a

51.7 KB
Binary file not shown.

samples/sample-alac.m4a

215 KB
Binary file not shown.

src/decoding.rs

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,6 @@ impl Iterator for MediaDecoder {
126126
// Get the track.
127127
let track = format.tracks().get(*track_index)?;
128128
let track_id = track.id;
129-
let number_of_channels = track.codec_params.channels?.count();
130-
let input_sample_rate = track.codec_params.sample_rate? as f32;
131129

132130
loop {
133131
// Get the next packet from the format reader.
@@ -166,8 +164,8 @@ impl Iterator for MediaDecoder {
166164

167165
// Decode the packet into audio samples.
168166
match decoder.decode(&packet) {
169-
Ok(audio_buf) => {
170-
let output = convert_buf(audio_buf, number_of_channels, input_sample_rate);
167+
Ok(input) => {
168+
let output = convert_buf(input);
171169
return Some(Ok(output));
172170
}
173171
Err(SymphoniaError::DecodeError(err)) => {
@@ -188,52 +186,49 @@ impl Iterator for MediaDecoder {
188186
}
189187

190188
/// Convert a Symphonia AudioBufferRef to our own AudioBuffer
191-
fn convert_buf(
192-
input: AudioBufferRef<'_>,
193-
number_of_channels: usize,
194-
input_sample_rate: f32,
195-
) -> AudioBuffer {
196-
let chans = 0..number_of_channels;
189+
fn convert_buf(input: AudioBufferRef<'_>) -> AudioBuffer {
190+
let channels = 0..input.spec().channels.count();
191+
let sample_rate = input.spec().rate as f32;
197192

198193
// This looks a bit awkward but this may be the only way to get the f32 samples
199194
// out without making double copies.
200195
use symphonia::core::audio::AudioBufferRef::*;
201196

202197
let data: Vec<Vec<f32>> = match input {
203-
U8(buf) => chans
198+
U8(buf) => channels
204199
.map(|i| buf.chan(i).iter().copied().map(f32::from_sample).collect())
205200
.collect(),
206-
U16(buf) => chans
201+
U16(buf) => channels
207202
.map(|i| buf.chan(i).iter().copied().map(f32::from_sample).collect())
208203
.collect(),
209-
U24(buf) => chans
204+
U24(buf) => channels
210205
.map(|i| buf.chan(i).iter().copied().map(f32::from_sample).collect())
211206
.collect(),
212-
U32(buf) => chans
207+
U32(buf) => channels
213208
.map(|i| buf.chan(i).iter().copied().map(f32::from_sample).collect())
214209
.collect(),
215-
S8(buf) => chans
210+
S8(buf) => channels
216211
.map(|i| buf.chan(i).iter().copied().map(f32::from_sample).collect())
217212
.collect(),
218-
S16(buf) => chans
213+
S16(buf) => channels
219214
.map(|i| buf.chan(i).iter().copied().map(f32::from_sample).collect())
220215
.collect(),
221-
S24(buf) => chans
216+
S24(buf) => channels
222217
.map(|i| buf.chan(i).iter().copied().map(f32::from_sample).collect())
223218
.collect(),
224-
S32(buf) => chans
219+
S32(buf) => channels
225220
.map(|i| buf.chan(i).iter().copied().map(f32::from_sample).collect())
226221
.collect(),
227-
F32(buf) => chans
222+
F32(buf) => channels
228223
.map(|i| buf.chan(i).iter().copied().map(f32::from_sample).collect())
229224
.collect(),
230-
F64(buf) => chans
225+
F64(buf) => channels
231226
.map(|i| buf.chan(i).iter().copied().map(f32::from_sample).collect())
232227
.collect(),
233228
};
234229

235230
let channels = data.into_iter().map(ChannelData::from).collect();
236-
AudioBuffer::from_channels(channels, input_sample_rate)
231+
AudioBuffer::from_channels(channels, sample_rate)
237232
}
238233

239234
#[cfg(test)]

0 commit comments

Comments
 (0)