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