Home | History | Annotate | Download | only in midi
      1 /*
      2  * Copyright (C) 2014 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 package android.media.midi;
     18 
     19 /**
     20  * This class contains utilities for socket communication between a
     21  * MidiInputPort and MidiOutputPort
     22  */
     23 /* package */ class MidiPortImpl {
     24     private static final String TAG = "MidiPort";
     25 
     26     /**
     27      * Packet type for data packet
     28      */
     29     public static final int PACKET_TYPE_DATA = 1;
     30 
     31     /**
     32      * Packet type for flush packet
     33      */
     34     public static final int PACKET_TYPE_FLUSH = 2;
     35 
     36     /**
     37      * Maximum size of a packet that can be passed between processes.
     38      */
     39     public static final int MAX_PACKET_SIZE = 1024;
     40 
     41     /**
     42      * size of message timestamp in bytes
     43      */
     44     private static final int TIMESTAMP_SIZE = 8;
     45 
     46     /**
     47      * Data packet overhead is timestamp size plus packet type byte
     48      */
     49     private static final int DATA_PACKET_OVERHEAD = TIMESTAMP_SIZE + 1;
     50 
     51     /**
     52      * Maximum amount of MIDI data that can be included in a packet
     53      */
     54     public static final int MAX_PACKET_DATA_SIZE = MAX_PACKET_SIZE - DATA_PACKET_OVERHEAD;
     55 
     56     /**
     57      * Utility function for packing MIDI data to be passed between processes
     58      *
     59      * message byte array contains variable length MIDI message.
     60      * messageSize is size of variable length MIDI message
     61      * timestamp is message timestamp to pack
     62      * dest is buffer to pack into
     63      * returns size of packed message
     64      */
     65     public static int packData(byte[] message, int offset, int size, long timestamp,
     66             byte[] dest) {
     67         if (size  > MAX_PACKET_DATA_SIZE) {
     68             size = MAX_PACKET_DATA_SIZE;
     69         }
     70         int length = 0;
     71         // packet type goes first
     72         dest[length++] = PACKET_TYPE_DATA;
     73         // data goes next
     74         System.arraycopy(message, offset, dest, length, size);
     75         length += size;
     76 
     77         // followed by timestamp
     78         for (int i = 0; i < TIMESTAMP_SIZE; i++) {
     79             dest[length++] = (byte)timestamp;
     80             timestamp >>= 8;
     81         }
     82 
     83         return length;
     84     }
     85 
     86     /**
     87      * Utility function for packing a flush command to be passed between processes
     88      */
     89     public static int packFlush(byte[] dest) {
     90         dest[0] = PACKET_TYPE_FLUSH;
     91         return 1;
     92     }
     93 
     94     /**
     95      * Returns the packet type (PACKET_TYPE_DATA or PACKET_TYPE_FLUSH)
     96      */
     97     public static int getPacketType(byte[] buffer, int bufferLength) {
     98         return buffer[0];
     99     }
    100 
    101     /**
    102      * Utility function for unpacking MIDI data received from other process
    103      * returns the offset of the MIDI message in packed buffer
    104      */
    105     public static int getDataOffset(byte[] buffer, int bufferLength) {
    106         // data follows packet type byte
    107         return 1;
    108     }
    109 
    110     /**
    111      * Utility function for unpacking MIDI data received from other process
    112      * returns size of MIDI data in packed buffer
    113      */
    114     public static int getDataSize(byte[] buffer, int bufferLength) {
    115         // message length is total buffer length minus size of the timestamp
    116         return bufferLength - DATA_PACKET_OVERHEAD;
    117     }
    118 
    119     /**
    120      * Utility function for unpacking MIDI data received from other process
    121      * unpacks timestamp from packed buffer
    122      */
    123     public static long getPacketTimestamp(byte[] buffer, int bufferLength) {
    124         // timestamp is at end of the packet
    125         int offset = bufferLength;
    126         long timestamp = 0;
    127 
    128         for (int i = 0; i < TIMESTAMP_SIZE; i++) {
    129             int b = (int)buffer[--offset] & 0xFF;
    130             timestamp = (timestamp << 8) | b;
    131         }
    132         return timestamp;
    133     }
    134 }
    135