midi-communications-macos 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.version +6 -0
  3. data/.yardoc/checksums +9 -0
  4. data/.yardoc/complete +0 -0
  5. data/.yardoc/object_types +0 -0
  6. data/.yardoc/objects/root.dat +0 -0
  7. data/.yardoc/proxy_types +0 -0
  8. data/.yardopts +6 -0
  9. data/LICENSE +159 -668
  10. data/README.md +6 -13
  11. data/doc/MIDICommunicationsMacOS/API/CF.html +124 -0
  12. data/doc/MIDICommunicationsMacOS/API/HostTime.html +124 -0
  13. data/doc/MIDICommunicationsMacOS/API/MIDIPacket.html +137 -0
  14. data/doc/MIDICommunicationsMacOS/API/MIDIPacketList.html +137 -0
  15. data/doc/MIDICommunicationsMacOS/API/MIDISysexSendRequest.html +137 -0
  16. data/doc/MIDICommunicationsMacOS/API.html +912 -0
  17. data/doc/MIDICommunicationsMacOS/Destination.html +1983 -0
  18. data/doc/MIDICommunicationsMacOS/Device.html +1102 -0
  19. data/doc/MIDICommunicationsMacOS/Endpoint.html +1665 -0
  20. data/doc/MIDICommunicationsMacOS/Entity.html +971 -0
  21. data/doc/MIDICommunicationsMacOS/Source.html +1784 -0
  22. data/doc/MIDICommunicationsMacOS/TypeConversion.html +393 -0
  23. data/doc/MIDICommunicationsMacOS.html +214 -0
  24. data/doc/_index.html +250 -0
  25. data/doc/class_list.html +54 -0
  26. data/doc/css/common.css +1 -0
  27. data/doc/css/full_list.css +58 -0
  28. data/doc/css/style.css +503 -0
  29. data/doc/file.README.html +275 -0
  30. data/doc/file_list.html +59 -0
  31. data/doc/frames.html +22 -0
  32. data/doc/index.html +275 -0
  33. data/doc/js/app.js +344 -0
  34. data/doc/js/full_list.js +242 -0
  35. data/doc/js/jquery.js +4 -0
  36. data/doc/method_list.html +542 -0
  37. data/doc/top-level-namespace.html +110 -0
  38. data/lib/midi-communications-macos/api.rb +7 -1
  39. data/lib/midi-communications-macos/destination.rb +86 -20
  40. data/lib/midi-communications-macos/device.rb +52 -18
  41. data/lib/midi-communications-macos/endpoint.rb +31 -5
  42. data/lib/midi-communications-macos/entity.rb +20 -6
  43. data/lib/midi-communications-macos/source.rb +79 -19
  44. data/lib/midi-communications-macos/type_conversion.rb +11 -4
  45. data/lib/midi-communications-macos/version.rb +2 -1
  46. data/lib/midi-communications-macos.rb +37 -0
  47. data/midi-communications-macos.gemspec +11 -9
  48. metadata +83 -4
@@ -1,12 +1,33 @@
1
1
  module MIDICommunicationsMacOS
2
- # Type of endpoint used for output
2
+ # MIDI output endpoint for sending MIDI messages.
3
+ #
4
+ # A Destination represents a MIDI output that can send messages to
5
+ # external MIDI devices or software. Messages can be sent as numeric
6
+ # bytes, hex strings, or arrays.
7
+ #
8
+ # @example Send a Note On/Off sequence
9
+ # output = MIDICommunicationsMacOS::Destination.first
10
+ # output.open
11
+ # output.puts(0x90, 60, 100) # Note On, middle C, velocity 100
12
+ # sleep(0.5)
13
+ # output.puts(0x80, 60, 0) # Note Off
14
+ #
15
+ # @example Send as hex string
16
+ # output.puts_s("903C64") # Note On
17
+ # output.puts_s("803C00") # Note Off
18
+ #
19
+ # @see Source For receiving MIDI messages
20
+ # @see Endpoint For shared endpoint functionality
21
+ #
22
+ # @api public
3
23
  class Destination
4
24
  include Endpoint
5
25
 
6
26
  attr_reader :entity
7
27
 
8
- # Close this output
9
- # @return [Boolean]
28
+ # Closes this output.
29
+ #
30
+ # @return [Boolean] true if closed, false if already closed
10
31
  def close
11
32
  if @enabled
12
33
  @enabled = false
@@ -16,9 +37,14 @@ module MIDICommunicationsMacOS
16
37
  end
17
38
  end
18
39
 
19
- # Send a MIDI message comprised of a String of hex digits
20
- # @param [String] data A string of hex digits eg "904040"
21
- # @return [Boolean]
40
+ # Sends a MIDI message as a hex string.
41
+ #
42
+ # @param data [String] hex string (e.g., "904040" for Note On)
43
+ # @return [Boolean] true on success
44
+ #
45
+ # @example
46
+ # output.puts_s("904060") # Note On
47
+ # output.puts_s("804060") # Note Off
22
48
  def puts_s(data)
23
49
  data = data.dup
24
50
  bytes = []
@@ -31,9 +57,13 @@ module MIDICommunicationsMacOS
31
57
  alias puts_bytestr puts_s
32
58
  alias puts_hex puts_s
33
59
 
34
- # Send a MIDI message comprised of numeric bytes
35
- # @param [*Integer] data Numeric bytes eg 0x90, 0x40, 0x40
36
- # @return [Boolean]
60
+ # Sends a MIDI message as numeric bytes.
61
+ #
62
+ # @param data [Integer] numeric bytes (e.g., 0x90, 0x40, 0x40)
63
+ # @return [Boolean] true on success
64
+ #
65
+ # @example
66
+ # output.puts_bytes(0x90, 0x40, 0x40) # Note On
37
67
  def puts_bytes(*data)
38
68
  type = sysex?(data) ? :sysex : :small
39
69
  bytes = API.get_midi_packet(data)
@@ -41,9 +71,24 @@ module MIDICommunicationsMacOS
41
71
  true
42
72
  end
43
73
 
44
- # Send a MIDI message of indeterminate type
45
- # @param [*Array<Integer>, *Array<String>, *Integer, *String] args
46
- # @return [Boolean]
74
+ # Sends a MIDI message in any supported format.
75
+ #
76
+ # Accepts multiple formats:
77
+ # - Numeric bytes: `puts(0x90, 0x40, 0x40)`
78
+ # - Array of bytes: `puts([0x90, 0x40, 0x40])`
79
+ # - Hex string: `puts("904040")`
80
+ #
81
+ # @param args [Array<Integer>, Array<String>, Integer, String] MIDI data
82
+ # @return [Boolean] true on success
83
+ #
84
+ # @example Send as bytes
85
+ # output.puts(0x90, 60, 100)
86
+ #
87
+ # @example Send as array
88
+ # output.puts([0x90, 60, 100])
89
+ #
90
+ # @example Send as hex string
91
+ # output.puts("903C64")
47
92
  def puts(*args)
48
93
  case args.first
49
94
  when Array then args.each { |arg| puts(*arg) }
@@ -53,8 +98,19 @@ module MIDICommunicationsMacOS
53
98
  end
54
99
  alias write puts
55
100
 
56
- # Enable this device
57
- # @return [Destination]
101
+ # Opens this output for use.
102
+ #
103
+ # When a block is given, the output is automatically closed when
104
+ # the block exits.
105
+ #
106
+ # @yield [destination] optional block to execute with the open output
107
+ # @yieldparam destination [Destination] self
108
+ # @return [Destination] self
109
+ #
110
+ # @example Open with automatic close
111
+ # output.open do |o|
112
+ # o.puts(0x90, 60, 100)
113
+ # end
58
114
  def enable
59
115
  @enabled ||= true
60
116
  if block_given?
@@ -69,20 +125,30 @@ module MIDICommunicationsMacOS
69
125
  alias open enable
70
126
  alias start enable
71
127
 
72
- # Shortcut to the first output endpoint available
73
- # @return [Destination]
128
+ # Returns the first available output endpoint.
129
+ #
130
+ # @return [Destination] the first destination
131
+ #
132
+ # @example
133
+ # output = MIDICommunicationsMacOS::Destination.first
74
134
  def self.first
75
135
  Endpoint.first(:destination)
76
136
  end
77
137
 
78
- # Shortcut to the last output endpoint available
79
- # @return [Destination]
138
+ # Returns the last available output endpoint.
139
+ #
140
+ # @return [Destination] the last destination
80
141
  def self.last
81
142
  Endpoint.last(:destination)
82
143
  end
83
144
 
84
- # All output endpoints
85
- # @return [Array<Destination>]
145
+ # Returns all available output endpoints.
146
+ #
147
+ # @return [Array<Destination>] all destinations
148
+ #
149
+ # @example
150
+ # outputs = MIDICommunicationsMacOS::Destination.all
151
+ # outputs.each { |o| puts o.display_name }
86
152
  def self.all
87
153
  Endpoint.all_by_type[:destination]
88
154
  end
@@ -1,17 +1,38 @@
1
1
  module MIDICommunicationsMacOS
2
- # A MIDI device may have multiple logically distinct sub-components. For example, one device may
3
- # encompass a MIDI synthesizer and a pair of MIDI ports, both addressable via a USB port. Each
4
- # such element of a device is called a MIDI entity.
2
+ # Represents a physical or virtual MIDI device.
5
3
  #
6
- # https://developer.apple.com/library/ios/documentation/CoreMidi/Reference/MIDIServices_Reference/Reference/reference.html
4
+ # A MIDI device may have multiple logically distinct sub-components. For example,
5
+ # one device may encompass a MIDI synthesizer and a pair of MIDI ports, both
6
+ # addressable via a USB port. Each such element of a device is called an {Entity}.
7
+ #
8
+ # Devices contain {Entity entities}, which in turn contain {Endpoint endpoints}
9
+ # ({Source sources} and {Destination destinations}).
10
+ #
11
+ # @example List all devices
12
+ # MIDICommunicationsMacOS::Device.all.each do |device|
13
+ # puts device.name
14
+ # end
15
+ #
16
+ # @see https://developer.apple.com/documentation/coremidi/midideviceref
17
+ #
18
+ # @api public
7
19
  class Device
20
+ # @!attribute [r] entities
21
+ # @return [Array<Entity>] the device's entities
22
+ # @!attribute [r] id
23
+ # @return [Integer] unique numeric ID
24
+ # @!attribute [r] name
25
+ # @return [String] device name from Core MIDI
8
26
  attr_reader :entities,
9
- :id, # Unique Numeric id
10
- :name # Device name from midi-communications-macos
27
+ :id,
28
+ :name
11
29
 
12
- # @param [Integer] id The ID for the device
13
- # @param [Object] device_pointer The underlying device pointer
14
- # @param [Boolean] include_offline Whether to include offline entities (default: false)
30
+ # Creates a new Device wrapper.
31
+ #
32
+ # @param id [Integer] the device ID
33
+ # @param device_pointer [FFI::Pointer] pointer to the Core MIDI device
34
+ # @param include_offline [Boolean] whether to include offline entities
35
+ # @api private
15
36
  def initialize(id, device_pointer, include_offline: false)
16
37
  @id = id
17
38
  @resource = device_pointer
@@ -19,8 +40,9 @@ module MIDICommunicationsMacOS
19
40
  populate(include_offline: include_offline)
20
41
  end
21
42
 
22
- # Endpoints for this device
23
- # @return [Array<Endpoint>]
43
+ # Returns all endpoints for this device, grouped by type.
44
+ #
45
+ # @return [Hash{Symbol => Array<Endpoint>}] hash with :source and :destination keys
24
46
  def endpoints
25
47
  endpoints = { source: [], destination: [] }
26
48
  endpoints.each_key do |key|
@@ -39,11 +61,19 @@ module MIDICommunicationsMacOS
39
61
  id
40
62
  end
41
63
 
42
- # All cached devices
43
- # @param [Hash] options The options to select devices with
44
- # @option options [Boolean] :cache If false, the device list will never be cached. This would be useful if one needs to alter the device list (e.g. plug in a USB MIDI interface) while their program is running.
45
- # @option options [Boolean] :include_offline If true, devices marked offline by midi-communications-macos will be included in the list
46
- # @return [Array<Device>] All cached devices
64
+ # Returns all available MIDI devices.
65
+ #
66
+ # Devices are cached by default. Use `cache: false` to refresh, or call
67
+ # {.refresh} to clear the cache.
68
+ #
69
+ # @param options [Hash] options for device selection
70
+ # @option options [Boolean] :cache (true) whether to use cached devices
71
+ # @option options [Boolean] :include_offline (false) include offline devices
72
+ # @return [Array<Device>] all available devices
73
+ #
74
+ # @example
75
+ # devices = MIDICommunicationsMacOS::Device.all
76
+ # devices.each { |d| puts d.name }
47
77
  def self.all(options = {})
48
78
  use_cache = options[:cache] || true
49
79
  include_offline = options[:include_offline] || false
@@ -60,8 +90,12 @@ module MIDICommunicationsMacOS
60
90
  @devices
61
91
  end
62
92
 
63
- # Refresh the Device cache. This is needed if, for example a USB MIDI device is plugged in while the program is running
64
- # @return [Array<Device>] The Device cache
93
+ # Clears the device cache.
94
+ #
95
+ # Call this when MIDI devices are plugged in or unplugged while the
96
+ # program is running, then call {.all} to get the updated list.
97
+ #
98
+ # @return [Array<Device>] the cleared cache (empty array)
65
99
  def self.refresh
66
100
  @devices.clear
67
101
  @devices
@@ -1,18 +1,44 @@
1
1
  module MIDICommunicationsMacOS
2
- # A source or destination of a 16-channel MIDI stream
2
+ # A source or destination of a 16-channel MIDI stream.
3
3
  #
4
- # https://developer.apple.com/library/ios/documentation/CoreMidi/Reference/MIDIServices_Reference/Reference/reference.html
4
+ # This module provides shared functionality for both {Source} (input) and
5
+ # {Destination} (output) endpoints. Each endpoint represents a single
6
+ # point of MIDI communication within an {Entity}.
7
+ #
8
+ # @see https://developer.apple.com/documentation/coremidi/midiendpointref
9
+ #
10
+ # @api public
5
11
  module Endpoint
6
12
  extend Forwardable
7
13
 
8
- attr_reader :enabled, # has the endpoint been initialized?
14
+ # @!attribute [r] enabled
15
+ # @return [Boolean] whether the endpoint has been initialized
16
+ # @!attribute [r] entity
17
+ # @return [Entity] the parent entity
18
+ # @!attribute [r] id
19
+ # @return [Integer] unique local numeric ID of the endpoint
20
+ # @!attribute [r] resource_id
21
+ # @return [Integer] Core MIDI resource identifier
22
+ # @!attribute [r] type
23
+ # @return [Symbol] endpoint type (:source or :destination)
24
+ attr_reader :enabled,
9
25
  :entity,
10
- :id, # unique local Numeric id of the endpoint
11
- :resource_id, # :input or :output
26
+ :id,
27
+ :resource_id,
12
28
  :type
13
29
 
30
+ # @!method manufacturer
31
+ # @return [String] device manufacturer name (delegated to entity)
32
+ # @!method model
33
+ # @return [String] device model name (delegated to entity)
34
+ # @!method name
35
+ # @return [String] endpoint name (delegated to entity)
36
+ # @!method display_name
37
+ # @return [String] formatted display name (delegated to entity)
14
38
  def_delegators :entity, :manufacturer, :model, :name, :display_name
15
39
 
40
+ # @!method enabled?
41
+ # @return [Boolean] alias for {#enabled}
16
42
  alias enabled? enabled
17
43
 
18
44
  # @param [Integer] resource_id
@@ -1,12 +1,26 @@
1
1
  module MIDICommunicationsMacOS
2
- # A MIDI entity can have any number of MIDI endpoints, each of which is a source or destination
3
- # of a 16-channel MIDI stream. By grouping a device's endpoints into entities, the system has
4
- # enough information for an application to make reasonable default assumptions about how to
5
- # communicate in a bi-directional manner with each entity, as is necessary in MIDI librarian
6
- # applications.
2
+ # A logical grouping of MIDI endpoints within a device.
7
3
  #
8
- # https://developer.apple.com/library/ios/documentation/CoreMidi/Reference/MIDIServices_Reference/Reference/reference.html
4
+ # A MIDI entity can have any number of MIDI endpoints, each of which is a
5
+ # {Source source} or {Destination destination} of a 16-channel MIDI stream.
6
+ # By grouping a device's endpoints into entities, the system has enough
7
+ # information for applications to make reasonable default assumptions about
8
+ # bidirectional communication.
9
+ #
10
+ # @see https://developer.apple.com/documentation/coremidi/midientityref
11
+ #
12
+ # @api public
9
13
  class Entity
14
+ # @!attribute [r] endpoints
15
+ # @return [Hash{Symbol => Array<Endpoint>}] endpoints grouped by :source and :destination
16
+ # @!attribute [r] manufacturer
17
+ # @return [String] device manufacturer name
18
+ # @!attribute [r] model
19
+ # @return [String] device model name
20
+ # @!attribute [r] name
21
+ # @return [String] entity name
22
+ # @!attribute [r] resource
23
+ # @return [FFI::Pointer] pointer to the Core MIDI entity
10
24
  attr_reader :endpoints,
11
25
  :manufacturer,
12
26
  :model,
@@ -1,8 +1,40 @@
1
1
  module MIDICommunicationsMacOS
2
- # Type of endpoint used for input
2
+ # MIDI input endpoint for receiving MIDI messages.
3
+ #
4
+ # A Source represents a MIDI input that can receive messages from
5
+ # external MIDI devices or software. Messages are queued and can
6
+ # be retrieved using {#gets} or {#gets_s}.
7
+ #
8
+ # @example Open and read from the first input
9
+ # input = MIDICommunicationsMacOS::Source.first
10
+ # input.open
11
+ # messages = input.gets
12
+ # # => [{ data: [144, 60, 100], timestamp: 1234567890.123 }]
13
+ #
14
+ # @example Read messages as hex strings
15
+ # messages = input.gets_s
16
+ # # => [{ data: "903C64", timestamp: 1234567890.123 }]
17
+ #
18
+ # @see Destination For sending MIDI messages
19
+ # @see Endpoint For shared endpoint functionality
20
+ #
21
+ # @api public
3
22
  class Source
4
23
  include Endpoint
5
24
 
25
+ # Reads MIDI messages from the input buffer.
26
+ #
27
+ # Returns an array of MIDI event hashes. Each hash contains:
28
+ # - `:data` - Array of numeric bytes (e.g., [144, 60, 100])
29
+ # - `:timestamp` - Float timestamp when the message was received
30
+ #
31
+ # This method blocks until at least one message is available.
32
+ #
33
+ # @return [Array<Hash>] array of MIDI event hashes
34
+ #
35
+ # @example
36
+ # messages = input.gets
37
+ # # => [{ data: [144, 60, 100], timestamp: 1024.5 }]
6
38
  #
7
39
  # An array of MIDI event hashes as such:
8
40
  # [
@@ -20,15 +52,17 @@ module MIDICommunicationsMacOS
20
52
  end
21
53
  alias read gets
22
54
 
23
- # Same as Source#gets except that it returns message data as string of hex
24
- # digits as such:
25
- # [
26
- # { data: "904060", timestamp: 904 },
27
- # { data: "804060", timestamp: 1150 },
28
- # { data: "90447F", timestamp: 1300 }
29
- # ]
55
+ # Reads MIDI messages as hex strings.
30
56
  #
31
- # @return [Array<Hash>]
57
+ # Same as {#gets} but returns message data as hex strings instead
58
+ # of byte arrays.
59
+ #
60
+ # @return [Array<Hash>] array of MIDI event hashes with hex string data
61
+ #
62
+ # @example
63
+ # messages = input.gets_s
64
+ # # => [{ data: "904060", timestamp: 904 },
65
+ # # { data: "804060", timestamp: 1150 }]
32
66
  def gets_s
33
67
  messages = gets
34
68
  messages.each do |message|
@@ -38,8 +72,23 @@ module MIDICommunicationsMacOS
38
72
  end
39
73
  alias gets_bytestr gets_s
40
74
 
41
- # Enable this the input for use; can be passed a block
42
- # @return [Source]
75
+ # Opens this input for use.
76
+ #
77
+ # When a block is given, the input is automatically closed when
78
+ # the block exits.
79
+ #
80
+ # @yield [source] optional block to execute with the open input
81
+ # @yieldparam source [Source] self
82
+ # @return [Source] self
83
+ #
84
+ # @example Open with automatic close
85
+ # input.open do |i|
86
+ # messages = i.gets
87
+ # end
88
+ #
89
+ # @example Open manually
90
+ # input.open
91
+ # messages = input.gets
43
92
  def enable
44
93
  @enabled ||= true
45
94
  if block_given?
@@ -54,8 +103,9 @@ module MIDICommunicationsMacOS
54
103
  alias open enable
55
104
  alias start enable
56
105
 
57
- # Close this input
58
- # @return [Boolean]
106
+ # Closes this input.
107
+ #
108
+ # @return [Boolean] true if closed, false if already closed
59
109
  def close
60
110
  #error = API.MIDIPortDisconnectSource( @handle, @resource )
61
111
  #raise "MIDIPortDisconnectSource returned error code #{error}" unless error.zero?
@@ -73,20 +123,30 @@ module MIDICommunicationsMacOS
73
123
  end
74
124
  end
75
125
 
76
- # Shortcut to the first available input endpoint
77
- # @return [Source]
126
+ # Returns the first available input endpoint.
127
+ #
128
+ # @return [Source] the first source
129
+ #
130
+ # @example
131
+ # input = MIDICommunicationsMacOS::Source.first
78
132
  def self.first
79
133
  Endpoint.first(:source)
80
134
  end
81
135
 
82
- # Shortcut to the last available input endpoint
83
- # @return [Source]
136
+ # Returns the last available input endpoint.
137
+ #
138
+ # @return [Source] the last source
84
139
  def self.last
85
140
  Endpoint.last(:source)
86
141
  end
87
142
 
88
- # All input endpoints
89
- # @return [Array<Source>]
143
+ # Returns all available input endpoints.
144
+ #
145
+ # @return [Array<Source>] all sources
146
+ #
147
+ # @example
148
+ # inputs = MIDICommunicationsMacOS::Source.all
149
+ # inputs.each { |i| puts i.display_name }
90
150
  def self.all
91
151
  Endpoint.all_by_type[:source]
92
152
  end
@@ -1,11 +1,18 @@
1
1
  module MIDICommunicationsMacOS
2
- # Helper for convertig MIDI data
2
+ # Utility methods for converting between MIDI data formats.
3
+ #
4
+ # @api public
3
5
  module TypeConversion
4
6
  extend self
5
7
 
6
- # Convert an array of numeric byes to a hex string (e.g. [0x90, 0x40, 0x40] becomes "904040")
7
- # @param [Array<Integer>] bytes
8
- # @return [String]
8
+ # Converts an array of numeric bytes to a hex string.
9
+ #
10
+ # @param bytes [Array<Integer>] array of numeric bytes (e.g., [0x90, 0x40, 0x40])
11
+ # @return [String] uppercase hex string (e.g., "904040")
12
+ #
13
+ # @example
14
+ # TypeConversion.numeric_bytes_to_hex_string([0x90, 0x40, 0x40])
15
+ # # => "904040"
9
16
  def numeric_bytes_to_hex_string(bytes)
10
17
  string_bytes = bytes.map do |byte|
11
18
  str = byte.to_s(16).upcase
@@ -1,3 +1,4 @@
1
1
  module MIDICommunicationsMacOS
2
- VERSION = '0.6.1'.freeze
2
+ # Current version of the midi-communications-macos gem.
3
+ VERSION = '0.7.0'.freeze
3
4
  end
@@ -23,5 +23,42 @@ require 'midi-communications-macos/destination'
23
23
 
24
24
  require_relative 'midi-communications-macos/version'
25
25
 
26
+ # macOS-specific MIDI I/O using the Core MIDI framework.
27
+ #
28
+ # This library provides low-level access to MIDI devices on macOS through
29
+ # Apple's Core MIDI framework via FFI bindings. It is typically used through
30
+ # the higher-level {https://github.com/javier-sy/midi-communications midi-communications} gem.
31
+ #
32
+ # The main classes are:
33
+ # - {Source} - MIDI input endpoints for receiving messages
34
+ # - {Destination} - MIDI output endpoints for sending messages
35
+ # - {Device} - Physical or virtual MIDI devices
36
+ # - {Entity} - Logical groupings of endpoints within a device
37
+ #
38
+ # @example List all MIDI sources (inputs)
39
+ # MIDICommunicationsMacOS::Source.all.each do |source|
40
+ # puts "#{source.id}: #{source.display_name}"
41
+ # end
42
+ #
43
+ # @example List all MIDI destinations (outputs)
44
+ # MIDICommunicationsMacOS::Destination.all.each do |dest|
45
+ # puts "#{dest.id}: #{dest.display_name}"
46
+ # end
47
+ #
48
+ # @example Send a MIDI message
49
+ # output = MIDICommunicationsMacOS::Destination.first
50
+ # output.open
51
+ # output.puts(0x90, 60, 100) # Note On
52
+ # output.puts(0x80, 60, 0) # Note Off
53
+ #
54
+ # @example Receive MIDI messages
55
+ # input = MIDICommunicationsMacOS::Source.first
56
+ # input.open
57
+ # messages = input.gets
58
+ # # => [{ data: [144, 60, 100], timestamp: 1234567890.123 }]
59
+ #
60
+ # @see https://developer.apple.com/documentation/coremidi Apple Core MIDI Documentation
61
+ #
62
+ # @api public
26
63
  module MIDICommunicationsMacOS
27
64
  end
@@ -9,24 +9,26 @@ Gem::Specification.new do |s|
9
9
  s.authors = ['Javier Sánchez Yeste']
10
10
  s.email = ['javier.sy@gmail.com']
11
11
  s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
12
- s.homepage = 'https://rubygems.org/gems/midi-communications-macos'
13
- s.license = 'LGPL-3.0'
12
+ s.homepage = 'https://github.com/javier-sy/midi-communications-macos'
13
+ s.license = 'LGPL-3.0-or-later'
14
14
 
15
15
  s.required_ruby_version = '>= 2.7'
16
16
 
17
- # TODO
18
- #s.metadata = {
19
- # "source_code_uri" => "https://",
20
- # "homepage_uri" => "",
21
- # "documentation_uri" => "",
22
- # "changelog_uri" => ""
23
- #}
17
+ s.metadata = {
18
+ 'homepage_uri' => s.homepage,
19
+ 'source_code_uri' => s.homepage,
20
+ 'documentation_uri' => 'https://www.rubydoc.info/gems/midi-communications-macos'
21
+ }
24
22
 
25
23
  s.add_runtime_dependency 'ffi', '~> 1.15', '>= 1.15.4'
26
24
 
27
25
  s.add_development_dependency 'minitest', '~>5', '>= 5.14.4'
28
26
  s.add_development_dependency 'rake', '~>13', '>= 13.0.6'
29
27
  s.add_development_dependency 'shoulda-context', '~>2', '>= 2.0.0'
28
+
29
+ s.add_development_dependency 'yard', '~> 0.9'
30
+ s.add_development_dependency 'redcarpet', '~> 3.6'
31
+ s.add_development_dependency 'webrick', '~> 1.8'
30
32
  end
31
33
 
32
34