1b6b9a91c02b7a44cf56943e5358cee68fa4aece5Mike Lockwood/* 2b6b9a91c02b7a44cf56943e5358cee68fa4aece5Mike Lockwood * Copyright (C) 2014 The Android Open Source Project 3b6b9a91c02b7a44cf56943e5358cee68fa4aece5Mike Lockwood * 4b6b9a91c02b7a44cf56943e5358cee68fa4aece5Mike Lockwood * Licensed under the Apache License, Version 2.0 (the "License"); 5b6b9a91c02b7a44cf56943e5358cee68fa4aece5Mike Lockwood * you may not use this file except in compliance with the License. 6b6b9a91c02b7a44cf56943e5358cee68fa4aece5Mike Lockwood * You may obtain a copy of the License at 7b6b9a91c02b7a44cf56943e5358cee68fa4aece5Mike Lockwood * 8b6b9a91c02b7a44cf56943e5358cee68fa4aece5Mike Lockwood * http://www.apache.org/licenses/LICENSE-2.0 9b6b9a91c02b7a44cf56943e5358cee68fa4aece5Mike Lockwood * 10b6b9a91c02b7a44cf56943e5358cee68fa4aece5Mike Lockwood * Unless required by applicable law or agreed to in writing, software 11b6b9a91c02b7a44cf56943e5358cee68fa4aece5Mike Lockwood * distributed under the License is distributed on an "AS IS" BASIS, 12b6b9a91c02b7a44cf56943e5358cee68fa4aece5Mike Lockwood * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b6b9a91c02b7a44cf56943e5358cee68fa4aece5Mike Lockwood * See the License for the specific language governing permissions and 14b6b9a91c02b7a44cf56943e5358cee68fa4aece5Mike Lockwood * limitations under the License. 15b6b9a91c02b7a44cf56943e5358cee68fa4aece5Mike Lockwood */ 16b6b9a91c02b7a44cf56943e5358cee68fa4aece5Mike Lockwood 17b673770f7172d4fca9bc05de1f36bc53e93eb247Mike Lockwoodpackage android.media.midi; 18b6b9a91c02b7a44cf56943e5358cee68fa4aece5Mike Lockwood 19b6b9a91c02b7a44cf56943e5358cee68fa4aece5Mike Lockwood/** 2020821ecbe81ba52b260ae232096bc2bfb3e92ad0Mike Lockwood * This class contains utilities for socket communication between a 2120821ecbe81ba52b260ae232096bc2bfb3e92ad0Mike Lockwood * MidiInputPort and MidiOutputPort 22b6b9a91c02b7a44cf56943e5358cee68fa4aece5Mike Lockwood */ 2320821ecbe81ba52b260ae232096bc2bfb3e92ad0Mike Lockwood/* package */ class MidiPortImpl { 2410024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood private static final String TAG = "MidiPort"; 25b6b9a91c02b7a44cf56943e5358cee68fa4aece5Mike Lockwood 2610024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood /** 27b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood * Packet type for data packet 28b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood */ 29b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood public static final int PACKET_TYPE_DATA = 1; 30b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood 31b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood /** 32b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood * Packet type for flush packet 33b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood */ 34b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood public static final int PACKET_TYPE_FLUSH = 2; 35b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood 36b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood /** 37b673770f7172d4fca9bc05de1f36bc53e93eb247Mike Lockwood * Maximum size of a packet that can pass through our ParcelFileDescriptor. 3810024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood */ 39b673770f7172d4fca9bc05de1f36bc53e93eb247Mike Lockwood public static final int MAX_PACKET_SIZE = 1024; 4010024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood 4110024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood /** 42cb096273734d96f4676014fa9030b57ea48b58d8Mike Lockwood * size of message timestamp in bytes 4310024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood */ 44cb096273734d96f4676014fa9030b57ea48b58d8Mike Lockwood private static final int TIMESTAMP_SIZE = 8; 45cb096273734d96f4676014fa9030b57ea48b58d8Mike Lockwood 46cb096273734d96f4676014fa9030b57ea48b58d8Mike Lockwood /** 47b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood * Data packet overhead is timestamp size plus packet type byte 48b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood */ 49b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood private static final int DATA_PACKET_OVERHEAD = TIMESTAMP_SIZE + 1; 50b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood 51b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood /** 52cb096273734d96f4676014fa9030b57ea48b58d8Mike Lockwood * Maximum amount of MIDI data that can be included in a packet 53cb096273734d96f4676014fa9030b57ea48b58d8Mike Lockwood */ 54b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood public static final int MAX_PACKET_DATA_SIZE = MAX_PACKET_SIZE - DATA_PACKET_OVERHEAD; 5510024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood 5610024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood /** 57b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood * Utility function for packing MIDI data to be sent through our ParcelFileDescriptor 5810024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood * 5910024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood * message byte array contains variable length MIDI message. 6010024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood * messageSize is size of variable length MIDI message 6110024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood * timestamp is message timestamp to pack 6210024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood * dest is buffer to pack into 6310024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood * returns size of packed message 6410024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood */ 65b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood public static int packData(byte[] message, int offset, int size, long timestamp, 6610024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood byte[] dest) { 67b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood if (size > MAX_PACKET_DATA_SIZE) { 68b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood size = MAX_PACKET_DATA_SIZE; 69cb096273734d96f4676014fa9030b57ea48b58d8Mike Lockwood } 70b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood int length = 0; 71b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood // packet type goes first 72b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood dest[length++] = PACKET_TYPE_DATA; 73b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood // data goes next 74b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood System.arraycopy(message, offset, dest, length, size); 75b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood length += size; 76cb096273734d96f4676014fa9030b57ea48b58d8Mike Lockwood 77cb096273734d96f4676014fa9030b57ea48b58d8Mike Lockwood // followed by timestamp 78cb096273734d96f4676014fa9030b57ea48b58d8Mike Lockwood for (int i = 0; i < TIMESTAMP_SIZE; i++) { 79b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood dest[length++] = (byte)timestamp; 8010024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood timestamp >>= 8; 8110024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood } 8210024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood 83b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood return length; 84b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood } 85b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood 86b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood /** 87b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood * Utility function for packing a flush command to be sent through our ParcelFileDescriptor 88b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood */ 89b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood public static int packFlush(byte[] dest) { 90b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood dest[0] = PACKET_TYPE_FLUSH; 91b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood return 1; 92b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood } 93b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood 94b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood /** 95b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood * Returns the packet type (PACKET_TYPE_DATA or PACKET_TYPE_FLUSH) 96b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood */ 97b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood public static int getPacketType(byte[] buffer, int bufferLength) { 98b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood return buffer[0]; 9910024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood } 10010024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood 10110024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood /** 102b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood * Utility function for unpacking MIDI data received from our ParcelFileDescriptor 103cb096273734d96f4676014fa9030b57ea48b58d8Mike Lockwood * returns the offset of the MIDI message in packed buffer 10410024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood */ 105b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood public static int getDataOffset(byte[] buffer, int bufferLength) { 106b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood // data follows packet type byte 107b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood return 1; 10810024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood } 10910024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood 11010024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood /** 111b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood * Utility function for unpacking MIDI data received from our ParcelFileDescriptor 112cb096273734d96f4676014fa9030b57ea48b58d8Mike Lockwood * returns size of MIDI data in packed buffer 11310024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood */ 114b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood public static int getDataSize(byte[] buffer, int bufferLength) { 115cb096273734d96f4676014fa9030b57ea48b58d8Mike Lockwood // message length is total buffer length minus size of the timestamp 116b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood return bufferLength - DATA_PACKET_OVERHEAD; 11710024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood } 11810024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood 11910024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood /** 120b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood * Utility function for unpacking MIDI data received from our ParcelFileDescriptor 12110024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood * unpacks timestamp from packed buffer 12210024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood */ 123b6f50d357bd3d4d296be6bb047f5ce93a79cbca1Mike Lockwood public static long getPacketTimestamp(byte[] buffer, int bufferLength) { 124cb096273734d96f4676014fa9030b57ea48b58d8Mike Lockwood // timestamp is at end of the packet 125cb096273734d96f4676014fa9030b57ea48b58d8Mike Lockwood int offset = bufferLength; 12610024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood long timestamp = 0; 12710024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood 128cb096273734d96f4676014fa9030b57ea48b58d8Mike Lockwood for (int i = 0; i < TIMESTAMP_SIZE; i++) { 129cb096273734d96f4676014fa9030b57ea48b58d8Mike Lockwood int b = (int)buffer[--offset] & 0xFF; 13010024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood timestamp = (timestamp << 8) | b; 13110024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood } 13210024b3dc12a8552c1547b67810c77b865045cc8Mike Lockwood return timestamp; 133cb096273734d96f4676014fa9030b57ea48b58d8Mike Lockwood } 134b6b9a91c02b7a44cf56943e5358cee68fa4aece5Mike Lockwood} 135