1 use std::sync::Arc;
2 
3 extern crate jni;
4 extern crate ndk_glue;
5 
6 use self::jni::Executor;
7 use self::jni::{errors::Result as JResult, objects::JObject, JNIEnv, JavaVM};
8 
9 // constants from android.media.AudioFormat
10 pub const ENCODING_PCM_16BIT: i32 = 2;
11 pub const ENCODING_PCM_FLOAT: i32 = 4;
12 pub const CHANNEL_OUT_MONO: i32 = 4;
13 pub const CHANNEL_OUT_STEREO: i32 = 12;
14 
with_attached<F, R>(closure: F) -> JResult<R> where F: FnOnce(&JNIEnv, JObject) -> JResult<R>,15 fn with_attached<F, R>(closure: F) -> JResult<R>
16 where
17     F: FnOnce(&JNIEnv, JObject) -> JResult<R>,
18 {
19     let activity = ndk_glue::native_activity();
20     let vm = Arc::new(unsafe { JavaVM::from_raw(activity.vm())? });
21     let activity = activity.activity();
22     Executor::new(vm).with_attached(|env| closure(env, activity.into()))
23 }
24 
get_min_buffer_size( class: &'static str, sample_rate: i32, channel_mask: i32, format: i32, ) -> i3225 fn get_min_buffer_size(
26     class: &'static str,
27     sample_rate: i32,
28     channel_mask: i32,
29     format: i32,
30 ) -> i32 {
31     // Unwrapping everything because these operations are not expected to fail
32     // or throw exceptions. Android returns negative values for invalid parameters,
33     // which is what we expect.
34     with_attached(|env, _activity| {
35         let class = env.find_class(class).unwrap();
36         env.call_static_method(
37             class,
38             "getMinBufferSize",
39             "(III)I",
40             &[sample_rate.into(), channel_mask.into(), format.into()],
41         )
42         .unwrap()
43         .i()
44     })
45     .unwrap()
46 }
47 
get_audio_track_min_buffer_size(sample_rate: i32, channel_mask: i32, format: i32) -> i3248 pub fn get_audio_track_min_buffer_size(sample_rate: i32, channel_mask: i32, format: i32) -> i32 {
49     get_min_buffer_size(
50         "android/media/AudioTrack",
51         sample_rate,
52         channel_mask,
53         format,
54     )
55 }
56 
get_audio_record_min_buffer_size(sample_rate: i32, channel_mask: i32, format: i32) -> i3257 pub fn get_audio_record_min_buffer_size(sample_rate: i32, channel_mask: i32, format: i32) -> i32 {
58     get_min_buffer_size(
59         "android/media/AudioRecord",
60         sample_rate,
61         channel_mask,
62         format,
63     )
64 }
65