-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Separate batch decoding logic into the
batch
submodule (#42)
- Loading branch information
1 parent
0f2f1ad
commit 8ed40dc
Showing
23 changed files
with
494 additions
and
462 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
babycat.batch | ||
============= | ||
|
||
.. py:module:: babycat.batch | ||
This submodule contains functions for decoding/demuxing multiple audio files in parallel. | ||
Parallelism is achieved using multithreadinrg in Rust, which means that decoding will | ||
not be slowed down by the `Python Global Interpreter Lock (GIL) <https://realpython.com/python-gil/>`_. | ||
|
||
Decoding audio | ||
-------------- | ||
.. toctree:: | ||
:maxdepth: 2 | ||
|
||
.waveforms_from_files() <waveforms_from_files> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
babycat.batch.waveforms_from_files() | ||
==================================== | ||
|
||
.. automethod:: babycat.batch.waveforms_from_files |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
//! Functions that use multithreading to manipulate multiple audio files in parallel. | ||
//! | ||
//! This submodule is only available if the Cargo feature | ||
//! `enable-multithreading` is enabled. Functions that read audio from | ||
//! the filesystem also need the Cargo feature `enable-filesystem` | ||
//! to be enabled. Both of these feature are disabled in Babycat's | ||
//! WebAssembly frontend. | ||
use rayon::prelude::*; | ||
use serde::{Deserialize, Serialize}; | ||
|
||
use crate::backend::Waveform; | ||
use crate::backend::WaveformArgs; | ||
use crate::backend::WaveformNamedResult; | ||
|
||
/// The default number of threads to use for multithreaded operations. | ||
/// By default, we will initialize as many threads as *logical* | ||
/// CPU cores on your machine. | ||
pub const DEFAULT_NUM_WORKERS: u32 = 0; | ||
|
||
/// Configures multithreading in Babycat. | ||
#[repr(C)] | ||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] | ||
pub struct BatchArgs { | ||
/// The maximum number of threads to initialize when doing multithreaded work. | ||
/// | ||
/// Babycat uses Rayon for multithreading, which | ||
/// [by default](https://github.com/rayon-rs/rayon/blob/master/FAQ.md) | ||
/// will initialize as many threads as *logical* CPU cores on your machine. | ||
pub num_workers: usize, | ||
} | ||
|
||
impl Default for BatchArgs { | ||
fn default() -> Self { | ||
BatchArgs { | ||
num_workers: DEFAULT_NUM_WORKERS as usize, | ||
} | ||
} | ||
} | ||
|
||
/// Decodes a list of audio files in parallel. | ||
/// | ||
/// # Arguments | ||
/// - `filenames`: A filename of an encoded audio file on the local filesystem. | ||
/// - `waveform_args`: Instructions on how to demux/decode each audio file. | ||
/// - `batch_args`: Instructions on how to divide the work across multiple threads. | ||
/// | ||
/// # Feature flags | ||
/// This function is only available if both of the `enable-filesystem` | ||
/// and `enable-multithreading` features are enabled. These features | ||
/// are enabled by default in Babycat's Rust, Python, and C frontends. | ||
/// These features are disabled in Babycat's WebAssembly frontend. | ||
/// | ||
/// # Examples | ||
/// **(Attempt to) decode three files:** | ||
/// | ||
/// In this example, we process three filenames and demonstrate how to handle errors. | ||
/// The first two files are successfully processed, and we catch a | ||
/// [`Error::FileNotFound`][crate::Error::FileNotFound] error when processing the third file. | ||
/// ``` | ||
/// use babycat::{Error, WaveformArgs, WaveformNamedResult}; | ||
/// use babycat::batch::{BatchArgs, waveforms_from_files}; | ||
/// | ||
/// let filenames = &[ | ||
/// "audio-for-tests/andreas-theme/track.mp3", | ||
/// "audio-for-tests/blippy-trance/track.mp3", | ||
/// "does-not-exist", | ||
/// ]; | ||
/// let decode_args = Default::default(); | ||
/// let batch_args = Default::default(); | ||
/// let batch = waveforms_from_files( | ||
/// filenames, | ||
/// decode_args, | ||
/// batch_args | ||
/// ); | ||
/// | ||
/// fn display_result(wnr: &WaveformNamedResult) -> String { | ||
/// match &wnr.result { | ||
/// Ok(waveform) => format!("\nSuccess: {}:\n{:?}", wnr.name, waveform), | ||
/// Err(err) => format!("\nFailure: {}:\n{}", wnr.name, err), | ||
/// } | ||
/// } | ||
/// assert_eq!( | ||
/// display_result(&batch[0]), | ||
/// " | ||
/// Success: audio-for-tests/andreas-theme/track.mp3: | ||
/// Waveform { frame_rate_hz: 44100, num_channels: 2, num_frames: 9586944}", | ||
/// ); | ||
/// assert_eq!( | ||
/// display_result(&batch[1]), | ||
/// " | ||
/// Success: audio-for-tests/blippy-trance/track.mp3: | ||
/// Waveform { frame_rate_hz: 44100, num_channels: 2, num_frames: 5293440}", | ||
/// ); | ||
/// assert_eq!( | ||
/// display_result(&batch[2]), | ||
/// " | ||
/// Failure: does-not-exist: | ||
/// Cannot find the given filename does-not-exist.", | ||
/// ); | ||
/// ``` | ||
#[allow(dead_code)] // Silence dead code warning because we do not use this function in the C frontend. | ||
pub fn waveforms_from_files( | ||
filenames: &[&str], | ||
waveform_args: WaveformArgs, | ||
batch_args: BatchArgs, | ||
) -> Vec<WaveformNamedResult> { | ||
let thread_pool: rayon::ThreadPool = rayon::ThreadPoolBuilder::new() | ||
.num_threads(batch_args.num_workers) | ||
.build() | ||
.unwrap(); | ||
|
||
let waveforms: Vec<WaveformNamedResult> = thread_pool.install(|| { | ||
filenames | ||
.par_iter() | ||
.map(|filename| WaveformNamedResult { | ||
name: (*filename).to_string(), | ||
result: Waveform::from_file(filename, waveform_args), | ||
}) | ||
.collect() | ||
}); | ||
waveforms | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,16 @@ | ||
mod batch_args; | ||
#[cfg(all(feature = "enable-multithreading", feature = "enable-filesystem"))] | ||
pub mod batch; | ||
mod common; | ||
pub mod decode; | ||
mod errors; | ||
mod named_result; | ||
pub mod resample; | ||
mod waveform; | ||
mod waveform_args; | ||
mod waveform_named_result; | ||
mod waveform_result; | ||
|
||
pub use batch_args::*; | ||
pub use errors::*; | ||
pub use named_result::*; | ||
pub use waveform::*; | ||
pub use waveform_args::*; | ||
pub use waveform_named_result::WaveformNamedResult; | ||
pub use waveform_result::WaveformResult; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
use crate::backend::WaveformResult; | ||
|
||
#[repr(C)] | ||
#[derive(Clone, Debug)] | ||
pub struct WaveformNamedResult { | ||
pub name: String, | ||
pub result: WaveformResult, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
use crate::backend::Error; | ||
use crate::backend::Waveform; | ||
|
||
pub type WaveformResult = Result<Waveform, Error>; |
Oops, something went wrong.