1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 1992-2001 by Sun Microsystems, Inc. 24 * All rights reserved. 25 */ 26 27 #include <AudioHdr.h> 28 29 // class AudioHdr basic methods 30 31 // This routine uses the byteorder network utilities to tell whether the 32 // current process uses network byte order or not. 33 AudioEndian AudioHdr::localByteOrder() const 34 { 35 short sTestHost; 36 short sTestNetwork; 37 static AudioEndian ae = UNDEFINED_ENDIAN; 38 39 if (ae == UNDEFINED_ENDIAN) { 40 sTestHost = MAXSHORT; 41 sTestNetwork = htons(sTestHost); 42 if (sTestNetwork != sTestHost) { 43 ae = LITTLE_ENDIAN; 44 } else { 45 ae = BIG_ENDIAN; 46 } 47 } 48 return (ae); 49 } 50 51 // Clear a header structure 52 void AudioHdr:: 53 Clear() 54 { 55 sample_rate = 0; 56 samples_per_unit = 0; 57 bytes_per_unit = 0; 58 channels = 0; 59 encoding = NONE; 60 } 61 62 // Return error code (TRUE) if header is inconsistent or unrecognizable 63 // XXX - how do we support extensions? 64 AudioError AudioHdr:: 65 Validate() const 66 { 67 // Check for uninitialized fields 68 if ((bytes_per_unit < 1) || (samples_per_unit < 1) || 69 (sample_rate < 1) || (channels < 1)) 70 return (AUDIO_ERR_BADHDR); 71 72 switch (encoding) { 73 case NONE: 74 return (AUDIO_ERR_BADHDR); 75 76 case LINEAR: 77 if (bytes_per_unit > 4) 78 return (AUDIO_ERR_PRECISION); 79 if (samples_per_unit != 1) 80 return (AUDIO_ERR_HDRINVAL); 81 break; 82 83 case FLOAT: 84 if ((bytes_per_unit != 4) && (bytes_per_unit != 8)) 85 return (AUDIO_ERR_PRECISION); 86 if (samples_per_unit != 1) 87 return (AUDIO_ERR_HDRINVAL); 88 break; 89 90 case ULAW: 91 case ALAW: 92 case G722: 93 if (bytes_per_unit != 1) 94 return (AUDIO_ERR_PRECISION); 95 if (samples_per_unit != 1) 96 return (AUDIO_ERR_HDRINVAL); 97 break; 98 99 case G721: 100 case DVI: 101 // G.721 is a 4-bit encoding 102 if ((bytes_per_unit != 1) || (samples_per_unit != 2)) 103 return (AUDIO_ERR_PRECISION); 104 break; 105 106 case G723: 107 // G.723 has 3-bit and 5-bit flavors 108 // 5-bit is currently unsupported 109 if ((bytes_per_unit != 3) || (samples_per_unit != 8)) 110 return (AUDIO_ERR_PRECISION); 111 break; 112 } 113 return (AUDIO_SUCCESS); 114 } 115 116 117 // Convert a byte count into a floating-point time value, in seconds, 118 // using the encoding specified in the audio header. 119 Double AudioHdr:: 120 Bytes_to_Time( 121 off_t cnt) const // byte count 122 { 123 if ((cnt == AUDIO_UNKNOWN_SIZE) || (Validate() != AUDIO_SUCCESS)) 124 return (AUDIO_UNKNOWN_TIME); 125 126 // round off to nearest sample frame! 127 cnt -= (cnt % (bytes_per_unit * channels)); 128 129 return (Double) ((double)cnt / 130 ((double)(channels * bytes_per_unit * sample_rate) / 131 (double)samples_per_unit)); 132 } 133 134 // Convert a floating-point time value, in seconds, to a byte count for 135 // the audio encoding in the audio header. Make sure that the byte count 136 // or offset does not span a sample frame. 137 off_t AudioHdr:: 138 Time_to_Bytes( 139 Double sec) const // time, in seconds 140 { 141 off_t offset; 142 143 if (Undefined(sec) || (Validate() != AUDIO_SUCCESS)) 144 return (AUDIO_UNKNOWN_SIZE); 145 146 offset = (off_t)(0.5 + (sec * 147 ((double)(channels * bytes_per_unit * sample_rate) / 148 (double)samples_per_unit))); 149 150 // Round down to the start of the nearest sample frame 151 offset -= (offset % (bytes_per_unit * channels)); 152 return (offset); 153 } 154 155 // Round a byte count down to a sample frame boundary. 156 off_t AudioHdr:: 157 Bytes_to_Bytes( 158 off_t& cnt) const 159 { 160 if (Validate() != AUDIO_SUCCESS) 161 return (AUDIO_UNKNOWN_SIZE); 162 163 // Round down to the start of the nearest sample frame 164 cnt -= (cnt % (bytes_per_unit * channels)); 165 return (cnt); 166 } 167 168 // Round a byte count down to a sample frame boundary. 169 size_t AudioHdr:: 170 Bytes_to_Bytes( 171 size_t& cnt) const 172 { 173 if (Validate() != AUDIO_SUCCESS) 174 return (AUDIO_UNKNOWN_SIZE); 175 176 // Round down to the start of the nearest sample frame 177 cnt -= (cnt % (bytes_per_unit * channels)); 178 return (cnt); 179 } 180 181 // Convert a count of sample frames into a floating-point time value, 182 // in seconds, using the encoding specified in the audio header. 183 Double AudioHdr:: 184 Samples_to_Time( 185 unsigned long cnt) const // sample frame count 186 { 187 if ((cnt == AUDIO_UNKNOWN_SIZE) || (Validate() != AUDIO_SUCCESS)) 188 return (AUDIO_UNKNOWN_TIME); 189 190 return ((Double)(((double)cnt * (double)samples_per_unit) / 191 (double)sample_rate)); 192 } 193 194 // Convert a floating-point time value, in seconds, to a count of sample frames 195 // for the audio encoding in the audio header. 196 unsigned long AudioHdr:: 197 Time_to_Samples( 198 Double sec) const // time, in seconds 199 { 200 if (Undefined(sec) || (Validate() != AUDIO_SUCCESS)) 201 return (AUDIO_UNKNOWN_SIZE); 202 203 // Round down to sample frame boundary 204 return ((unsigned long) (AUDIO_MINFLOAT + 205 (((double)sec * (double)sample_rate) / (double)samples_per_unit))); 206 } 207 208 // Return the number of bytes in a sample frame for the audio encoding. 209 unsigned int AudioHdr:: 210 FrameLength() const 211 { 212 return (bytes_per_unit * channels); 213 } 214