1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_MEDIA_MIDI_H_
18#define ANDROID_MEDIA_MIDI_H_
19
20#include <stdarg.h>
21#include <stdint.h>
22#include <sys/types.h>
23
24#include <utils/Errors.h>
25
26using android::status_t;
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
32struct AMIDI_Device;
33struct AMIDI_InputPort;
34struct AMIDI_OutputPort;
35
36#define AMIDI_INVALID_HANDLE NULL
37
38enum {
39    AMIDI_OPCODE_DATA = 1,
40    AMIDI_OPCODE_FLUSH = 2,
41    AMIDI_PACKET_SIZE = 1024,  /* !!! Currently MidiPortImpl.MAX_PACKET_SIZE !!! */
42    AMIDI_PACKET_OVERHEAD = 9,
43    AMIDI_BUFFER_SIZE = AMIDI_PACKET_SIZE - AMIDI_PACKET_OVERHEAD
44            /* !!! TBD, currently MidiPortImpl.MAX_PACKET_DATA_SIZE !!! */
45};
46
47typedef struct {
48    uint32_t    opcode;
49    uint8_t     buffer[AMIDI_BUFFER_SIZE];
50    size_t      len;
51    int64_t     timestamp;
52} AMIDI_Message;
53
54enum {
55    AMIDI_DEVICE_TYPE_USB = 1,
56    AMIDI_DEVICE_TYPE_VIRTUAL = 2,
57    AMIDI_DEVICE_TYPE_BLUETOOTH = 3
58};
59
60typedef struct {
61    int32_t type;
62    int32_t uid;
63    int32_t isPrivate;
64    int32_t inputPortCount;
65    int32_t outputPortCount;
66} AMIDI_DeviceInfo;
67
68/*
69 * Device API
70 */
71/*
72 * Retrieves information for the native MIDI device.
73 *
74 * device           The Native API token for the device.
75 * deviceInfoPtr    Receives the associated device info.
76 *
77 * Returns OK or a (negative) error code.
78 */
79status_t AMIDI_getDeviceInfo(AMIDI_Device *device, AMIDI_DeviceInfo *deviceInfoPtr);
80
81/*
82 * API for receiving data from the Output port of a device.
83 */
84/*
85 * Opens the output port.
86 *
87 * device           Identifies the device.
88 * portNumber       Specifies the zero-based port index on the device to open.
89 * outputPortPtr    Receives the native API port identifier of the opened port.
90 *
91 * Returns OK, or a (negative) error code.
92 */
93status_t AMIDI_openOutputPort(AMIDI_Device *device, int portNumber,
94        AMIDI_OutputPort **outputPortPtr);
95
96/*
97 * Receives any pending MIDI messages (up to the specified maximum number of messages).
98 *
99 * outputPort   Identifies the port to receive messages from.
100 * messages     Points to an array (size maxMessages) to receive the MIDI messages.
101 * maxMessages  The number of messages allocated in the messages array.
102 *
103 * Returns the number of messages received, or a (negative) error code.
104 */
105ssize_t AMIDI_receive(AMIDI_OutputPort *outputPort, AMIDI_Message *messages, ssize_t maxMessages);
106
107/*
108 * Closes the output port.
109 *
110 * outputPort   The native API port identifier of the port.
111 *
112 * Returns OK, or a (negative) error code.
113 */
114status_t AMIDI_closeOutputPort(AMIDI_OutputPort *outputPort);
115
116/*
117 * API for sending data to the Input port of a device.
118 */
119/*
120 * Opens the input port.
121 *
122 * device           Identifies the device.
123 * portNumber       Specifies the zero-based port index on the device to open.
124 * inputPortPtr     Receives the native API port identifier of the opened port.
125 *
126 * Returns OK, or a (negative) error code.
127 */
128status_t AMIDI_openInputPort(AMIDI_Device *device, int portNumber, AMIDI_InputPort **inputPortPtr);
129
130/*
131 * Returns the maximum number of bytes that can be received in a single MIDI message.
132 */
133ssize_t AMIDI_getMaxMessageSizeInBytes(AMIDI_InputPort *inputPort);
134
135/*
136 * Sends data to the specified input port.
137 *
138 * inputPort    The native API identifier of the port to send data to.
139 * buffer       Points to the array of bytes containing the data to send.
140 * numBytes     Specifies the number of bytes to write.
141 *
142 * Returns  The number of bytes sent or a (negative) error code.
143 */
144ssize_t AMIDI_send(AMIDI_InputPort *inputPort, uint8_t *buffer, ssize_t numBytes);
145
146/*
147 * Sends data to the specified input port with a timestamp.
148 *
149 * inputPort    The native API identifier of the port to send data to.
150 * buffer       Points to the array of bytes containing the data to send.
151 * numBytes     Specifies the number of bytes to write.
152 * timestamp    The time stamp to associate with the sent data.
153 *
154 * Returns  The number of bytes sent or a (negative) error code.
155 */
156ssize_t AMIDI_sendWithTimestamp(AMIDI_InputPort *inputPort, uint8_t *buffer,
157        ssize_t numBytes, int64_t timestamp);
158
159/*
160 * Sends a message with a 'MIDI flush command code' to the specified port.
161 *
162 * inputPort    The native API identifier of the port to send the flush message to.
163 *
164 * Returns OK, or a (negative) error code.
165 */
166status_t AMIDI_flush(AMIDI_InputPort *inputPort);
167
168/*
169 * Closes the input port.
170 *
171 * inputPort   The native API port identifier of the port.
172 *
173 *
174 * Returns OK, or a (negative) error code.
175 */
176status_t AMIDI_closeInputPort(AMIDI_InputPort *inputPort);
177
178#ifdef __cplusplus
179}
180#endif
181
182#endif /* ANDROID_MEDIA_MIDI_H_ */
183