summaryrefslogtreecommitdiff
path: root/usr/src/cmd/audio/include/AudioHdr.h
blob: 263ed536184384f5ad6c71cc47180d0d113530cd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright (c) 1992-2001 by Sun Microsystems, Inc.
 * All rights reserved.
 */

#ifndef _MULTIMEDIA_AUDIOHDR_H
#define	_MULTIMEDIA_AUDIOHDR_H

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#ifdef NO_EXTERN_C

#ifdef __cplusplus
extern "C" {
#endif

#endif /* NO_EXTERN_C */

#include <AudioTypes.h>
#include <AudioError.h>
#include <audio_hdr.h>

// Required for the use of MAXSHORT
#include <values.h>

// Required by htons() and other network services.
#include <sys/types.h>
#include <netinet/in.h>

// Define an in-core audio data header.
//
// This is different than the on-disk file header.
//
//
// The audio header contains the following fields:
//
//	sample_rate		Number of samples per second (per channel).
//
//	samples_per_unit	This field describes the number of samples
//				  represented by each sample unit (which, by
//				  definition, are aligned on byte boundaries).
//				  Audio samples may be stored individually
//				  or, in the case of compressed formats
//				  (e.g., ADPCM), grouped in algorithm-
//				  specific ways.  If the data is bit-packed,
//				  this field tells the number of samples
//				  needed to get to a byte boundary.
//
//	bytes_per_unit		Number of bytes stored for each sample unit
//
//	channels		Number of interleaved sample units.
//				   For any given time quantum, the set
//				   consisting of 'channels' sample units
//				   is called a sample frame.  Seeks in
//				   the data should be aligned to the start
//				   of the nearest sample frame.
//
//	encoding		Data encoding format.
//
//
// The first four values are used to compute the byte offset given a
// particular time, and vice versa.  Specifically:
//
//	seconds = offset / C
//	offset = seconds * C
// where:
//	C = (channels * bytes_per_unit * sample_rate) / samples_per_unit


// Define the possible encoding types.
// XXX - As long as audio_hdr.h exists, these values should match the
//	 corresponding fields in audio_hdr.h since the cast operator
//	 copies them blindly.  This implies that the values should
//	 match any of the encodings that appear in <sys/audioio.h> also.
// XXX - How can encoding types be added dynamically?
enum AudioEncoding {
	NONE = 0,	// no encoding type set
	ULAW = 1,	// ISDN u-law
	ALAW = 2,	// ISDN A-law
	LINEAR = 3,	// PCM 2's-complement (0-center)
	FLOAT = 100,	// IEEE float (-1. <-> +1.)
	G721 = 101,	// CCITT G.721 ADPCM
	G722 = 102,	// CCITT G.722 ADPCM
	G723 = 103,	// CCITT G.723 ADPCM
	DVI = 104 	// DVI ADPCM
};

// The byte order of the data.  This is only applicable if the data
// is 16-bit.  All variables of this type will have the prefix "endian".
enum AudioEndian {
	BIG_ENDIAN = 0,	// Sun and network byte order
	LITTLE_ENDIAN = 1,  // Intel byte order
	SWITCH_ENDIAN = 2,  // Flag to switch to the opposite endian, used
			    // by coerceEndian().
	UNDEFINED_ENDIAN = -1
};

// Define a public data header structure.
// Clients must be able to modify multiple fields inbetween validity checking.
class AudioHdr {
public:
	unsigned int	sample_rate;		// samples per second
	unsigned int	samples_per_unit;	// samples per unit
	unsigned int	bytes_per_unit;		// bytes per sample unit
	unsigned int	channels;		// # of interleaved channels
	AudioEncoding	encoding;		// data encoding format
	AudioEndian	endian;			// byte order

	AudioHdr():					// Constructor
	    sample_rate(0), samples_per_unit(0), bytes_per_unit(0),
	    channels(0), encoding(NONE)
	    {
		// The default for files is BIG, but this is
		// set in the AudioUnixfile class.
		endian = localByteOrder();
	    }

	AudioHdr(Audio_hdr hdr):		// Constructor from C struct
	    sample_rate(hdr.sample_rate),
	    samples_per_unit(hdr.samples_per_unit),
	    bytes_per_unit(hdr.bytes_per_unit),
	    channels(hdr.channels),
	    encoding((AudioEncoding)hdr.encoding)
	    {
		// The default for files is BIG, but this is
		// set in the AudioUnixfile class.
		endian = localByteOrder();
	    }

	// Determines the local byte order, otherwise know as the endian
	// nature of the current machine.
	AudioEndian localByteOrder() const;

	virtual void Clear();				// Init header
	virtual AudioError Validate() const;		// Check hdr validity

	// Conversion between time (in seconds) and byte offsets
	virtual Double Bytes_to_Time(off_t cnt) const;
	virtual off_t Time_to_Bytes(Double sec) const;

	// Round down a byte count to a sample frame boundary
	virtual off_t Bytes_to_Bytes(off_t& cnt) const;
	virtual size_t Bytes_to_Bytes(size_t& cnt) const;

	// Conversion between time (in seconds) and sample frames
	virtual Double Samples_to_Time(unsigned long cnt) const;
	virtual unsigned long Time_to_Samples(Double sec) const;

	// Return the number of bytes in a sample frame for the audio encoding.
	virtual unsigned int FrameLength() const;

	// Return some meaningful strings.  The returned char pointers
	// must be deleted when the caller is through with them.
	virtual char *RateString() const;	// eg "44.1kHz"
	virtual char *ChannelString() const;	// eg "stereo"
	virtual char *EncodingString() const;	// eg "3-bit G.723"
	virtual char *FormatString() const;	// eg "4-bit G.721, 8 kHz, mono"

	// Parse strings and set corresponding header fields.
	virtual AudioError RateParse(char *);
	virtual AudioError ChannelParse(char *);
	virtual AudioError EncodingParse(char *);
	virtual AudioError FormatParse(char *);

	// for casting to C Audio_hdr struct
	operator Audio_hdr() {
		Audio_hdr hdr;

		hdr.sample_rate = sample_rate;
		hdr.samples_per_unit = samples_per_unit;
		hdr.bytes_per_unit = bytes_per_unit;
		hdr.channels = channels;
		hdr.encoding = encoding;
		hdr.endian = endian;
		return (hdr);
	};

	// compare two AudioHdr objects
	int operator == (const AudioHdr& tst)
	{
		return ((sample_rate == tst.sample_rate) &&
		    (samples_per_unit == tst.samples_per_unit) &&
		    (bytes_per_unit == tst.bytes_per_unit) &&
		    (channels == tst.channels) &&
// Audioconvert uses this method to see if a conversion should take
// place, but doesn't know how to convert between endian formats.
// This makes it ignore endian differences.
//		    (endian = tst.endian) &&
		    (encoding == tst.encoding));
	}
	int operator != (const AudioHdr& tst)
	{
		return (! (*this == tst));
	}
};

#ifdef NO_EXTERN_C

#ifdef __cplusplus
}
#endif

#endif /* NO_EXTERN_C */

#endif /* !_MULTIMEDIA_AUDIOHDR_H */