Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

setup of riff module, support for PCM aiff #193

Merged
merged 11 commits into from May 1, 2023

Conversation

dedobbin
Copy link
Contributor

@dedobbin dedobbin commented Mar 6, 2023

I set up a RIFF module to support AIFF files. It's heavily based on the wav module.
As discussed, in a future release the WAVE logic should be moved in to this RIFF module, since both WAVE and AIFF are contained in a RIFF file

symphonia-format-riff/Cargo.toml Outdated Show resolved Hide resolved
//
// Select the appropriate codec using bits per sample. Samples are always interleaved and
// little-endian encoded for the PCM format.
let codec = match bits_per_sample {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned, setting bits_per_coded_sample and bits_per_sample correctly in the CodecParameters will make PcmDecoder properly read non-multiple-of-8 samples. The codec type will need to be round up to the nearest multiple, though (e.g., 17 bits = CODEC_TYPE_S24_BE).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried this and it does allow for playback, but the audio is clipping. I manually compared the values in the binary and what Symphonia was reading as samples, and it seemed to be multiplied by 16, but i haven't spent that much time digging into it

The CodecParameter value was properly set to 12 though, so something somewhere else is misbehaving.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it, it could be the decoder then.

symphonia-format-riff/src/chunks.rs Outdated Show resolved Hide resolved
symphonia-format-riff/src/chunks.rs Outdated Show resolved Hide resolved
let mut sample_rate: [u8; 10] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
let _res = reader.read_buf(sample_rate.as_mut());
let sample_rate = Extended::from_be_bytes(sample_rate);
let sample_rate = sample_rate.to_f64() as u32;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is a 0 sample rate an error?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess 0 is valid sample rate?? It doens't make much sense, but the spec doesn't mention much about this field. Not really sure how to validate this value haha.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd probably assume a sample rate of 0 is an error. At least, it's unplayable since samples would never be consumed.

const AIFC_RIFF_FORM: [u8; 4] = *b"AIFC";

/// The maximum number of frames that will be in a packet.
/// Took this from symphonia-format-wav, but I don't know if it's correct.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's arbitrary since there are no packets in WAVE. 1152 is the same as MP3.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated comment to reflect this

@@ -161,6 +161,8 @@ pub mod default {
pub use symphonia_format_mkv::MkvReader;
#[cfg(feature = "ogg")]
pub use symphonia_format_ogg::OggReader;
#[cfg(feature = "riff")]
pub use symphonia_format_riff::RiffReader;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you are still experimenting with this. But presumably this should be an aiff feature, enabling the AiffReader.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm yes, i did it like because in this iteration, the RiffReader only supports Aiff. In an updated version that supports AIFC and lays some groundwork to get WAVE in this structure, there is/should be more separate readers.

Maybe i can even call the feature "aiff" but use the RiffReader. Another option is to rename it here to AiffReader, that bit more clean perhaps.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, i ended up doing it the way you posted here.
In another branch i extracted similar logic from symphonia-format-aiff and symphonia-format-wav to get rid of the copy pasting while still having separate features . Maybe it's best i also incorporate that commit into this branch before we merge. It will make the MR slightly more complex.

Copy link
Owner

@pdeljanov pdeljanov Apr 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I'm a bit confused. I think there are 3 ways forward:

  1. Have a symphonia-format-aiff crate with a single reader: AiffReader. Keep WaveReader in it's own symphonia-format-wave crate. Other RIFF based formats would also have their own crates and readers.
  2. Have generic RIFF crate symphonia-format-riff with a single RiffReader that can read AIFF, WAVE, etc.
  3. Have a generic RIFF crate symphonia-format-riff with multiple readers: AiffReader, WaveReader, etc.

I got the impression that we narrowed our options between 2 and 3, but it seems you landed on 1 in the current iteration. Have I missed anything?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed, 3 it is!

@pdeljanov
Copy link
Owner

You'll need a nightly toolchain to properly format the code! Once you install the nightly toolchain you can run rustfmt with cargo +nightly fmt.

@pdeljanov pdeljanov merged commit abb3aab into pdeljanov:master May 1, 2023
8 checks passed
@pdeljanov
Copy link
Owner

Thanks for your work on this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants