AudioHdr.h revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* 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 */