diff --git a/musikr/src/main/jni/build.rs b/musikr/src/main/jni/build.rs index 50f693467..a16fc91e4 100644 --- a/musikr/src/main/jni/build.rs +++ b/musikr/src/main/jni/build.rs @@ -109,6 +109,9 @@ fn main() { // Build the shim and cxx bridge together cxx_build::bridge("src/taglib/ffi.rs") .file("shim/iostream_shim.cpp") + .file("shim/file_shim.cpp") + .file("shim/string_shim.cpp") + .file("shim/audioproperties_shim.cpp") .include(format!("taglib/pkg/{}/include", arch)) .include("shim") .include(".") // Add the current directory to include path @@ -119,5 +122,11 @@ fn main() { // Rebuild if shim files change println!("cargo:rerun-if-changed=shim/iostream_shim.hpp"); println!("cargo:rerun-if-changed=shim/iostream_shim.cpp"); + println!("cargo:rerun-if-changed=shim/file_shim.hpp"); + println!("cargo:rerun-if-changed=shim/file_shim.cpp"); + println!("cargo:rerun-if-changed=shim/string_shim.hpp"); + println!("cargo:rerun-if-changed=shim/string_shim.cpp"); + println!("cargo:rerun-if-changed=shim/audioproperties_shim.hpp"); + println!("cargo:rerun-if-changed=shim/audioproperties_shim.cpp"); println!("cargo:rerun-if-changed=src/taglib/ffi.rs"); } diff --git a/musikr/src/main/jni/shim/audioproperties_shim.cpp b/musikr/src/main/jni/shim/audioproperties_shim.cpp new file mode 100644 index 000000000..77642f0e0 --- /dev/null +++ b/musikr/src/main/jni/shim/audioproperties_shim.cpp @@ -0,0 +1,26 @@ +#include "audioproperties_shim.hpp" +#include + +namespace taglib_shim { + +const TagLib::AudioProperties* File_audioProperties(const TagLib::File& file) { + return file.audioProperties(); +} + +int AudioProperties_lengthInMilliseconds(const TagLib::AudioProperties* properties) { + return properties->lengthInMilliseconds(); +} + +int AudioProperties_bitrateInKilobitsPerSecond(const TagLib::AudioProperties* properties) { + return properties->bitrate(); +} + +int AudioProperties_sampleRateInHz(const TagLib::AudioProperties* properties) { + return properties->sampleRate(); +} + +int AudioProperties_numberOfChannels(const TagLib::AudioProperties* properties) { + return properties->channels(); +} + +} // namespace taglib_shim \ No newline at end of file diff --git a/musikr/src/main/jni/shim/audioproperties_shim.hpp b/musikr/src/main/jni/shim/audioproperties_shim.hpp new file mode 100644 index 000000000..ee0c38970 --- /dev/null +++ b/musikr/src/main/jni/shim/audioproperties_shim.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +namespace taglib_shim { + +// Audio Properties methods +const TagLib::AudioProperties* File_audioProperties(const TagLib::File& file); +int AudioProperties_lengthInMilliseconds(const TagLib::AudioProperties* properties); +int AudioProperties_bitrateInKilobitsPerSecond(const TagLib::AudioProperties* properties); +int AudioProperties_sampleRateInHz(const TagLib::AudioProperties* properties); +int AudioProperties_numberOfChannels(const TagLib::AudioProperties* properties); + +} // namespace taglib_shim \ No newline at end of file diff --git a/musikr/src/main/jni/shim/file_shim.cpp b/musikr/src/main/jni/shim/file_shim.cpp new file mode 100644 index 000000000..9237dbcf9 --- /dev/null +++ b/musikr/src/main/jni/shim/file_shim.cpp @@ -0,0 +1,66 @@ +#include "file_shim.hpp" + +namespace taglib_shim { + +// FileRef helper functions +bool FileRef_isNull(const TagLib::FileRef& ref) { + return ref.isNull(); +} + +const TagLib::File& FileRef_file(const TagLib::FileRef& ref) { + return *ref.file(); +} + +// File tag methods +bool File_tag(const TagLib::File& file) { + return file.tag() != nullptr; +} + +namespace { + // Keep the empty string as a static member to ensure it lives long enough + const TagLib::String empty_string; +} + +const TagLib::String& File_tag_title(const TagLib::File& file) { + if (auto* tag = file.tag()) { + static TagLib::String title; + title = tag->title(); + return title; + } + return empty_string; +} + +// File type checking functions +bool File_isMPEG(const TagLib::File& file) { + return dynamic_cast(&file) != nullptr; +} + +bool File_isFLAC(const TagLib::File& file) { + return dynamic_cast(&file) != nullptr; +} + +bool File_isMP4(const TagLib::File& file) { + return dynamic_cast(&file) != nullptr; +} + +bool File_isOgg(const TagLib::File& file) { + return dynamic_cast(&file) != nullptr; +} + +bool File_isOpus(const TagLib::File& file) { + return dynamic_cast(&file) != nullptr; +} + +bool File_isWAV(const TagLib::File& file) { + return dynamic_cast(&file) != nullptr; +} + +bool File_isWavPack(const TagLib::File& file) { + return dynamic_cast(&file) != nullptr; +} + +bool File_isAPE(const TagLib::File& file) { + return dynamic_cast(&file) != nullptr; +} + +} // namespace taglib_shim \ No newline at end of file diff --git a/musikr/src/main/jni/shim/file_shim.hpp b/musikr/src/main/jni/shim/file_shim.hpp new file mode 100644 index 000000000..20b85dfe3 --- /dev/null +++ b/musikr/src/main/jni/shim/file_shim.hpp @@ -0,0 +1,43 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace taglib_shim { + +// FileRef helper functions +bool FileRef_isNull(const TagLib::FileRef& ref); +const TagLib::File& FileRef_file(const TagLib::FileRef& ref); + +// File tag methods +bool File_tag(const TagLib::File& file); +const TagLib::String& File_tag_title(const TagLib::File& file); + +// File type checking functions +bool File_isMPEG(const TagLib::File& file); +bool File_isFLAC(const TagLib::File& file); +bool File_isMP4(const TagLib::File& file); +bool File_isOgg(const TagLib::File& file); +bool File_isOpus(const TagLib::File& file); +bool File_isWAV(const TagLib::File& file); +bool File_isWavPack(const TagLib::File& file); +bool File_isAPE(const TagLib::File& file); + +// Audio Properties methods +const TagLib::AudioProperties* File_audioProperties(const TagLib::File& file); +int AudioProperties_length(const TagLib::AudioProperties* properties); +int AudioProperties_bitrate(const TagLib::AudioProperties* properties); +int AudioProperties_sampleRate(const TagLib::AudioProperties* properties); +int AudioProperties_channels(const TagLib::AudioProperties* properties); + +} // namespace taglib_shim \ No newline at end of file diff --git a/musikr/src/main/jni/shim/iostream_shim.cpp b/musikr/src/main/jni/shim/iostream_shim.cpp index d14813eb6..c56079b3c 100644 --- a/musikr/src/main/jni/shim/iostream_shim.cpp +++ b/musikr/src/main/jni/shim/iostream_shim.cpp @@ -1,6 +1,7 @@ #include "iostream_shim.hpp" #include #include +#include // These are the functions we'll define in Rust extern "C" { @@ -26,64 +27,6 @@ std::unique_ptr new_FileRef_from_stream(std::unique_ptr(stream.release(), true); } -// FileRef helper functions -bool FileRef_isNull(const TagLib::FileRef& ref) { - return ref.isNull(); -} - -const TagLib::File& FileRef_file(const TagLib::FileRef& ref) { - return *ref.file(); -} - -// File tag methods -bool File_tag(const TagLib::File& file) { - return file.tag() != nullptr; -} - -namespace { - // Keep the empty string as a static member to ensure it lives long enough - const TagLib::String empty_string; -} - -const TagLib::String& File_tag_title(const TagLib::File& file) { - if (auto* tag = file.tag()) { - static TagLib::String title; - title = tag->title(); - return title; - } - return empty_string; -} - -// Audio Properties methods -const TagLib::AudioProperties* File_audioProperties(const TagLib::File& file) { - return file.audioProperties(); -} - -int AudioProperties_length(const TagLib::AudioProperties* properties) { - return properties->length(); -} - -int AudioProperties_bitrate(const TagLib::AudioProperties* properties) { - return properties->bitrate(); -} - -int AudioProperties_sampleRate(const TagLib::AudioProperties* properties) { - return properties->sampleRate(); -} - -int AudioProperties_channels(const TagLib::AudioProperties* properties) { - return properties->channels(); -} - -// String utilities -const char* to_string(const TagLib::String& str) { - return str.toCString(true); -} - -bool isEmpty(const TagLib::String& str) { - return str.isEmpty(); -} - RustIOStream::RustIOStream(RustStream* stream) : rust_stream(stream) {} RustIOStream::~RustIOStream() = default; diff --git a/musikr/src/main/jni/shim/iostream_shim.hpp b/musikr/src/main/jni/shim/iostream_shim.hpp index 781bf6d63..823a099b5 100644 --- a/musikr/src/main/jni/shim/iostream_shim.hpp +++ b/musikr/src/main/jni/shim/iostream_shim.hpp @@ -4,18 +4,6 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include namespace taglib_shim { @@ -50,56 +38,4 @@ private: std::unique_ptr new_rust_iostream(RustStream* stream); std::unique_ptr new_FileRef_from_stream(std::unique_ptr stream); -// FileRef helper functions -bool FileRef_isNull(const TagLib::FileRef& ref); -const TagLib::File& FileRef_file(const TagLib::FileRef& ref); - -// File tag methods -bool File_tag(const TagLib::File& file); -const TagLib::String& File_tag_title(const TagLib::File& file); - -// File type checking functions -bool File_isMPEG(const TagLib::File& file) { - return dynamic_cast(&file) != nullptr; -} - -bool File_isFLAC(const TagLib::File& file) { - return dynamic_cast(&file) != nullptr; -} - -bool File_isMP4(const TagLib::File& file) { - return dynamic_cast(&file) != nullptr; -} - -bool File_isOgg(const TagLib::File& file) { - return dynamic_cast(&file) != nullptr; -} - -bool File_isOpus(const TagLib::File& file) { - return dynamic_cast(&file) != nullptr; -} - -bool File_isWAV(const TagLib::File& file) { - return dynamic_cast(&file) != nullptr; -} - -bool File_isWavPack(const TagLib::File& file) { - return dynamic_cast(&file) != nullptr; -} - -bool File_isAPE(const TagLib::File& file) { - return dynamic_cast(&file) != nullptr; -} - -// Audio Properties methods -const TagLib::AudioProperties* File_audioProperties(const TagLib::File& file); -int AudioProperties_length(const TagLib::AudioProperties* properties); -int AudioProperties_bitrate(const TagLib::AudioProperties* properties); -int AudioProperties_sampleRate(const TagLib::AudioProperties* properties); -int AudioProperties_channels(const TagLib::AudioProperties* properties); - -// String utilities -const char* to_string(const TagLib::String& str); -bool isEmpty(const TagLib::String& str); - -} \ No newline at end of file +} // namespace taglib_shim \ No newline at end of file diff --git a/musikr/src/main/jni/shim/string_shim.cpp b/musikr/src/main/jni/shim/string_shim.cpp new file mode 100644 index 000000000..53a1a6dc0 --- /dev/null +++ b/musikr/src/main/jni/shim/string_shim.cpp @@ -0,0 +1,13 @@ +#include "string_shim.hpp" + +namespace taglib_shim { + +const char* to_string(const TagLib::String& str) { + return str.toCString(true); +} + +bool isEmpty(const TagLib::String& str) { + return str.isEmpty(); +} + +} // namespace taglib_shim \ No newline at end of file diff --git a/musikr/src/main/jni/shim/string_shim.hpp b/musikr/src/main/jni/shim/string_shim.hpp new file mode 100644 index 000000000..0d5d725af --- /dev/null +++ b/musikr/src/main/jni/shim/string_shim.hpp @@ -0,0 +1,11 @@ +#pragma once + +#include + +namespace taglib_shim { + +// String utilities +const char* to_string(const TagLib::String& str); +bool isEmpty(const TagLib::String& str); + +} // namespace taglib_shim \ No newline at end of file diff --git a/musikr/src/main/jni/src/lib.rs b/musikr/src/main/jni/src/lib.rs index 6c4941b14..cc18f3224 100644 --- a/musikr/src/main/jni/src/lib.rs +++ b/musikr/src/main/jni/src/lib.rs @@ -34,11 +34,7 @@ pub extern "C" fn Java_org_oxycblt_musikr_metadata_MetadataJNI_openFile<'local>( } }; - // Get the file and read the title - let file = file_ref.file(); - let title = file.title().unwrap_or("No title"); - // Return the title - let output = env.new_string(title).expect("Couldn't create string!"); + let output = env.new_string("title").expect("Couldn't create string!"); output.into_raw() } diff --git a/musikr/src/main/jni/src/taglib/ffi.rs b/musikr/src/main/jni/src/taglib/ffi.rs index b7d479742..277178895 100644 --- a/musikr/src/main/jni/src/taglib/ffi.rs +++ b/musikr/src/main/jni/src/taglib/ffi.rs @@ -4,6 +4,9 @@ pub(crate) mod bindings { include!("taglib/taglib.h"); include!("taglib/tstring.h"); include!("shim/iostream_shim.hpp"); + include!("shim/file_shim.hpp"); + include!("shim/string_shim.hpp"); + include!("shim/audioproperties_shim.hpp"); #[namespace = "TagLib"] type FileRef; @@ -58,13 +61,13 @@ pub(crate) mod bindings { #[namespace = "taglib_shim"] unsafe fn File_audioProperties(file: &File) -> *const AudioProperties; #[namespace = "taglib_shim"] - unsafe fn AudioProperties_length(properties: *const AudioProperties) -> i32; + unsafe fn AudioProperties_lengthInMilliseconds(properties: *const AudioProperties) -> i32; #[namespace = "taglib_shim"] - unsafe fn AudioProperties_bitrate(properties: *const AudioProperties) -> i32; + unsafe fn AudioProperties_bitrateInKilobitsPerSecond(properties: *const AudioProperties) -> i32; #[namespace = "taglib_shim"] - unsafe fn AudioProperties_sampleRate(properties: *const AudioProperties) -> i32; + unsafe fn AudioProperties_sampleRateInHz(properties: *const AudioProperties) -> i32; #[namespace = "taglib_shim"] - unsafe fn AudioProperties_channels(properties: *const AudioProperties) -> i32; + unsafe fn AudioProperties_numberOfChannels(properties: *const AudioProperties) -> i32; // String conversion utilities #[namespace = "taglib_shim"] @@ -73,15 +76,3 @@ pub(crate) mod bindings { fn isEmpty(s: &TagString) -> bool; } } - -extern "C" { - // File type checking functions - pub fn File_isMPEG(file: *const bindings::File) -> bool; - pub fn File_isFLAC(file: *const bindings::File) -> bool; - pub fn File_isMP4(file: *const bindings::File) -> bool; - pub fn File_isOgg(file: *const bindings::File) -> bool; - pub fn File_isOpus(file: *const bindings::File) -> bool; - pub fn File_isWAV(file: *const bindings::File) -> bool; - pub fn File_isWavPack(file: *const bindings::File) -> bool; - pub fn File_isAPE(file: *const bindings::File) -> bool; -} diff --git a/musikr/src/main/jni/src/taglib/mod.rs b/musikr/src/main/jni/src/taglib/mod.rs index 828f7ea19..a2432b598 100644 --- a/musikr/src/main/jni/src/taglib/mod.rs +++ b/musikr/src/main/jni/src/taglib/mod.rs @@ -7,10 +7,10 @@ use ffi::bindings; /// Audio properties of a media file #[derive(Default)] pub struct AudioProperties { - pub length: i32, - pub bitrate: i32, - pub sample_rate: i32, - pub channels: i32, + pub length_in_milliseconds: i32, + pub bitrate_in_kilobits_per_second: i32, + pub sample_rate_in_hz: i32, + pub number_of_channels: i32, } pub enum File { @@ -139,10 +139,10 @@ impl FileRef { let props_ptr = ffi::bindings::File_audioProperties(file_ptr); if !props_ptr.is_null() { Some(AudioProperties { - length: ffi::bindings::AudioProperties_length(props_ptr), - bitrate: ffi::bindings::AudioProperties_bitrate(props_ptr), - sample_rate: ffi::bindings::AudioProperties_sampleRate(props_ptr), - channels: ffi::bindings::AudioProperties_channels(props_ptr), + length_in_milliseconds: ffi::bindings::AudioProperties_lengthInMilliseconds(props_ptr), + bitrate_in_kilobits_per_second: ffi::bindings::AudioProperties_bitrateInKilobitsPerSecond(props_ptr), + sample_rate_in_hz: ffi::bindings::AudioProperties_sampleRateInHz(props_ptr), + number_of_channels: ffi::bindings::AudioProperties_numberOfChannels(props_ptr), }) } else { None