Skip to content

Commit

Permalink
fix memory leak in Soloud
Browse files Browse the repository at this point in the history
  • Loading branch information
MoAlyousef committed Aug 7, 2023
1 parent 82eebf7 commit a2a7eda
Show file tree
Hide file tree
Showing 9 changed files with 56 additions and 195 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
# Changelog


## [1.0.4] - 2023-08-08
- Fix memory leak in Soloud initialization.

## [1.0.3] - 2023-07-24
- Update Soloud submodule.

## [1.0.2] - 2022-02-17
- Add scrape examples to docs.rs.

## [1.0.1] - 2022-01-16
- Update soloud module.
- Remove references to LoadExt::load_mem_weak().
Expand Down
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ soloud = { git = "https://github.com/moalyousef/soloud-rs" }
```

To play audio:
```rust
```rust,no_run
use soloud::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
Expand All @@ -53,7 +53,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
```

To play speech:
```rust
```rust,no_run
use soloud::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
Expand Down Expand Up @@ -87,7 +87,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
```

To add a filter:
```rust
```rust,no_run
use soloud::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
Expand All @@ -110,11 +110,11 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
```

The examples can be found in the soloud/examples directory. They can be run using:
```
$ cargo run --example simple
$ cargo run --example speech
$ cargo run --example filter
$ cargo run --example load_mem
```bash
cargo run --example simple
cargo run --example speech
cargo run --example filter
cargo run --example load_mem
```
You will need to have valid "sample.wav" and "Recording.mp3" audio files in the project root. Or you can change the paths to point to any supported audio file.

Expand All @@ -130,12 +130,12 @@ The default backend is miniaudio, however Soloud supports several backends to va
soloud = { version = "1", default-features = false, features = ["alsa"] }
```
This also assumes that those libraries headers are in your include path where CMake can find them, otherwise you can set it via the command line (posix):
```
$ export CXXFLAGS="-I /path/to/include"
```bash
export CXXFLAGS="-I /path/to/include"
```
or for Windows:
```
$ set CXXFLAGS="-I C:\\path\\to\\include"
```bash
set CXXFLAGS="-I C:\\path\\to\\include"
```
The same can be done for CFLAGS if needed.

Expand Down
2 changes: 1 addition & 1 deletion soloud-sys/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "soloud-sys"
version = "1.0.3"
version = "1.0.4"
authors = ["MoAlyousef <mohammed.alyousef@neurosrg.com>"]
edition = "2018"
build = "build/main.rs"
Expand Down
2 changes: 1 addition & 1 deletion soloud-sys/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ soloud-sys = { version = "1", features = ["miniaudio"] }
```

Example code:
```rust
```rust,no_run
use soloud_sys::soloud::*;
fn main() {
Expand Down
1 change: 1 addition & 0 deletions soloud-sys/build/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![allow(clippy::needless_borrow)]
use std::{env, path::PathBuf};

mod android;
Expand Down
37 changes: 1 addition & 36 deletions soloud-sys/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,40 +1,5 @@
/*!
# soloud-sys
#![doc = include_str!("../README.md")]

Raw bindings to soloud. These are generated using bindgen on the soloud C headers.
## Usage
```toml
[dependencies]
soloud-sys = { version = "1", features = ["miniaudio"] }
```
Example code:
```rust,no_run
use soloud_sys::soloud::*;
fn main() {
unsafe {
let sl = Soloud_create();
Soloud_init(sl);
std::thread::sleep(std::time::Duration::from_millis(100));
Soloud_setGlobalVolume(sl, 3.0);
let speech = Speech_create();
let ret = Speech_setText(speech, "Hello World\0".as_ptr() as _);
dbg!(ret);
Soloud_play(sl, speech);
while Soloud_getVoiceCount(sl) > 0 {
// calls to play are non-blocking, so we put the thread to sleep
std::thread::sleep(std::time::Duration::from_millis(100));
}
}
}
```
*/
#![allow(non_camel_case_types)]
#![allow(dead_code)]
#![allow(non_upper_case_globals)]
Expand Down
2 changes: 1 addition & 1 deletion soloud/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "soloud"
version = "1.0.3"
version = "1.0.4"
authors = ["MoAlyousef <mohammed.alyousef@neurosrg.com>"]
edition = "2018"
description = "Rust bindings for the soloud audio engine"
Expand Down
164 changes: 21 additions & 143 deletions soloud/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,142 +1,9 @@
//! # soloud
//!
//! Rust bindings for the soloud audio engine library.
//!
//! Supported formats: wav, mp3, ogg. The library also comes with a speech synthesizer.
//!
//!
//! - The official soloud [website](https://sol.gfxile.net/soloud/index.html)
//! - The official soloud [repo](https://github.com/jarikomppa/soloud)
//!
//! ## Usage
//! ```toml
//! [dependencies]
//! soloud = "1"
//! ```
//!
//! Or to use the latest developments:
//! ```toml
//! [dependencies]
//! soloud = { git = "https://!github.com/moalyousef/soloud-rs" }
//! ```
//!
//! To play audio:
//! ```no_run
//! use soloud::*;
//!
//! fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let mut sl = Soloud::default()?;
//!
//! let mut wav = audio::Wav::default();
//!
//! wav.load(&std::path::Path::new("sample.wav"))?;
//!
//! sl.play(&wav);
//! while sl.voice_count() > 0 {
//! std::thread::sleep(std::time::Duration::from_millis(100));
//! }
//!
//! wav.load(&std::path::Path::new("Recording.mp3"))?;
//!
//! sl.play(&wav);
//! while sl.voice_count() > 0 {
//! std::thread::sleep(std::time::Duration::from_millis(100));
//! }
//!
//! Ok(())
//! }
//! ```
//!
//! To play speech:
//! ```no_run
//! use soloud::*;
//!
//! fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let mut sl = Soloud::default()?;
//!
//! let mut speech = audio::Speech::default();
//!
//! speech.set_text("Hello World")?;
//!
//! sl.play(&speech);
//! while sl.active_voice_count() > 0 {
//! std::thread::sleep(std::time::Duration::from_millis(100));
//! }
//!
//! speech.set_text("1 2 3")?;
//!
//! sl.play(&speech);
//! while sl.active_voice_count() > 0 {
//! std::thread::sleep(std::time::Duration::from_millis(100));
//! }
//!
//! speech.set_text("Can you hear me?")?;
//!
//! sl.play(&speech);
//! while sl.active_voice_count() > 0 {
//! std::thread::sleep(std::time::Duration::from_millis(100));
//! }
//!
//! Ok(())
//! }
//! ```
//!
//! To add a filter:
//! ```no_run
//! use soloud::*;
//!
//! fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let mut sl = Soloud::default()?;
//!
//! let mut wav = audio::Wav::default();
//! let mut filt = filter::EchoFilter::default();
//! filt.set_params(0.2)?;
//!
//! wav.load(&std::path::Path::new("sample.wav"))?;
//! wav.set_filter(0, Some(&filt));
//!
//! sl.play(&wav);
//! while sl.voice_count() > 0 {
//! std::thread::sleep(std::time::Duration::from_millis(100));
//! }
//!
//! Ok(())
//! }
//! ```
//! ## Backends
//! The default backend is miniaudio, however Soloud supports several backends to varying degrees. To enable support of a certain backend, alsa for example:
//! ```toml
//! [dependencies]
//! soloud = { version = "1", default-features = false, features = ["alsa"] }
//! ```
//! This also assumes that those libraries headers are in your include path where CMake can find them, otherwise you can set it via the command line (posix):
//! ```sh
//! $ export CXXFLAGS="-I /path/to/include"
//! ```
//! or for Windows:
//! ```sh
//! $ set CXXFLAGS="-I C:\\path\\to\\include"
//! ```
//! The same can be done for CFLAGS if needed.
//!
//! ### Supported backends:
//! - miniaudio
//! - oss
//! - alsa
//! - sdl2
//! - sdl2-static
//! - portaudio
//! - openal
//! - xaudio2
//! - winmm
//! - wasapi
//! - opensles
//! - coreaudio
//! - jack
#![doc = include_str!("../README.md")]

#![allow(unused_unsafe)]
#![allow(non_upper_case_globals)]
#![warn(missing_docs)]
#![allow(clippy::too_many_arguments)]

/// FFI function call with error handling
///
Expand Down Expand Up @@ -235,7 +102,9 @@ unsafe impl Sync for Soloud {}

impl Soloud {
/// Creates an uninitialized instance of a Soloud engine
pub fn default_uninit() -> std::mem::MaybeUninit<Self> {
/// # Safety
/// Creates an uninitialized instance of Soloud
pub unsafe fn default_uninit() -> std::mem::MaybeUninit<Self> {
unsafe {
let ptr = ffi::Soloud_create();
assert!(!ptr.is_null());
Expand All @@ -244,16 +113,21 @@ impl Soloud {
}

/// initialize an uninitialized instance of Soloud
pub fn init(&mut self) -> Result<(), SoloudError> {
/// # Safety
/// initializes an uninitialized instance of Soloud
pub unsafe fn init(&mut self) -> Result<(), SoloudError> {
assert!(!self.inner.is_null());
ffi_call!(ffi::Soloud_init(self.inner))
}

/// Creates a default initialized instance of soloud
#[allow(clippy::should_implement_trait)]
pub fn default() -> Result<Self, SoloudError> {
let mut temp = unsafe { Soloud::default_uninit().assume_init() };
temp.init()?;
Ok(temp)
unsafe {
let mut temp = Soloud::default_uninit().assume_init();
temp.init()?;
Ok(temp)
}
}

/// initialize an uninitialized instance of Soloud with extra args
Expand Down Expand Up @@ -512,11 +386,12 @@ impl Soloud {
}

/// Deinitialize the soloud engine
pub(crate) fn deinit(&mut self) {
/// # Safety
/// Deinitializing will require correct reinitialization
pub unsafe fn deinit(&mut self) {
assert!(!self.inner.is_null());
unsafe {
ffi::Soloud_deinit(self.inner);
self.inner = std::ptr::null_mut();
}
}

Expand Down Expand Up @@ -1249,7 +1124,10 @@ impl Soloud {
impl Drop for Soloud {
fn drop(&mut self) {
if !self.inner.is_null() {
self.deinit()
unsafe {
self.deinit();
ffi::Soloud_destroy(self.inner);
}
}
}
}
Loading

0 comments on commit a2a7eda

Please sign in to comment.