/*
* 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
* 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 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdlib.h>
#include <memory.h>
#include <math.h>
#include <AudioTypePcm.h>
#include <libaudio.h>
#define irint(d) ((int)d)
// class AudioTypePcm methods
// Constructor
{
// Set up fixed header values; the rest are negotiable
}
// Test conversion possibilities.
AudioHdr h) const // target header
{
if (h.samples_per_unit != 1)
return (FALSE);
switch (h.encoding) {
case LINEAR:
switch (h.bytes_per_unit) {
case 1: case 2: case 4:
break;
default:
return (FALSE);
}
break;
case FLOAT:
switch (h.bytes_per_unit) {
case 4: case 8:
break;
default:
return (FALSE);
}
break;
case ULAW:
case ALAW:
switch (h.bytes_per_unit) {
case 1:
break;
default:
return (FALSE);
}
break;
default:
return (FALSE);
}
return (TRUE);
}
// Clip most negative values and convert to floating-point
inline double AudioTypePcm::
char2dbl(char B)
{
return ((unsigned char)B == 0x80 ? -1. : (double)B / 127.);
}
inline double AudioTypePcm::
short2dbl(short S)
{
return ((unsigned short)S == 0x8000 ? -1. : (double)S / 32767.);
}
inline double AudioTypePcm::
long2dbl(long L)
{
return ((unsigned long)L == 0x80000000 ? -1. : (double)L / 2147483647.);
}
// Convert floating-point to integer, scaled by the appropriate constant
inline long AudioTypePcm::
dbl2long(double D, long C)
{
}
// Simple type conversions
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
float2double(float *&F, double *&T) { *T++ = *F++; }
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
double2float(double *&F, float *&T) { *T++ = *F++; }
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
inline void AudioTypePcm::
// Convert buffer to the specified type
// May replace the buffer with a new one, if necessary
{
void* inptr;
void* outptr;
return (AUDIO_ERR_BADARG);
// Make sure we're not being asked to do the impossible
// XXX - how do we deal with multi-channel data??
// XXX - need a better error code
return (err);
return (AUDIO_ERR_HDRINVAL);
// If the buffer is not referenced, and the target size is no bigger
// than the current size, the conversion can be done in place
if (!inbuf->isReferenced() &&
} else {
// Allocate a new buffer
if (outbuf == 0)
return (AUDIO_UNIXERROR);
delete outbuf;
return (err);
}
}
// Convert from the input type to the output type
// Define macro to copy with no data conversion
// Define macro to translate a buffer
// XXX - The temporary pointers are necessary to get the updates
// token catenation different for ANSI cpp v.s. old cpp.
#ifdef __STDC__
#define MOVE(F, T) { \
}
#else
#define MOVE(F, T) { \
}
#endif
case LINEAR:
case LINEAR: // Convert linear to linear
switch (inhdr.bytes_per_unit) {
case 1:
switch (outhdr.bytes_per_unit) {
case 2: MOVE(char, short); break;
case 4: MOVE(char, long); break;
default: err = AUDIO_ERR_HDRINVAL; break;
}
break;
case 2:
switch (outhdr.bytes_per_unit) {
case 1: MOVE(short, char); break;
case 4: MOVE(short, long); break;
default: err = AUDIO_ERR_HDRINVAL; break;
}
break;
case 4:
switch (outhdr.bytes_per_unit) {
case 1: MOVE(long, char); break;
case 2: MOVE(long, short); break;
default: err = AUDIO_ERR_HDRINVAL; break;
}
break;
default:
err = AUDIO_ERR_HDRINVAL; break;
}
break;
case FLOAT: // Convert linear to float
switch (inhdr.bytes_per_unit) {
case 1:
switch (outhdr.bytes_per_unit) {
case 4: MOVE(char, float); break;
case 8: MOVE(char, double); break;
default: err = AUDIO_ERR_HDRINVAL; break;
}
break;
case 2:
switch (outhdr.bytes_per_unit) {
case 4: MOVE(short, float); break;
case 8: MOVE(short, double); break;
default: err = AUDIO_ERR_HDRINVAL; break;
}
break;
case 4:
switch (outhdr.bytes_per_unit) {
case 4: MOVE(long, float); break;
case 8: MOVE(long, double); break;
default: err = AUDIO_ERR_HDRINVAL; break;
}
break;
default:
err = AUDIO_ERR_HDRINVAL; break;
}
break;
case ULAW: // Convert linear to u-law
switch (inhdr.bytes_per_unit) {
default: err = AUDIO_ERR_HDRINVAL; break;
}
break;
case ALAW: // Convert linear to a-law
switch (inhdr.bytes_per_unit) {
default: err = AUDIO_ERR_HDRINVAL; break;
}
break;
default:
err = AUDIO_ERR_HDRINVAL; break;
}
break;
case FLOAT:
case LINEAR: // Convert float to linear
switch (inhdr.bytes_per_unit) {
case 4:
switch (outhdr.bytes_per_unit) {
case 1: MOVE(float, char); break;
case 2: MOVE(float, short); break;
case 4: MOVE(float, long); break;
default: err = AUDIO_ERR_HDRINVAL; break;
}
break;
case 8:
switch (outhdr.bytes_per_unit) {
case 1: MOVE(double, char); break;
case 2: MOVE(double, short); break;
case 4: MOVE(double, long); break;
default: err = AUDIO_ERR_HDRINVAL; break;
}
break;
default:
err = AUDIO_ERR_HDRINVAL; break;
}
break;
case FLOAT: // Convert float to float
switch (inhdr.bytes_per_unit) {
case 4:
switch (outhdr.bytes_per_unit) {
case 8: MOVE(float, double); break;
default: err = AUDIO_ERR_HDRINVAL; break;
}
break;
case 8:
switch (outhdr.bytes_per_unit) {
case 4: MOVE(double, float); break;
default: err = AUDIO_ERR_HDRINVAL; break;
}
break;
default:
err = AUDIO_ERR_HDRINVAL; break;
}
break;
case ULAW: // Convert float to u-law
switch (inhdr.bytes_per_unit) {
default: err = AUDIO_ERR_HDRINVAL; break;
}
break;
case ALAW: // Convert float to a-law
switch (inhdr.bytes_per_unit) {
default: err = AUDIO_ERR_HDRINVAL; break;
}
break;
default:
err = AUDIO_ERR_HDRINVAL; break;
}
break;
case ULAW:
case LINEAR: // Convert ulaw to linear
switch (outhdr.bytes_per_unit) {
default: err = AUDIO_ERR_HDRINVAL; break;
}
break;
case FLOAT: // Convert ulaw to float
switch (outhdr.bytes_per_unit) {
default: err = AUDIO_ERR_HDRINVAL; break;
}
break;
case ULAW: // Convert ulaw to u-law
COPY(1); break;
case ALAW: // Convert ulaw to a-law
default:
err = AUDIO_ERR_HDRINVAL; break;
}
break;
case ALAW:
case LINEAR: // Convert alaw to linear
switch (outhdr.bytes_per_unit) {
default: err = AUDIO_ERR_HDRINVAL; break;
}
break;
case FLOAT: // Convert alaw to float
switch (outhdr.bytes_per_unit) {
default: err = AUDIO_ERR_HDRINVAL; break;
}
break;
case ALAW: // Convert alaw to a-law
COPY(1); break;
case ULAW: // Convert alaw to u-law
default:
err = AUDIO_ERR_HDRINVAL; break;
}
break;
default:
err = AUDIO_ERR_HDRINVAL; break;
}
if (err) {
delete outbuf;
return (err);
}
// Finish up
// If the conversion was in-place, set the new header
} else {
// This will delete the buffer
inbuf->Dereference();
// Set the valid data length and replace the pointer
}
return (AUDIO_SUCCESS);
}
AudioBuffer*& /* buf */)
{
return (AUDIO_SUCCESS);
}