use {
crate::{
makepad_platform::audio::*,
makepad_platform::midi::*,
register_audio_component,
audio_traits::*,
makepad_platform::os::apple::audio_unit::*,
makepad_platform::thread::*,
makepad_platform::*
},
};
live_design!{
pub AudioUnitInstrument= {{AudioUnitInstrument}} {
plugin: "FM8"
}
}
enum ToUI {
NewAudioUnit(AudioUnit),
UIReady
}
enum FromUI {
NewAudioUnit(AudioUnitClone)
}
#[derive(Live)]
struct AudioUnitInstrument {
#[live] plugin: String,
#[live] preset_data: String,
#[rust] audio_unit: Option<AudioUnit>,
#[rust] from_ui: FromUISender<FromUI>,
#[rust] to_ui: ToUIReceiver<ToUI>,
}
impl LiveRegister for AudioUnitInstrument{
fn live_register(cx: &mut Cx){
register_audio_component!(cx, AudioUnitInstrument)
}
}
impl LiveHook for AudioUnitInstrument{
fn after_new_from_doc(&mut self, _cx: &mut Cx) {
self.load_audio_unit();
}
}
struct Node {
from_ui: FromUIReceiver<FromUI>,
audio_unit: Option<AudioUnitClone>
}
impl AudioGraphNode for Node {
fn handle_midi_data(&mut self, data: MidiData) {
if let Some(audio_unit) = &self.audio_unit {
audio_unit.handle_midi_data(data);
}
}
fn all_notes_off(&mut self) {
}
fn render_to_audio_buffer(
&mut self,
info: AudioInfo,
outputs: &mut [&mut AudioBuffer],
inputs: &[&AudioBuffer],
display: &mut DisplayAudioGraph
) {
while let Ok(msg) = self.from_ui.try_recv() {
match msg {
FromUI::NewAudioUnit(audio_unit) => {
self.audio_unit = Some(audio_unit);
}
}
}
if let Some(audio_unit) = &self.audio_unit {
audio_unit.render_to_audio_buffer(info, outputs, inputs);
let display_buffer = display.pop_buffer_resize(outputs[0].frame_count(), outputs[0].channel_count());
if let Some(mut buf) = display_buffer {
buf.copy_from(&outputs[0]);
display.send_buffer(true, 0, buf);
}
}
}
}
impl AudioUnitInstrument {
fn load_audio_unit(&mut self) {
let list = AudioUnitAccess::query_audio_units(AudioUnitQuery::MusicDevice);
let sender = self.to_ui.sender();
if let Some(info) = list.iter().find( | item | item.name == self.plugin) {
AudioUnitAccess::new_audio_plugin(info, move | result | {
match result {
Ok(audio_unit) => {
let sender2 = sender.clone();
audio_unit.request_ui(move || {
sender2.send(ToUI::UIReady).unwrap()
});
sender.send(ToUI::NewAudioUnit(audio_unit)).unwrap();
}
Err(err) => error!("Error {:?}", err)
}
})
}
else {
error!("Cannot find music device {}", self.plugin);
for item in &list {
error!("MusicDevices: {}", item.name);
}
}
}
}
impl AudioComponent for AudioUnitInstrument {
fn get_graph_node(&mut self, _cx: &mut Cx) -> Box<dyn AudioGraphNode + Send> {
self.from_ui.new_channel();
Box::new(Node {
from_ui: self.from_ui.receiver(),
audio_unit: if let Some(audio_unit) = &self.audio_unit {Some(audio_unit.clone())}else {None}
})
}
fn handle_event_with(&mut self, _cx: &mut Cx, _event: &Event, _dispatch_action: &mut dyn FnMut(&mut Cx, AudioComponentAction)) {
while let Ok(to_ui) = self.to_ui.try_recv() {
match to_ui {
ToUI::UIReady => {
if let Some(audio_unit) = &self.audio_unit {
audio_unit.open_ui();
}
}
ToUI::NewAudioUnit(audio_unit) => {
self.from_ui.send(FromUI::NewAudioUnit(audio_unit.clone())).unwrap();
self.audio_unit = Some(audio_unit);
}
}
}
}
fn audio_query(&mut self, _query: &AudioQuery, _callback: &mut Option<AudioQueryCb>) -> AudioResult {
AudioResult::not_found()
}
}