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.
localByteOrder() const35 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::
Clear()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::
Validate() const67 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::
Bytes_to_Time(off_t cnt) const122 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::
Time_to_Bytes(Double sec) const140 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::
Bytes_to_Bytes(off_t & cnt) const159 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::
Bytes_to_Bytes(size_t & cnt) const172 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::
Samples_to_Time(unsigned long cnt) const186 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::
Time_to_Samples(Double sec) const199 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::
FrameLength() const212 FrameLength() const
213 {
214 return (bytes_per_unit * channels);
215 }
216