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, users should 31 * 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. 38 * 39 * @see AudioGroup 40 * @hide 41 */ 42 public class AudioStream extends RtpStream { 43 private AudioCodec mCodec; 44 private int mDtmfType = -1; 45 private AudioGroup mGroup; 46 47 /** 48 * Creates an AudioStream on the given local address. Note that the local 49 * port is assigned automatically to conform with RFC 3550. 50 * 51 * @param address The network address of the local host to bind to. 52 * @throws SocketException if the address cannot be bound or a problem 53 * occurs during binding. 54 */ 55 public AudioStream(InetAddress address) throws SocketException { 56 super(address); 57 } 58 59 /** 60 * Returns {@code true} if the stream has already joined an 61 * {@link AudioGroup}. 62 */ 63 @Override 64 public final boolean isBusy() { 65 return mGroup != null; 66 } 67 68 /** 69 * Returns the joined {@link AudioGroup}. 70 */ 71 public AudioGroup getGroup() { 72 return mGroup; 73 } 74 75 /** 76 * Joins an {@link AudioGroup}. Each stream can join only one group at a 77 * time. The group can be changed by passing a different one or removed 78 * by calling this method with {@code null}. 79 * 80 * @param group The AudioGroup to join or {@code null} to leave. 81 * @throws IllegalStateException if the stream is not properly configured. 82 * @see AudioGroup 83 */ 84 public void join(AudioGroup group) { 85 if (mGroup == group) { 86 return; 87 } 88 if (mGroup != null) { 89 mGroup.remove(this); 90 mGroup = null; 91 } 92 if (group != null) { 93 group.add(this, mCodec, mDtmfType); 94 mGroup = group; 95 } 96 } 97 98 /** 99 * Returns the {@link AudioCodec}, or {@code null} if it is not set. 100 * 101 * @see #setCodec(AudioCodec) 102 */ 103 public AudioCodec getCodec() { 104 return mCodec; 105 } 106 107 /** 108 * Sets the {@link AudioCodec}. 109 * 110 * @param codec The AudioCodec to be used. 111 * @throws IllegalArgumentException if its type is used by DTMF. 112 * @throws IllegalStateException if the stream is busy. 113 */ 114 public void setCodec(AudioCodec codec) { 115 if (isBusy()) { 116 throw new IllegalStateException("Busy"); 117 } 118 if (codec.type == mDtmfType) { 119 throw new IllegalArgumentException("The type is used by DTMF"); 120 } 121 mCodec = codec; 122 } 123 124 /** 125 * Returns the RTP payload type for dual-tone multi-frequency (DTMF) digits, 126 * or {@code -1} if it is not enabled. 127 * 128 * @see #setDtmfType(int) 129 */ 130 public int getDtmfType() { 131 return mDtmfType; 132 } 133 134 /** 135 * Sets the RTP payload type for dual-tone multi-frequency (DTMF) digits. 136 * The primary usage is to send digits to the remote gateway to perform 137 * certain tasks, such as second-stage dialing. According to RFC 2833, the 138 * RTP payload type for DTMF is assigned dynamically, so it must be in the 139 * range of 96 and 127. One can use {@code -1} to disable DTMF and free up 140 * the previous assigned type. This method cannot be called when the stream 141 * already joined an {@link AudioGroup}. 142 * 143 * @param type The RTP payload type to be used or {@code -1} to disable it. 144 * @throws IllegalArgumentException if the type is invalid or used by codec. 145 * @throws IllegalStateException if the stream is busy. 146 * @see AudioGroup#sendDtmf(int) 147 */ 148 public void setDtmfType(int type) { 149 if (isBusy()) { 150 throw new IllegalStateException("Busy"); 151 } 152 if (type != -1) { 153 if (type < 96 || type > 127) { 154 throw new IllegalArgumentException("Invalid type"); 155 } 156 if (type == mCodec.type) { 157 throw new IllegalArgumentException("The type is used by codec"); 158 } 159 } 160 mDtmfType = type; 161 } 162 } 163