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 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <AudioHdr.h> 30 31 // class AudioHdr basic methods 32 33 // This routine uses the byteorder network utilities to tell whether the 34 // current process uses network byte order or not. 35 AudioEndian AudioHdr::localByteOrder() const 36 { 37 short sTestHost; 38 short sTestNetwork; 39 static AudioEndian ae = UNDEFINED_ENDIAN; 40 41 if (ae == UNDEFINED_ENDIAN) { 42 sTestHost = MAXSHORT; 43 sTestNetwork = htons(sTestHost); 44 if (sTestNetwork != sTestHost) { 45 ae = LITTLE_ENDIAN; 46 } else { 47 ae = BIG_ENDIAN; 48 } 49 } 50 return (ae); 51 } 52 53 // Clear a header structure 54 void AudioHdr:: 55 Clear() 56 { 57 sample_rate = 0; 58 samples_per_unit = 0; 59 bytes_per_unit = 0; 60 channels = 0; 61 encoding = NONE; 62 } 63 64 // Return error code (TRUE) if header is inconsistent or unrecognizable 65 // XXX - how do we support extensions? 66 AudioError AudioHdr:: 67 Validate() const 68 { 69 // Check for uninitialized fields 70 if ((bytes_per_unit < 1) || (samples_per_unit < 1) || 71 (sample_rate < 1) || (channels < 1)) 72 return (AUDIO_ERR_BADHDR); 73 74 switch (encoding) { 75 case NONE: 76 return (AUDIO_ERR_BADHDR); 77 78 case LINEAR: 79 if (bytes_per_unit > 4) 80 return (AUDIO_ERR_PRECISION); 81 if (samples_per_unit != 1) 82 return (AUDIO_ERR_HDRINVAL); 83 break; 84 85 case FLOAT: 86 if ((bytes_per_unit != 4) && (bytes_per_unit != 8)) 87 return (AUDIO_ERR_PRECISION); 88 if (samples_per_unit != 1) 89 return (AUDIO_ERR_HDRINVAL); 90 break; 91 92 case ULAW: 93 case ALAW: 94 case G722: 95 if (bytes_per_unit != 1) 96 return (AUDIO_ERR_PRECISION); 97 if (samples_per_unit != 1) 98 return (AUDIO_ERR_HDRINVAL); 99 break; 100 101 case G721: 102 case DVI: 103 // G.721 is a 4-bit encoding 104 if ((bytes_per_unit != 1) || (samples_per_unit != 2)) 105 return (AUDIO_ERR_PRECISION); 106 break; 107 108 case G723: 109 // G.723 has 3-bit and 5-bit flavors 110 // 5-bit is currently unsupported 111 if ((bytes_per_unit != 3) || (samples_per_unit != 8)) 112 return (AUDIO_ERR_PRECISION); 113 break; 114 } 115 return (AUDIO_SUCCESS); 116 } 117 118 119 // Convert a byte count into a floating-point time value, in seconds, 120 // using the encoding specified in the audio header. 121 Double AudioHdr:: 122 Bytes_to_Time( 123 off_t cnt) const // byte count 124 { 125 if ((cnt == AUDIO_UNKNOWN_SIZE) || (Validate() != AUDIO_SUCCESS)) 126 return (AUDIO_UNKNOWN_TIME); 127 128 // round off to nearest sample frame! 129 cnt -= (cnt % (bytes_per_unit * channels)); 130 131 return (Double) ((double)cnt / 132 ((double)(channels * bytes_per_unit * sample_rate) / 133 (double)samples_per_unit)); 134 } 135 136 // Convert a floating-point time value, in seconds, to a byte count for 137 // the audio encoding in the audio header. Make sure that the byte count 138 // or offset does not span a sample frame. 139 off_t AudioHdr:: 140 Time_to_Bytes( 141 Double sec) const // time, in seconds 142 { 143 off_t offset; 144 145 if (Undefined(sec) || (Validate() != AUDIO_SUCCESS)) 146 return (AUDIO_UNKNOWN_SIZE); 147 148 offset = (off_t)(0.5 + (sec * 149 ((double)(channels * bytes_per_unit * sample_rate) / 150 (double)samples_per_unit))); 151 152 // Round down to the start of the nearest sample frame 153 offset -= (offset % (bytes_per_unit * channels)); 154 return (offset); 155 } 156 157 // Round a byte count down to a sample frame boundary. 158 off_t AudioHdr:: 159 Bytes_to_Bytes( 160 off_t& cnt) const 161 { 162 if (Validate() != AUDIO_SUCCESS) 163 return (AUDIO_UNKNOWN_SIZE); 164 165 // Round down to the start of the nearest sample frame 166 cnt -= (cnt % (bytes_per_unit * channels)); 167 return (cnt); 168 } 169 170 // Round a byte count down to a sample frame boundary. 171 size_t AudioHdr:: 172 Bytes_to_Bytes( 173 size_t& cnt) const 174 { 175 if (Validate() != AUDIO_SUCCESS) 176 return (AUDIO_UNKNOWN_SIZE); 177 178 // Round down to the start of the nearest sample frame 179 cnt -= (cnt % (bytes_per_unit * channels)); 180 return (cnt); 181 } 182 183 // Convert a count of sample frames into a floating-point time value, 184 // in seconds, using the encoding specified in the audio header. 185 Double AudioHdr:: 186 Samples_to_Time( 187 unsigned long cnt) const // sample frame count 188 { 189 if ((cnt == AUDIO_UNKNOWN_SIZE) || (Validate() != AUDIO_SUCCESS)) 190 return (AUDIO_UNKNOWN_TIME); 191 192 return ((Double)(((double)cnt * (double)samples_per_unit) / 193 (double)sample_rate)); 194 } 195 196 // Convert a floating-point time value, in seconds, to a count of sample frames 197 // for the audio encoding in the audio header. 198 unsigned long AudioHdr:: 199 Time_to_Samples( 200 Double sec) const // time, in seconds 201 { 202 if (Undefined(sec) || (Validate() != AUDIO_SUCCESS)) 203 return (AUDIO_UNKNOWN_SIZE); 204 205 // Round down to sample frame boundary 206 return ((unsigned long) (AUDIO_MINFLOAT + 207 (((double)sec * (double)sample_rate) / (double)samples_per_unit))); 208 } 209 210 // Return the number of bytes in a sample frame for the audio encoding. 211 unsigned int AudioHdr:: 212 FrameLength() const 213 { 214 return (bytes_per_unit * channels); 215 } 216