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.
localByteOrder() const33 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::
Clear()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::
Validate() const65 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::
Bytes_to_Time(off_t cnt) const120 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::
Time_to_Bytes(Double sec) const138 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::
Bytes_to_Bytes(off_t & cnt) const157 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::
Bytes_to_Bytes(size_t & cnt) const170 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::
Samples_to_Time(unsigned long cnt) const184 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::
Time_to_Samples(Double sec) const197 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::
FrameLength() const210 FrameLength() const
211 {
212 return (bytes_per_unit * channels);
213 }
214