เสื้อคลุม Elixir สำหรับห้องสมุด RTMIDI ได้รับแรงบันดาลใจจาก Python-Rtmidi
คำเตือน: ห้องสมุดนี้ถือว่าเป็นการทดลอง/pre-alpha จนกว่าจะมีการแก้ไขปัญหาด้านล่าง
พิจารณาตรวจสอบแท็บ "ปัญหา" หากคุณต้องการความช่วยเหลือ
ห้องสมุดนี้ใช้งานได้ แต่ฉันไม่ใช่โปรแกรมเมอร์ C ++ ยินดีต้อนรับการมีส่วนร่วมใด ๆ แต่ช่วยในพื้นที่เฉพาะเหล่านี้จะไปไกล:
C ++
src/ex_rtmidi_{output,input}.cpp สามารถใช้ OOP และ templating ได้ดีกว่ามากเพื่อลดการทำซ้ำของรหัสinput_callback และ attach_listener ใน src/ex_rtmidi_input.cpp ต้องดูดี อีกครั้ง refactor ล่วงหน้าเป็นที่ต้องการdetach_listener ไม่ควรพิมพ์ข้อผิดพลาดหากเรียกโดยไม่มีผู้ฟังน้ำอมฤต
init สำหรับอินพุต/เอาต์พุตใช้เวลานานกว่าที่แนะนำสำหรับ NIF ดู lib/ex_rtmidi/{output,input}.ex ความคิดเห็นopenVirtualPort ของ RTMIDIMix.Tasks.Compile.Rtmidi ออกจาก mix.exs ดูความคิดเห็นใน mix.exsทั่วไป
C ++ เป็นภาษา OO Elixir ไม่ได้ ฉันถูกฉีกขาดว่าจะแสดงสิ่งต่าง ๆ ที่ใช้งานได้มากขึ้นหรือสอดคล้องกับการประชุม OO ในที่สุดก็เลือกวิธีการที่ใช้งานได้มากขึ้น
ในการสร้างอินสแตนซ์ RTMIDI วิธีการ init จะถูกเรียกด้วยตัวระบุอินสแตนซ์ ใน C ++ อินสแตนซ์จะถูกเก็บไว้เป็นค่าในแผนที่ที่ตัวระบุคือคีย์ การโทรไปยังวิธีการอินสแตนซ์ RTMIDI ในอนาคตจำเป็นต้องส่งตัวระบุเพื่อให้ทราบว่าอินสแตนซ์ใดที่จะกำหนดเป้าหมาย
NIFs เป็นโครงสร้างของ Erlang เป็นหลักดังนั้นคุณจะเห็นว่าเสื้อคลุม Elixir ทำการแปลงเป็นจำนวนมากไปและกลับจาก Charlists นี่เป็นเพราะสตริงใน Erlang เป็น Charlists ใน Elixir ดังนั้นวิธีการสตริง NIF ใช้เวลาจริงและส่งคืน Charlists แทน String.t()
ผู้ฟังในพอร์ตอินพุตที่ส่งไปยัง C ++ เป็น PID เมื่อได้รับข้อความ NIF จะแยกวิเคราะห์และส่งผ่านข้อความขึ้นไปยัง PID ที่ระบุ
จนกว่าปัญหา C ++ ที่เร่งด่วนจะได้รับการแก้ไขฉันไม่ต้องการโปรโมตห้องสมุดนี้เพื่อการใช้งานสาธารณะ ก่อนหน้านั้นคุณจะต้องได้รับจาก GitHub:
def deps do
[
{ :ex_rtmidi , git: "https://github.com/kieraneglin/ex_rtmidi" }
]
end ปัจจุบันห้องสมุดนี้ใช้แนวทางการจัดการข้อความที่เปลือยเปล่ามากกว่าที่คุณคาดไว้ คุณอาจได้รับคุณค่าจากเสื้อคลุมขนาดเล็กรอบ ๆ การส่งและการแยกวิเคราะห์ข้อความที่เหมาะกับกรณีการใช้งานของคุณ
ฉันได้ระบุกรณีการใช้งานพื้นฐานบางอย่าง แต่คุณควรเห็น lib/ex_rtmidi/{output,input}.ex สำหรับเอกสารเชิงลึกเพิ่มเติม
alias ExRtmidi.Output
{ :ok , instance } = Output . init ( :my_instance_name ) # Instance name can be whatever you want - it's unrelated to available MIDI devices
Output . get_port_count ( instance )
# iex> {:ok, 2}
Output . get_ports ( instance )
# iex> {:ok, ["IAC Midi", "Dummy MIDI"]}
Output . open_port ( instance , 0 ) # Or `Output.open_port(instance, "IAC Midi")`
# iex> :ok
Output . send_message ( instance , [ 0x90 , 60 , 100 ] )
# iex> :ok
Output . close_port ( instance )
# iex> :okมีเสื้อคลุมสำหรับข้อความ MIDI ที่ปรับปรุงประสบการณ์ในการสร้างข้อความ นี่เป็นส่วนใหญ่สำหรับเอาต์พุตและไม่ได้ถูกส่งไปยัง deconstruct ข้อความที่เข้ามา (ดูส่วน "ความช่วยเหลือที่จำเป็น")
สำหรับรายการข้อความทั้งหมดดู lib/ex_rtmidi/message/spec.ex
alias ExRtmidi.Output
alias ExRtmidi.Message
# Assume `init` has been run and a port has been opened as in the instance above
message = Message . compose ( :note_on , channel: 0 , note: 60 , velocity: 100 )
Output . send_message ( instance , message ) # In midi_input_server.ex
defmodule MidiInputServer do
use GenServer
def init ( state \ [ ] ) do
{ :ok , state }
end
def handle_info ( { :midi_input , midi_message } , state ) do
IO . inspect ( midi_message )
{ :noreply , state }
end
end
# In another file
alias ExRtmidi.Input
# Much of setup including init, listing ports, and opening a port is the same as in the Output example above.
# Setup will be omitted for brevity. Assume we have an instance at our disposal.
{ :ok , midi_listener_pid } = GenServer . start_link ( MidiInputServer , [ ] )
# You should attach the listener before opening the port to ensure no messages get missed
Input . attach_listener ( instance , midi_listener_pid )
# iex> :ok
Input . open_port ( instance )
# iex> :ok
# Messages will be handled from this point on
# When you're done, be sure to detatch the listener before closing the port
Input . detatch_listener ( instance )
# iex> :ok
Input . close_port ( instance )
# iex> :ok ลิขสิทธิ์ 2021
ได้รับอนุญาตโดยไม่ต้องเสียค่าใช้จ่ายสำหรับบุคคลใด ๆ ที่ได้รับสำเนาซอฟต์แวร์นี้และไฟล์เอกสารที่เกี่ยวข้อง ("ซอฟต์แวร์") เพื่อจัดการในซอฟต์แวร์โดยไม่มีการ จำกัด รวมถึง แต่ไม่ จำกัด เฉพาะสิทธิ์ในการใช้สำเนาดัดแปลงผสานเผยแพร่เผยแพร่
ประกาศลิขสิทธิ์ข้างต้นและประกาศการอนุญาตนี้จะรวมอยู่ในสำเนาทั้งหมดหรือส่วนสำคัญของซอฟต์แวร์
ซอฟต์แวร์มีให้ "ตามสภาพ" โดยไม่มีการรับประกันใด ๆ ไม่ว่าโดยชัดแจ้งหรือโดยนัยรวมถึง แต่ไม่ จำกัด เฉพาะการรับประกันความสามารถในการค้าการออกกำลังกายสำหรับวัตถุประสงค์เฉพาะและการไม่เข้าร่วม ไม่ว่าในกรณีใดผู้เขียนหรือผู้ถือลิขสิทธิ์จะต้องรับผิดชอบต่อการเรียกร้องความเสียหายหรือความรับผิดอื่น ๆ ไม่ว่าจะเป็นการกระทำของสัญญาการละเมิดหรืออื่น ๆ ที่เกิดขึ้นจากหรือเกี่ยวข้องกับซอฟต์แวร์หรือการใช้งานหรือการติดต่ออื่น ๆ ในซอฟต์แวร์