AudioBuffer.cc 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
* 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.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdlib.h>
#include <memory.h>
#include "../include/AudioDebug.h"
#include "../include/AudioBuffer.h"
// class AudioBuffer methods
// Constructor with optional hdr, size, and name arguments
double len, // buffer length, in seconds
const char *local_name): // name
{
}
// Destructor
~AudioBuffer()
{
(void) SetSize(0.); // deallocate the buffer
}
// XXX - the following functions are good candidates for inlining
// Return TRUE if the stream is 'open'
opened() const
{
// A buffer is open if it is allocated and has a valid header
return (hdrset() && (GetAddress() != 0));
}
// Allocate buffer. Size and header must be set.
alloc()
{
long size;
unsigned int ncpy;
void* tmpbuf;
// this is going to be the size we're setting the buffer
// to (buflen field). it's set by calling SetSize().
// this is actual current size, in bytes, of the allocated
// buffer (the bufsize field).
cnt = GetByteCount();
bufsize = 0;
if (size == 0) {
// Zero size deletes the buffer
if (bufaddr != 0) {
if (zflag != 0) {
AUDIO_DEBUG((5,
"%d: AudioBuffer::alloc - zfree mmapped buffer\n",
getid()));
} else {
AUDIO_DEBUG((5,
"%d: AudioBuffer::alloc - free malloc'd buffer\n",
getid()));
}
zflag = 0;
}
bufaddr = 0;
} else if (size < 0) {
// Ridiculous size
getid()));
return (RaiseError(AUDIO_ERR_BADARG));
} else if (bufaddr == 0) {
// Allocate a new buffer
if (size > MIN_ZBUFFER) {
AUDIO_DEBUG((5,
"%d: AudioBuffer::alloc - zmalloc new buffer\n",
getid()));
zflag = 1;
} else {
AUDIO_DEBUG((5,
"%d: AudioBuffer::alloc - malloc new buffer\n",
getid()));
zflag = 0;
}
if (bufaddr == 0) {
AUDIO_DEBUG((5,
"%d: AudioBuffer::alloc - buffer alloc failed\n",
getid()));
return (RaiseError(AUDIO_UNIXERROR));
}
} else {
// A buffer was already allocated.
// Change its size, preserving as much data as possible.
(zflag == 0)) {
AUDIO_DEBUG((5,
"%d: AudioBuffer::alloc - realloc to change size\n",
getid()));
bufaddr = (void*)
} else {
AUDIO_DEBUG((5,
"%d: AudioBuffer::alloc - zmalloc new buffer\n",
getid()));
// copy over as much of the old data as will fit
if (bufaddr != 0) {
(unsigned int)size;
AUDIO_DEBUG((5,
"%d: AudioBuffer::alloc - trasnfer %d bytes\n",
}
AUDIO_DEBUG((5,
"%d: AudioBuffer::alloc - zfree old buffer\n",
getid()));
} else {
AUDIO_DEBUG((5,
"%d: AudioBuffer::alloc - free old buffer\n",
getid()));
}
zflag = 1;
}
if (bufaddr == 0) {
return (RaiseError(AUDIO_UNIXERROR));
}
}
return (AUDIO_SUCCESS);
}
// Return the buffer address
void* AudioBuffer::
GetAddress() const
{
return (GetAddress(0.));
}
// Return the buffer address at a given time offset
// Returns NULL if no buffer, or the position is not within the buffer.
void* AudioBuffer::
{
char *addr;
return (NULL);
// If no offset, it's ok if the header hasn't been set yet
if (pos == 0.)
return ((void*) addr);
// Get the header and make sure it's valid
// This convoluted hfunc works around non-const function problems
return (NULL);
// One more validation, to be paranoid before handing out this address
return (NULL);
return ((void*) addr);
}
// Return the buffer size, in bytes
// (as opposed to 'length' which indicates how much data is in the buffer)
GetByteCount() const
{
return (bufsize);
}
// Return the buffer size, in seconds
// (as opposed to 'length' which indicates how much data is in the buffer)
GetSize() const
{
return (buflen);
}
// Set the buffer size, allocating the buffer as necessary
{
// If no change in size, do nothing
return (AUDIO_SUCCESS);
// If header not set, store the size for later
if (!hdrset()) {
return (AUDIO_SUCCESS);
}
// If shrinking buffer, note this
return (alloc());
}
// Set the data header
// If no buffer allocated, allocate one now (if size is set).
// If buffer allocated, fiddle the sizes to account for new header type.
const AudioHdr& h) // header to copy
{
// Validate, then update the header
if (err)
return (RaiseError(err));
(void) AudioStream::updateheader(h);
// If no size set, done for now
if (buflen == 0.)
return (AUDIO_SUCCESS);
// If no buffer allocated, allocate one now
if (GetAddress() == 0)
return (alloc());
// If buffer allocated, change size to match new header
return (AUDIO_SUCCESS);
}
// Set the buffer length (ie, the amount of data written to the buffer)
void AudioBuffer::
{
return;
return;
// Limit to the size of the buffer
} else {
}
}
// Copy data from local buffer into specified buffer.
// No data format translation takes place.
// The object's read position is not updated.
void* buf, // destination buffer address
{
// Copy length, zero return value
len = 0;
// Cannot read if buffer or header not valid
if (!opened())
return (RaiseError(AUDIO_ERR_NOEFFECT));
// Position must be valid
return (RaiseError(AUDIO_ERR_BADARG));
// If the starting offset is at or beyond EOF, return eof flag
return (err);
}
// Limit transfer to remaining room in buffer
if (resid <= 0) {
return (err);
}
// Fix the alignment to make sure we're not splitting frames
err = AUDIO_SUCCESS;
// Copy as much data as possible
(int)cnt);
} else {
}
// Return the updated transfer size and position
// Check to see if the endian is right.
return (err);
}
// Copy data to local buffer from specified buffer.
// No data format translation takes place.
// The object's write position is not updated.
void* buf, // source buffer address
{
// Copy length, zero return value
len = 0;
// Cannot write if buffer or header not valid
if (!opened())
return (RaiseError(AUDIO_ERR_NOEFFECT));
// Position must be valid
return (RaiseError(AUDIO_ERR_BADARG));
// If the starting offset beyond end of buffer, return short write flag
return (err);
}
// Limit transfer to remaining room in buffer
if (resid <= 0) {
return (err);
}
// Fix the alignment to make sure we're not splitting frames
err = AUDIO_SUCCESS;
// Copy as much data as possible
(int)cnt);
} else {
}
// Return the updated transfer size and position
// The end of a write to a buffer always becomes the buffer EOF
return (err);
}
// AppendData is just like WriteData, except that it guarantees to extend
// the buffer if it is not big enough.
// The object's write position is not updated.
void* buf, // source buffer address
{
// Cannot write if header not valid
if (!hdrset())
return (RaiseError(AUDIO_ERR_NOEFFECT));
// Position must be valid
if (pos < 0.)
return (RaiseError(AUDIO_ERR_BADARG));
// If the ending offset is beyond end of buffer, extend it
if (local_length > GetSize()) {
return (err);
}
}
// Copy routine to copy direct to destination
{
// Cannot write if buffer or header not valid
if (!opened())
return (RaiseError(AUDIO_ERR_NOEFFECT));
if (limit < 0.)
return (RaiseError(AUDIO_ERR_BADARG));
// Get maximum possible copy length
limit = 0.;
return (err);
}
limit = 0.;
if (bptr == 0) {
return (err);
}
if (cnt == 0) {
err = AUDIO_SUCCESS;
return (err);
}
// Add a bunch of paranoid checks
// re-adjust cnt so it reads up to the end of file
}
return (err);
}
// Report short writes
}
return (err);
}