musikr: add flac file
This commit is contained in:
parent
42dfe4edcc
commit
86b04eaead
4 changed files with 91 additions and 50 deletions
|
|
@ -3,49 +3,44 @@
|
|||
namespace taglib_shim
|
||||
{
|
||||
|
||||
const TagLib::Ogg::File *File_asOgg(const TagLib::File *file)
|
||||
TagLib::Ogg::Vorbis::File *File_asVorbis(TagLib::File *file)
|
||||
{
|
||||
return dynamic_cast<const TagLib::Ogg::File *>(file);
|
||||
return dynamic_cast<TagLib::Ogg::Vorbis::File *>(file);
|
||||
}
|
||||
|
||||
const TagLib::Ogg::Vorbis::File *File_asVorbis(const TagLib::File *file)
|
||||
TagLib::Ogg::Opus::File *File_asOpus(TagLib::File *file)
|
||||
{
|
||||
return dynamic_cast<const TagLib::Ogg::Vorbis::File *>(file);
|
||||
return dynamic_cast<TagLib::Ogg::Opus::File *>(file);
|
||||
}
|
||||
|
||||
const TagLib::Ogg::Opus::File *File_asOpus(const TagLib::File *file)
|
||||
TagLib::MPEG::File *File_asMPEG(TagLib::File *file)
|
||||
{
|
||||
return dynamic_cast<const TagLib::Ogg::Opus::File *>(file);
|
||||
return dynamic_cast<TagLib::MPEG::File *>(file);
|
||||
}
|
||||
|
||||
const TagLib::MPEG::File *File_asMPEG(const TagLib::File *file)
|
||||
TagLib::FLAC::File *File_asFLAC(TagLib::File *file)
|
||||
{
|
||||
return dynamic_cast<const TagLib::MPEG::File *>(file);
|
||||
return dynamic_cast<TagLib::FLAC::File *>(file);
|
||||
}
|
||||
|
||||
const TagLib::FLAC::File *File_asFLAC(const TagLib::File *file)
|
||||
TagLib::MP4::File *File_asMP4(TagLib::File *file)
|
||||
{
|
||||
return dynamic_cast<const TagLib::FLAC::File *>(file);
|
||||
return dynamic_cast<TagLib::MP4::File *>(file);
|
||||
}
|
||||
|
||||
const TagLib::MP4::File *File_asMP4(const TagLib::File *file)
|
||||
TagLib::RIFF::WAV::File *File_asWAV(TagLib::File *file)
|
||||
{
|
||||
return dynamic_cast<const TagLib::MP4::File *>(file);
|
||||
return dynamic_cast<TagLib::RIFF::WAV::File *>(file);
|
||||
}
|
||||
|
||||
const TagLib::RIFF::WAV::File *File_asWAV(const TagLib::File *file)
|
||||
TagLib::WavPack::File *File_asWavPack(TagLib::File *file)
|
||||
{
|
||||
return dynamic_cast<const TagLib::RIFF::WAV::File *>(file);
|
||||
return dynamic_cast<TagLib::WavPack::File *>(file);
|
||||
}
|
||||
|
||||
const TagLib::WavPack::File *File_asWavPack(const TagLib::File *file)
|
||||
TagLib::APE::File *File_asAPE(TagLib::File *file)
|
||||
{
|
||||
return dynamic_cast<const TagLib::WavPack::File *>(file);
|
||||
}
|
||||
|
||||
const TagLib::APE::File *File_asAPE(const TagLib::File *file)
|
||||
{
|
||||
return dynamic_cast<const TagLib::APE::File *>(file);
|
||||
return dynamic_cast<TagLib::APE::File *>(file);
|
||||
}
|
||||
|
||||
} // namespace taglib_shim
|
||||
|
|
@ -17,15 +17,13 @@
|
|||
namespace taglib_shim
|
||||
{
|
||||
|
||||
// File conversion functions
|
||||
const TagLib::Ogg::File *File_asOgg(const TagLib::File *file);
|
||||
const TagLib::Ogg::Vorbis::File *File_asVorbis(const TagLib::File *file);
|
||||
const TagLib::Ogg::Opus::File *File_asOpus(const TagLib::File *file);
|
||||
const TagLib::MPEG::File *File_asMPEG(const TagLib::File *file);
|
||||
const TagLib::FLAC::File *File_asFLAC(const TagLib::File *file);
|
||||
const TagLib::MP4::File *File_asMP4(const TagLib::File *file);
|
||||
const TagLib::RIFF::WAV::File *File_asWAV(const TagLib::File *file);
|
||||
const TagLib::WavPack::File *File_asWavPack(const TagLib::File *file);
|
||||
const TagLib::APE::File *File_asAPE(const TagLib::File *file);
|
||||
TagLib::Ogg::Vorbis::File *File_asVorbis(TagLib::File *file);
|
||||
TagLib::Ogg::Opus::File *File_asOpus(TagLib::File *file);
|
||||
TagLib::MPEG::File *File_asMPEG(TagLib::File *file);
|
||||
TagLib::FLAC::File *File_asFLAC(TagLib::File *file);
|
||||
TagLib::MP4::File *File_asMP4(TagLib::File *file);
|
||||
TagLib::RIFF::WAV::File *File_asWAV(TagLib::File *file);
|
||||
TagLib::WavPack::File *File_asWavPack(TagLib::File *file);
|
||||
TagLib::APE::File *File_asAPE(TagLib::File *file);
|
||||
|
||||
} // namespace taglib_shim
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
use std::collections::HashMap;
|
||||
use std::ffi::CStr;
|
||||
use std::pin::Pin;
|
||||
use std::pin::{pin, Pin};
|
||||
use std::string::ToString;
|
||||
|
||||
#[cxx::bridge]
|
||||
|
|
@ -74,6 +74,9 @@ pub(crate) mod bindings {
|
|||
#[namespace = "TagLib::FLAC"]
|
||||
#[cxx_name = "File"]
|
||||
type FLACFile;
|
||||
#[cxx_name = "xiphComment"]
|
||||
unsafe fn flacThisXiphComment(self: Pin<&mut FLACFile>, create: bool) -> *mut XiphComment;
|
||||
|
||||
#[namespace = "TagLib::MPEG"]
|
||||
#[cxx_name = "File"]
|
||||
type MPEGFile;
|
||||
|
|
@ -94,25 +97,22 @@ pub(crate) mod bindings {
|
|||
#[cxx_name = "File"]
|
||||
type APEFile;
|
||||
|
||||
// File conversion functions
|
||||
#[namespace = "taglib_shim"]
|
||||
unsafe fn File_asOgg(file: *const BaseFile) -> *const OggFile;
|
||||
unsafe fn File_asVorbis(file: *mut BaseFile) -> *mut VorbisFile;
|
||||
#[namespace = "taglib_shim"]
|
||||
unsafe fn File_asVorbis(file: *const BaseFile) -> *const VorbisFile;
|
||||
unsafe fn File_asOpus(file: *mut BaseFile) -> *mut OpusFile;
|
||||
#[namespace = "taglib_shim"]
|
||||
unsafe fn File_asOpus(file: *const BaseFile) -> *const OpusFile;
|
||||
unsafe fn File_asMPEG(file: *mut BaseFile) -> *mut MPEGFile;
|
||||
#[namespace = "taglib_shim"]
|
||||
unsafe fn File_asMPEG(file: *const BaseFile) -> *const MPEGFile;
|
||||
unsafe fn File_asFLAC(file: *mut BaseFile) -> *mut FLACFile;
|
||||
#[namespace = "taglib_shim"]
|
||||
unsafe fn File_asFLAC(file: *const BaseFile) -> *const FLACFile;
|
||||
unsafe fn File_asMP4(file: *mut BaseFile) -> *mut MP4File;
|
||||
#[namespace = "taglib_shim"]
|
||||
unsafe fn File_asMP4(file: *const BaseFile) -> *const MP4File;
|
||||
unsafe fn File_asWAV(file: *mut BaseFile) -> *mut WAVFile;
|
||||
#[namespace = "taglib_shim"]
|
||||
unsafe fn File_asWAV(file: *const BaseFile) -> *const WAVFile;
|
||||
unsafe fn File_asWavPack(file: *mut BaseFile) -> *mut WavPackFile;
|
||||
#[namespace = "taglib_shim"]
|
||||
unsafe fn File_asWavPack(file: *const BaseFile) -> *const WavPackFile;
|
||||
#[namespace = "taglib_shim"]
|
||||
unsafe fn File_asAPE(file: *const BaseFile) -> *const APEFile;
|
||||
unsafe fn File_asAPE(file: *mut BaseFile) -> *mut APEFile;
|
||||
|
||||
#[namespace = "TagLib"]
|
||||
type SimplePropertyMap;
|
||||
|
|
@ -143,7 +143,7 @@ pub(crate) mod bindings {
|
|||
}
|
||||
|
||||
impl bindings::FileRef {
|
||||
pub fn file_or(&self) -> Option<&bindings::BaseFile> {
|
||||
pub fn file_or(&self) -> Option<&mut bindings::BaseFile> {
|
||||
let file = unsafe {
|
||||
// SAFETY:
|
||||
// - This pin is only used in this unsafe scope.
|
||||
|
|
@ -168,7 +168,7 @@ impl bindings::FileRef {
|
|||
// - This points to a C++FFI type ensured to be valid by cxx's codegen.
|
||||
// - There are no datapaths that will yield any mutable pointers or references
|
||||
// to this, ensuring that it will not be mutated as per the aliasing rules.
|
||||
file.as_ref()
|
||||
file.as_mut()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -196,8 +196,8 @@ impl bindings::BaseFile {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn as_opus(&self) -> Option<&bindings::OpusFile> {
|
||||
let ptr_self = self as *const Self;
|
||||
pub fn as_opus(&mut self) -> Option<&mut bindings::OpusFile> {
|
||||
let ptr_self = self as *mut Self;
|
||||
let opus_file = unsafe {
|
||||
// SAFETY:
|
||||
// This FFI function will be a simple C++ dynamic_cast, which checks if
|
||||
|
|
@ -212,12 +212,12 @@ impl bindings::BaseFile {
|
|||
// - This points to a C++FFI type ensured to be valid by cxx's codegen.
|
||||
// - There are no datapaths that will yield any mutable pointers or references
|
||||
// to this, ensuring that it will not be mutated as per the aliasing rules.
|
||||
opus_file.as_ref()
|
||||
opus_file.as_mut()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_vorbis(&self) -> Option<&bindings::VorbisFile> {
|
||||
let ptr_self = self as *const Self;
|
||||
pub fn as_vorbis(&mut self) -> Option<&bindings::VorbisFile> {
|
||||
let ptr_self = self as *mut Self;
|
||||
let vorbis_file = unsafe {
|
||||
// SAFETY:
|
||||
// This FFI function will be a simple C++ dynamic_cast, which checks if
|
||||
|
|
@ -235,6 +235,26 @@ impl bindings::BaseFile {
|
|||
vorbis_file.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_flac(&mut self) -> Option<&mut bindings::FLACFile> {
|
||||
let ptr_self = self as *mut Self;
|
||||
let flac_file = unsafe {
|
||||
// SAFETY:
|
||||
// This FFI function will be a simple C++ dynamic_cast, which checks if
|
||||
// the file can be cased down to an opus file. If the cast fails, a null
|
||||
// pointer is returned, which will be handled by as_ref's null checking.
|
||||
bindings::File_asFLAC(ptr_self)
|
||||
};
|
||||
unsafe {
|
||||
// SAFETY:
|
||||
// - This points to a C++ FFI type ensured to be aligned by cxx's codegen.
|
||||
// - The null-safe version is being used.
|
||||
// - This points to a C++FFI type ensured to be valid by cxx's codegen.
|
||||
// - There are no datapaths that will yield any mutable pointers or references
|
||||
// to this, ensuring that it will not be mutated as per the aliasing rules.
|
||||
flac_file.as_mut()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl bindings::AudioProperties {
|
||||
|
|
@ -325,6 +345,26 @@ impl bindings::VorbisFile {
|
|||
}
|
||||
}
|
||||
|
||||
impl bindings::FLACFile {
|
||||
pub fn xiph_comments(&mut self) -> Option<&bindings::XiphComment> {
|
||||
let tag = unsafe {
|
||||
// SAFETY:
|
||||
// - This pin is only used in this unsafe scope.
|
||||
// - The pin is used as a C++ this pointer in the ffi call, which does
|
||||
// not change address by C++ semantics.
|
||||
// - The value is a pointer that does not depend on the address of self.
|
||||
let this = Pin::new_unchecked(self);
|
||||
// SAFETY: This is a C++ FFI function ensured to call correctly.
|
||||
this.flacThisXiphComment(false)
|
||||
};
|
||||
unsafe {
|
||||
// SAFETY: This pointer is a valid type, and can only used and accessed
|
||||
// via this function and thus cannot be mutated, satisfying the aliasing rules.
|
||||
tag.as_ref()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl bindings::XiphComment {
|
||||
pub fn field_list_map(&self) -> &bindings::SimplePropertyMap {
|
||||
unsafe {
|
||||
|
|
|
|||
|
|
@ -99,6 +99,14 @@ impl FileRef {
|
|||
audio_properties,
|
||||
xiph_comments,
|
||||
})
|
||||
} else if let Some(flac_file) = file.as_flac() {
|
||||
let xiph_comments = flac_file
|
||||
.xiph_comments()
|
||||
.map(|comments| comments.field_list_map().to_hashmap());
|
||||
Some(File::FLAC {
|
||||
audio_properties,
|
||||
xiph_comments,
|
||||
})
|
||||
} else {
|
||||
Some(File::Unknown { audio_properties })
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue