1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
#[cfg(test)]
mod tests {
use super::*;
use std::ffi::{c_void, CString};
use std::os::raw::c_int;
const MINIMAL_SOUND_FONT: &'static [u8] = &[
b'R',b'I',b'F',b'F',220,1,0,0,b's',b'f',b'b',b'k',
b'L',b'I',b'S',b'T',88,1,0,0,b'p',b'd',b't',b'a',
b'p',b'h',b'd',b'r',76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,0,255,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
b'p',b'b',b'a',b'g',8,0,0,0,0,0,0,0,1,0,0,0,b'p',b'm',b'o',b'd',10,0,0,0,0,0,0,0,0,0,0,0,0,0,b'p',b'g',b'e',b'n',8,0,0,0,41,0,0,0,0,0,0,0,
b'i',b'n',b's',b't',44,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
b'i',b'b',b'a',b'g',8,0,0,0,0,0,0,0,2,0,0,0,b'i',b'm',b'o',b'd',10,0,0,0,0,0,0,0,0,0,0,0,0,0,
b'i',b'g',b'e',b'n',12,0,0,0,54,0,1,0,53,0,0,0,0,0,0,0,
b's',b'h',b'd',b'r',92,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,50,0,0,0,0,0,0,0,49,0,0,0,34,86,0,0,60,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
b'L',b'I',b'S',b'T',112,0,0,0,b's',b'd',b't',b'a',b's',b'm',b'p',b'l',100,0,0,0,86,0,119,3,31,7,147,10,43,14,169,17,58,21,189,24,73,28,204,31,73,35,249,38,46,42,71,46,250,48,150,53,242,55,126,60,151,63,108,66,126,72,207,
70,86,83,100,72,74,100,163,39,241,163,59,175,59,179,9,179,134,187,6,186,2,194,5,194,15,200,6,202,96,206,159,209,35,213,213,216,45,220,221,223,76,227,221,230,91,234,242,237,105,241,8,245,118,248,32,252
];
#[test]
fn load_memory() {
unsafe {
let sf_ptr = MINIMAL_SOUND_FONT.as_ptr();
let sf_len = MINIMAL_SOUND_FONT.len();
let tsf = tsf_load_memory(sf_ptr as *const c_void, sf_len as c_int);
let preset_count = tsf_get_presetcount(tsf);
assert_eq!(1, preset_count);
tsf_close(tsf);
}
}
#[test]
fn load_filename_and_render_c3() {
unsafe {
let filename = CString::new("test_resources/sinewave.sf2").unwrap();
let tsf = tsf_load_filename(filename.as_ptr());
let preset_count = tsf_get_presetcount(tsf);
assert_eq!(1, preset_count);
let sample_rate = 44100;
let samples = sample_rate / 10;
let output_mode = TSFOutputMode_TSF_MONO;
let channels = 1;
let note: c_int = 48;
tsf_set_output(tsf, output_mode, sample_rate as c_int, 0f32);
{
let mut dst: Vec<f32> = Vec::with_capacity(samples * channels);
let dst_ptr: *mut f32 = dst.as_mut_ptr();
tsf_render_float(tsf, dst_ptr, samples as c_int, 0);
dst.set_len(samples * channels);
assert!(dst.iter().all(|x| *x == 0f32), "Didn't get silence");
}
tsf_note_on(tsf, 0 as c_int, note, 1.0f32);
{
let mut dst: Vec<f32> = Vec::with_capacity(samples * channels);
let dst_ptr: *mut f32 = dst.as_mut_ptr();
tsf_render_float(tsf, dst_ptr, samples as c_int, 0);
dst.set_len(samples * channels);
assert!(dst.iter().any(|x| *x != 0f32), "Got silence");
let (_, csv) = dst.iter().fold((0, String::new()), |acc, x| {
let (next_note_index, string_builder) = acc;
(next_note_index + 1, string_builder + &format!("{},{}\n", next_note_index as f32 / sample_rate as f32, x))
});
std::fs::create_dir_all("test_outputs").expect("Failed to create test_outputs directory - is there a non-directory already with that name?");
std::fs::write("test_outputs/load_soundfont_from_file_and_render_c3.csv", csv).expect("Failed to write file");
}
tsf_close(tsf);
}
}
}