WavPack: Support writing tags

This commit is contained in:
Serial 2022-05-30 08:45:08 -04:00
parent 74779369cf
commit 508185c48c
No known key found for this signature in database
GPG key ID: DA95198DC17C4568
8 changed files with 55 additions and 13 deletions

View file

@ -22,7 +22,7 @@ where
let probe = Probe::new(data).guess_file_type()?; let probe = Probe::new(data).guess_file_type()?;
match probe.file_type() { match probe.file_type() {
Some(FileType::APE | FileType::MP3) => {}, Some(FileType::APE | FileType::MP3 | FileType::WavPack) => {},
_ => return Err(LoftyError::new(ErrorKind::UnsupportedTag)), _ => return Err(LoftyError::new(ErrorKind::UnsupportedTag)),
} }

View file

@ -388,7 +388,7 @@ impl FileType {
None None
}, },
82 if buf.len() >= 4 && &buf[..4] == b"wvpk" => Some(Self::WavPack), 119 if buf.len() >= 4 && &buf[..4] == b"wvpk" => Some(Self::WavPack),
_ if buf.len() >= 8 && &buf[4..8] == b"ftyp" => Some(Self::MP4), _ if buf.len() >= 8 && &buf[4..8] == b"ftyp" => Some(Self::MP4),
_ => None, _ => None,
} }

View file

@ -14,7 +14,7 @@ pub(crate) fn write_id3v1(writer: &mut File, tag: &Id3v1TagRef<'_>) -> Result<()
let probe = Probe::new(writer).guess_file_type()?; let probe = Probe::new(writer).guess_file_type()?;
match probe.file_type() { match probe.file_type() {
Some(ft) if ft == FileType::APE || ft == FileType::MP3 => {}, Some(FileType::APE | FileType::MP3 | FileType::WavPack) => {},
_ => return Err(LoftyError::new(ErrorKind::UnsupportedTag)), _ => return Err(LoftyError::new(ErrorKind::UnsupportedTag)),
} }

View file

@ -67,6 +67,7 @@ mod tests {
use crate::ogg::{ use crate::ogg::{
OpusFile, OpusProperties, SpeexFile, SpeexProperties, VorbisFile, VorbisProperties, OpusFile, OpusProperties, SpeexFile, SpeexProperties, VorbisFile, VorbisProperties,
}; };
use crate::wavpack::{WavPackFile, WavPackProperties};
use crate::{AudioFile, FileProperties}; use crate::{AudioFile, FileProperties};
use std::fs::File; use std::fs::File;
@ -194,6 +195,17 @@ mod tests {
channels: 2, channels: 2,
}; };
const WAVPACK_PROPERTIES: WavPackProperties = WavPackProperties {
version: 0,
duration: Duration::from_millis(1428),
overall_bitrate: 598,
audio_bitrate: 598,
sample_rate: 48000,
channels: 2,
bit_depth: 16,
lossless: false,
};
fn get_properties<T>(path: &str) -> T::Properties fn get_properties<T>(path: &str) -> T::Properties
where where
T: AudioFile, T: AudioFile,
@ -293,4 +305,13 @@ mod tests {
WAV_PROPERTIES WAV_PROPERTIES
) )
} }
#[test]
#[ignore] // TODO
fn wavpack_properties() {
assert_eq!(
get_properties::<WavPackFile>("tests/files/assets/minimal/full_test.wv"),
WAVPACK_PROPERTIES
)
}
} }

View file

@ -1,7 +1,7 @@
use crate::error::{ErrorKind, LoftyError, Result}; use crate::error::{ErrorKind, LoftyError, Result};
use crate::file::FileType; use crate::file::FileType;
use crate::tag::{Tag, TagType}; use crate::tag::{Tag, TagType};
use crate::{ape, iff, mp3}; use crate::{ape, iff, mp3, wavpack};
#[cfg(feature = "id3v1")] #[cfg(feature = "id3v1")]
use crate::id3::v1::tag::Id3v1TagRef; use crate::id3::v1::tag::Id3v1TagRef;
@ -36,6 +36,7 @@ pub(crate) fn write_tag(tag: &Tag, file: &mut File, file_type: FileType) -> Resu
crate::mp4::ilst::write::write_to(file, &mut Into::<Ilst>::into(tag.clone()).as_ref()) crate::mp4::ilst::write::write_to(file, &mut Into::<Ilst>::into(tag.clone()).as_ref())
}, },
FileType::WAV => iff::wav::write::write_to(file, tag), FileType::WAV => iff::wav::write::write_to(file, tag),
FileType::WavPack => wavpack::write::write_to(file, tag),
_ => Err(LoftyError::new(ErrorKind::UnsupportedTag)), _ => Err(LoftyError::new(ErrorKind::UnsupportedTag)),
} }
} }

View file

@ -1,6 +1,7 @@
//! WavPack specific items //! WavPack specific items
mod properties; mod properties;
mod read; mod read;
pub(crate) mod write;
#[cfg(feature = "ape")] #[cfg(feature = "ape")]
use crate::ape::tag::ApeTag; use crate::ape::tag::ApeTag;

24
src/wavpack/write.rs Normal file
View file

@ -0,0 +1,24 @@
#[cfg(feature = "ape")]
use crate::ape;
use crate::error::{ErrorKind, LoftyError, Result};
#[cfg(feature = "id3v1")]
use crate::id3::v1;
#[allow(unused_imports)]
use crate::tag::{Tag, TagType};
use std::fs::File;
#[allow(unused_variables)]
pub(crate) fn write_to(data: &mut File, tag: &Tag) -> Result<()> {
match tag.tag_type() {
#[cfg(feature = "ape")]
TagType::Ape => ape::tag::ApeTagRef {
read_only: false,
items: ape::tag::tagitems_into_ape(tag.items()),
}
.write_to(data),
#[cfg(feature = "id3v1")]
TagType::Id3v1 => Into::<v1::tag::Id3v1TagRef<'_>>::into(tag).write_to(data),
_ => Err(LoftyError::new(ErrorKind::UnsupportedTag)),
}
}

View file

@ -16,10 +16,7 @@ fn read() {
crate::verify_artist!(file, tag, TagType::Id3v1, "Bar artist", 1); crate::verify_artist!(file, tag, TagType::Id3v1, "Bar artist", 1);
} }
// TODO
#[test] #[test]
#[ignore]
fn write() { fn write() {
let mut file = temp_file!("tests/files/assets/minimal/full_test.wv"); let mut file = temp_file!("tests/files/assets/minimal/full_test.wv");
@ -28,28 +25,26 @@ fn write() {
assert_eq!(tagged_file.file_type(), FileType::WavPack); assert_eq!(tagged_file.file_type(), FileType::WavPack);
// APE // APE
crate::set_artist!(tagged_file, primary_tag_mut, "Foo artist", 1 => file, "Bar artist"); set_artist!(tagged_file, primary_tag_mut, "Foo artist", 1 => file, "Bar artist");
// ID3v1 // ID3v1
crate::set_artist!(tagged_file, tag_mut, TagType::Id3v1, "Bar artist", 1 => file, "Baz artist"); set_artist!(tagged_file, tag_mut, TagType::Id3v1, "Bar artist", 1 => file, "Baz artist");
// Now reread the file // Now reread the file
file.rewind().unwrap(); file.rewind().unwrap();
let mut tagged_file = lofty::read_from(&mut file, false).unwrap(); let mut tagged_file = lofty::read_from(&mut file, false).unwrap();
crate::set_artist!(tagged_file, primary_tag_mut, "Bar artist", 1 => file, "Foo artist"); set_artist!(tagged_file, primary_tag_mut, "Bar artist", 1 => file, "Foo artist");
crate::set_artist!(tagged_file, tag_mut, TagType::Id3v1, "Baz artist", 1 => file, "Bar artist"); set_artist!(tagged_file, tag_mut, TagType::Id3v1, "Baz artist", 1 => file, "Bar artist");
} }
#[test] #[test]
#[ignore]
fn remove_id3v1() { fn remove_id3v1() {
crate::remove_tag!("tests/files/assets/minimal/full_test.wv", TagType::Id3v1); crate::remove_tag!("tests/files/assets/minimal/full_test.wv", TagType::Id3v1);
} }
#[test] #[test]
#[ignore]
fn remove_ape() { fn remove_ape() {
crate::remove_tag!("tests/files/assets/minimal/full_test.wv", TagType::Ape); crate::remove_tag!("tests/files/assets/minimal/full_test.wv", TagType::Ape);
} }