Home | History | Annotate | Download | only in rtp
      1 /*
      2  * Copyright (C) 2010 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.net.rtp;
     18 
     19 import java.net.InetAddress;
     20 import java.net.SocketException;
     21 
     22 /**
     23  * An AudioStream is a {@link RtpStream} which carrys audio payloads over
     24  * Real-time Transport Protocol (RTP). Two different classes are developed in
     25  * order to support various usages such as audio conferencing. An AudioStream
     26  * represents a remote endpoint which consists of a network mapping and a
     27  * configured {@link AudioCodec}. On the other side, An {@link AudioGroup}
     28  * represents a local endpoint which mixes all the AudioStreams and optionally
     29  * interacts with the speaker and the microphone at the same time. The simplest
     30  * usage includes one for each endpoints. For other combinations, developers
     31  * should be aware of the limitations described in {@link AudioGroup}.
     32  *
     33  * <p>An AudioStream becomes busy when it joins an AudioGroup. In this case most
     34  * of the setter methods are disabled. This is designed to ease the task of
     35  * managing native resources. One can always make an AudioStream leave its
     36  * AudioGroup by calling {@link #join(AudioGroup)} with {@code null} and put it
     37  * back after the modification is done.</p>
     38  *
     39  * <p class="note">Using this class requires
     40  * {@link android.Manifest.permission#INTERNET} permission.</p>
     41  *
     42  * @see RtpStream
     43  * @see AudioGroup
     44  */
     45 public class AudioStream extends RtpStream {
     46     private AudioCodec mCodec;
     47     private int mDtmfType = -1;
     48     private AudioGroup mGroup;
     49 
     50     /**
     51      * Creates an AudioStream on the given local address. Note that the local
     52      * port is assigned automatically to conform with RFC 3550.
     53      *
     54      * @param address The network address of the local host to bind to.
     55      * @throws SocketException if the address cannot be bound or a problem
     56      *     occurs during binding.
     57      */
     58     public AudioStream(InetAddress address) throws SocketException {
     59         super(address);
     60     }
     61 
     62     /**
     63      * Returns {@code true} if the stream has already joined an
     64      * {@link AudioGroup}.
     65      */
     66     @Override
     67     public final boolean isBusy() {
     68         return mGroup != null;
     69     }
     70 
     71     /**
     72      * Returns the joined {@link AudioGroup}.
     73      */
     74     public AudioGroup getGroup() {
     75         return mGroup;
     76     }
     77 
     78     /**
     79      * Joins an {@link AudioGroup}. Each stream can join only one group at a
     80      * time. The group can be changed by passing a different one or removed
     81      * by calling this method with {@code null}.
     82      *
     83      * @param group The AudioGroup to join or {@code null} to leave.
     84      * @throws IllegalStateException if the stream is not properly configured.
     85      * @see AudioGroup
     86      */
     87     public void join(AudioGroup group) {
     88         synchronized (this) {
     89             if (mGroup == group) {
     90                 return;
     91             }
     92             if (mGroup != null) {
     93                 mGroup.remove(this);
     94                 mGroup = null;
     95             }
     96             if (group != null) {
     97                 group.add(this);
     98                 mGroup = group;
     99             }
    100         }
    101     }
    102 
    103     /**
    104      * Returns the {@link AudioCodec}, or {@code null} if it is not set.
    105      *
    106      * @see #setCodec(AudioCodec)
    107      */
    108     public AudioCodec getCodec() {
    109         return mCodec;
    110     }
    111 
    112     /**
    113      * Sets the {@link AudioCodec}.
    114      *
    115      * @param codec The AudioCodec to be used.
    116      * @throws IllegalArgumentException if its type is used by DTMF.
    117      * @throws IllegalStateException if the stream is busy.
    118      */
    119     public void setCodec(AudioCodec codec) {
    120         if (isBusy()) {
    121             throw new IllegalStateException("Busy");
    122         }
    123         if (codec.type == mDtmfType) {
    124             throw new IllegalArgumentException("The type is used by DTMF");
    125         }
    126         mCodec = codec;
    127     }
    128 
    129     /**
    130      * Returns the RTP payload type for dual-tone multi-frequency (DTMF) digits,
    131      * or {@code -1} if it is not enabled.
    132      *
    133      * @see #setDtmfType(int)
    134      */
    135     public int getDtmfType() {
    136         return mDtmfType;
    137     }
    138 
    139     /**
    140      * Sets the RTP payload type for dual-tone multi-frequency (DTMF) digits.
    141      * The primary usage is to send digits to the remote gateway to perform
    142      * certain tasks, such as second-stage dialing. According to RFC 2833, the
    143      * RTP payload type for DTMF is assigned dynamically, so it must be in the
    144      * range of 96 and 127. One can use {@code -1} to disable DTMF and free up
    145      * the previous assigned type. This method cannot be called when the stream
    146      * already joined an {@link AudioGroup}.
    147      *
    148      * @param type The RTP payload type to be used or {@code -1} to disable it.
    149      * @throws IllegalArgumentException if the type is invalid or used by codec.
    150      * @throws IllegalStateException if the stream is busy.
    151      * @see AudioGroup#sendDtmf(int)
    152      */
    153     public void setDtmfType(int type) {
    154         if (isBusy()) {
    155             throw new IllegalStateException("Busy");
    156         }
    157         if (type != -1) {
    158             if (type < 96 || type > 127) {
    159                 throw new IllegalArgumentException("Invalid type");
    160             }
    161             if (mCodec != null && type == mCodec.type) {
    162                 throw new IllegalArgumentException("The type is used by codec");
    163             }
    164         }
    165         mDtmfType = type;
    166     }
    167 }
    168