Commit 6405adaa authored by Ivica Bukvic's avatar Ivica Bukvic
Browse files

*updated most of the audio API to the latest version (with the exception of...

*updated most of the audio API to the latest version (with the exception of ALSA and JACK which are partial until our improvements can be merged and/or new implementation of JACK thoroughly tested to ensure we like its default behavior)
parent 3da3a699
......@@ -205,7 +205,7 @@ proc ::dialog_audio::pdtk_audio_dialog {id \
set audio_callback $callback
set audio_blocksize $blocksize
set audio_longform $longform
set mytoplevel .prefs.nb.audio
set apifr $mytoplevel.api
if {![winfo exists $apifr]} {
......
......@@ -8493,8 +8493,7 @@ proc pdtk_audio_dialog {mytoplevel indev1 indev2 indev3 indev4 \
inchan1 inchan2 inchan3 inchan4 \
outdev1 outdev2 outdev3 outdev4 \
outchan1 outchan2 outchan3 outchan4 sr advance multi callback \
longform} {
set blocksize 64
longform blocksize} {
::dialog_audio::pdtk_audio_dialog \
$mytoplevel $indev1 $indev2 $indev3 $indev4 \
$inchan1 $inchan2 $inchan3 $inchan4 \
......
......@@ -90,6 +90,11 @@ int audio_isopen(void)
|| (audio_naudiooutdev > 0 && audio_audiochoutdev[0] > 0)));
}
int sys_audio_get_blocksize(void)
{
return (audio_blocksize);
}
void sys_get_audio_params(
int *pnaudioindev, int *paudioindev, int *chindev,
int *pnaudiooutdev, int *paudiooutdev, int *choutdev,
......@@ -146,7 +151,6 @@ void sys_save_audio_params(
audio_advance = advance;
audio_callback = callback;
audio_blocksize = blocksize;
fprintf(stderr,"blocksize=%d\n", blocksize);
}
/* init routines for any API which needs to set stuff up before
......@@ -421,7 +425,7 @@ void sys_reopen_audio( void)
#ifdef USEAPI_PORTAUDIO
if (sys_audioapi == API_PORTAUDIO)
{
int blksize = (sys_blocksize ? sys_blocksize : 64);
int blksize = (audio_blocksize ? audio_blocksize : 64);
outcome = pa_open_audio((naudioindev > 0 ? chindev[0] : 0),
(naudiooutdev > 0 ? choutdev[0] : 0), rate, sys_soundin,
sys_soundout, blksize, sys_advance_samples/blksize,
......@@ -441,7 +445,8 @@ void sys_reopen_audio( void)
#ifdef USEAPI_OSS
if (sys_audioapi == API_OSS)
outcome = oss_open_audio(naudioindev, audioindev, naudioindev,
chindev, naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate);
chindev, naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate,
audio_blocksize);
else
#endif
#ifdef USEAPI_ALSA
......@@ -456,7 +461,25 @@ void sys_reopen_audio( void)
#ifdef USEAPI_MMIO
if (sys_audioapi == API_MMIO)
outcome = mmio_open_audio(naudioindev, audioindev, naudioindev,
chindev, naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate,
audio_blocksize);
else
#endif
#ifdef USEAPI_AUDIOUNIT
if (sys_audioapi == API_AUDIOUNIT)
outcome = audiounit_open_audio((naudioindev > 0 ? chindev[0] : 0),
(naudioindev > 0 ? choutdev[0] : 0), rate);
else
#endif
#ifdef USEAPI_ESD
if (sys_audioapi == API_ALSA)
outcome = esd_open_audio(naudioindev, audioindev, naudioindev,
chindev, naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate);
else
#endif
#ifdef USEAPI_DUMMY
if (sys_audioapi == API_DUMMY)
outcome = dummy_open_audio(naudioindev, naudiooutdev, rate);
else
#endif
if (sys_audioapi == API_NONE)
......@@ -735,7 +758,7 @@ void glob_audio_properties(t_pd *dummy, t_floatarg flongform)
"pdtk_audio_dialog %%s \
%d %d %d %d %d %d %d %d \
%d %d %d %d %d %d %d %d \
%d %d %d %d %d\n",
%d %d %d %d %d %d\n",
audioindev1, audioindev2, audioindev3, audioindev4,
audioinchan1, audioinchan2, audioinchan3, audioinchan4,
audiooutdev1, audiooutdev2, audiooutdev3, audiooutdev4,
......
......@@ -11,7 +11,7 @@
#include <windows.h>
#include <MMSYSTEM.H>
#include <mmsystem.h>
/* ------------------------- audio -------------------------- */
......@@ -696,11 +696,11 @@ idle:
int mmio_open_audio(int naudioindev, int *audioindev,
int nchindev, int *chindev, int naudiooutdev, int *audiooutdev,
int nchoutdev, int *choutdev, int rate)
int nchoutdev, int *choutdev, int rate, int blocksize)
{
int nbuf;
nt_realdacblksize = (sys_blocksize ? sys_blocksize : DEFREALDACBLKSIZE);
nt_realdacblksize = (blocksize ? blocksize : DEFREALDACBLKSIZE);
nbuf = sys_advance_samples/nt_realdacblksize;
if (nbuf >= MAXBUFFER)
{
......
......@@ -5,7 +5,14 @@
/* this file inputs and outputs audio using the OSS API available on linux. */
#include <linux/soundcard.h>
#include <sys/soundcard.h>
#ifndef SNDCTL_DSP_GETISPACE
#define SNDCTL_DSP_GETISPACE SOUND_PCM_GETISPACE
#endif
#ifndef SNDCTL_DSP_GETOSPACE
#define SNDCTL_DSP_GETOSPACE SOUND_PCM_GETOSPACE
#endif
#include "m_pd.h"
#include "s_stuff.h"
......@@ -41,8 +48,11 @@ typedef int32_t t_oss_int32;
#define OSS_XFERSIZE(chans, width) (DEFDACBLKSIZE * (chans) * (width))
/* GLOBALS */
static int linux_meters; /* true if we're metering */
static t_sample linux_inmax; /* max input amplitude */
static t_sample linux_outmax; /* max output amplitude */
static int linux_fragsize = 0; /* for block mode; block size (sample frames) */
extern int audio_blocksize; /* stolen from s_audio.c */
/* our device handles */
typedef struct _oss_dev
......@@ -67,6 +77,7 @@ t_sample *sys_soundin;
/* OSS-specific private variables */
static int oss_blockmode = 1; /* flag to use "blockmode" */
static char ossdsp[] = "/dev/dsp%d";
/* don't assume we can turn all 31 bits when doing float-to-fix;
otherwise some audio drivers (e.g. Midiman/ALSA) wrap around. */
......@@ -117,10 +128,12 @@ int oss_reset(int fd) {
return err;
}
void oss_configure(t_oss_dev *dev, int srate, int dac, int skipblocksize)
void oss_configure(t_oss_dev *dev, int srate, int dac, int skipblocksize,
int suggestedblocksize)
{
int orig, param, fd = dev->d_fd, wantformat;
int orig, param, nblk, fd = dev->d_fd, wantformat;
int nchannels = dev->d_nchannels;
int advwas = sys_schedadvance;
audio_buf_info ainfo;
......@@ -148,7 +161,7 @@ void oss_configure(t_oss_dev *dev, int srate, int dac, int skipblocksize)
{
int fragbytes, logfragsize, nfragment;
/* setting fragment count and size. */
linux_fragsize = sys_blocksize;
linux_fragsize = suggestedblocksize;
if (!linux_fragsize)
{
linux_fragsize = OSS_DEFFRAGSIZE;
......@@ -192,7 +205,7 @@ void oss_configure(t_oss_dev *dev, int srate, int dac, int skipblocksize)
out. */
int defect;
if (ioctl(fd, SOUND_PCM_GETOSPACE,&ainfo) < 0)
if (ioctl(fd, SNDCTL_DSP_GETOSPACE,&ainfo) < 0)
fprintf(stderr,"OSS: ioctl on output device failed");
dev->d_bufsize = ainfo.bytes;
......@@ -234,7 +247,7 @@ static int oss_setchannels(int fd, int wantchannels, char *devname)
}
}
param = wantchannels;
//whynot:
whynot:
while (param > 1)
{
int save = param;
......@@ -251,15 +264,19 @@ static int oss_setchannels(int fd, int wantchannels, char *devname)
#define O_AUDIOFLAG O_NDELAY
int oss_open_audio(int nindev, int *indev, int nchin, int *chin,
int noutdev, int *outdev, int nchout, int *chout, int rate)
int noutdev, int *outdev, int nchout, int *chout, int rate,
int blocksize)
{
int capabilities = 0;
int inchannels = 0, outchannels = 0;
char devname[20];
int n, i, fd, flags;
char buf[OSS_MAXSAMPLEWIDTH * DEFDACBLKSIZE * OSS_MAXCHPERDEV];
int num_devs = 0;
int wantmore=0;
int spread = 0;
audio_buf_info ainfo;
linux_nindevs = linux_noutdevs = 0;
/* mark devices unopened */
for (i = 0; i < OSS_MAXDEV; i++)
......@@ -350,7 +367,7 @@ int oss_open_audio(int nindev, int *indev, int nchin, int *chin,
{
linux_dacs[linux_noutdevs].d_nchannels = gotchans;
linux_dacs[linux_noutdevs].d_fd = fd;
oss_configure(linux_dacs+linux_noutdevs, rate, 1, 0);
oss_configure(linux_dacs+linux_noutdevs, rate, 1, 0, blocksize);
linux_noutdevs++;
outchannels += gotchans;
......@@ -425,7 +442,8 @@ int oss_open_audio(int nindev, int *indev, int nchin, int *chin,
linux_adcs[linux_nindevs].d_nchannels = gotchans;
oss_configure(linux_adcs+linux_nindevs, rate, 0, alreadyopened);
oss_configure(linux_adcs+linux_nindevs, rate, 0, alreadyopened,
blocksize);
inchannels += gotchans;
linux_nindevs++;
......@@ -499,14 +517,14 @@ static void oss_calcspace(void)
audio_buf_info ainfo;
for (dev=0; dev < linux_noutdevs; dev++)
{
if (ioctl(linux_dacs[dev].d_fd, SOUND_PCM_GETOSPACE, &ainfo) < 0)
if (ioctl(linux_dacs[dev].d_fd, SNDCTL_DSP_GETOSPACE, &ainfo) < 0)
fprintf(stderr,"OSS: ioctl on output device %d failed",dev);
linux_dacs[dev].d_space = ainfo.bytes;
}
for (dev = 0; dev < linux_nindevs; dev++)
{
if (ioctl(linux_adcs[dev].d_fd, SOUND_PCM_GETISPACE,&ainfo) < 0)
if (ioctl(linux_adcs[dev].d_fd, SNDCTL_DSP_GETISPACE,&ainfo) < 0)
fprintf(stderr, "OSS: ioctl on input device %d, fd %d failed",
dev, linux_adcs[dev].d_fd);
linux_adcs[dev].d_space = ainfo.bytes;
......@@ -533,7 +551,7 @@ in audio output and/or input. */
static void oss_doresync( void)
{
int dev, zeroed = 0;
int dev, zeroed = 0, wantsize;
char buf[OSS_MAXSAMPLEWIDTH * DEFDACBLKSIZE * OSS_MAXCHPERDEV];
audio_buf_info ainfo;
......@@ -554,7 +572,7 @@ static void oss_doresync( void)
linux_adcs_read(linux_adcs[dev].d_fd, buf,
OSS_XFERSIZE(linux_adcs[dev].d_nchannels,
linux_adcs[dev].d_bytespersamp));
if (ioctl(linux_adcs[dev].d_fd, SOUND_PCM_GETISPACE, &ainfo) < 0)
if (ioctl(linux_adcs[dev].d_fd, SNDCTL_DSP_GETISPACE, &ainfo) < 0)
{
fprintf(stderr, "OSS: ioctl on input device %d, fd %d failed",
dev, linux_adcs[dev].d_fd);
......@@ -583,7 +601,7 @@ static void oss_doresync( void)
linux_dacs_write(linux_dacs[dev].d_fd, buf,
OSS_XFERSIZE(linux_dacs[dev].d_nchannels,
linux_dacs[dev].d_bytespersamp));
if (ioctl(linux_dacs[dev].d_fd, SOUND_PCM_GETOSPACE, &ainfo) < 0)
if (ioctl(linux_dacs[dev].d_fd, SNDCTL_DSP_GETOSPACE, &ainfo) < 0)
{
fprintf(stderr, "OSS: ioctl on output device %d, fd %d failed",
dev, linux_dacs[dev].d_fd);
......@@ -612,9 +630,11 @@ static void oss_doresync( void)
int oss_send_dacs(void)
{
t_sample *fp1, *fp2;
long fill;
int i, j, dev, rtnval = SENDDACS_YES;
char buf[OSS_MAXSAMPLEWIDTH * DEFDACBLKSIZE * OSS_MAXCHPERDEV];
t_oss_int16 *sp;
t_oss_int32 *lp;
/* the maximum number of samples we should have in the ADC buffer */
int idle = 0;
int thischan;
......@@ -655,6 +675,7 @@ int oss_send_dacs(void)
for (dev = 0;dev < linux_nindevs; dev++)
if (linux_adcs[dev].d_space == 0)
{
audio_buf_info ainfo;
sys_microsleep(2000);
oss_calcspace();
if (linux_adcs[dev].d_space != 0) continue;
......
This diff is collapsed.
/*
* pablio.c
* Portable Audio Blocking Input/Output utility.
*
* Author: Phil Burk, http://www.softsynth.com
*
* This program uses the PortAudio Portable Audio Library.
* For more information see: http://www.audiomulch.com/portaudio/
* Copyright (c) 1999-2000 Ross Bencina and Phil Burk
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
* they can be incorporated into the canonical version.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
/* changes by Miller Puckette to support Pd: device selection,
settable audio buffer size, and settable number of channels.
LATER also fix it to poll for input and output fifo fill points. */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "portaudio.h"
#include "s_audio_paring.h"
#include "s_audio_pablio.h" /* MSP */
#include <string.h>
/* MSP -- FRAMES_PER_BUFFER constant removed */
static void NPa_Sleep(int n) /* MSP wrapper to check we never stall... */
{
#if 0
fprintf(stderr, "sleep\n");
#endif
Pa_Sleep(n);
}
/************************************************************************/
/******** Prototypes ****************************************************/
/************************************************************************/
static int blockingIOCallback( const void *inputBuffer, void *outputBuffer, /*MSP */
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo *outTime,
PaStreamCallbackFlags myflags,
void *userData );
static PaError PABLIO_InitFIFO( sys_ringbuf *rbuf, long numFrames, long bytesPerFrame );
static PaError PABLIO_TermFIFO( sys_ringbuf *rbuf );
/************************************************************************/
/******** Functions *****************************************************/
/************************************************************************/
/* Called from PortAudio.
* Read and write data only if there is room in FIFOs.
*/
static int blockingIOCallback( const void *inputBuffer, void *outputBuffer, /* MSP */
unsigned long framesPerBuffer,
const PaStreamCallbackTimeInfo *outTime,
PaStreamCallbackFlags myflags,
void *userData )
{
PABLIO_Stream *data = (PABLIO_Stream*)userData;
(void) outTime;
/* This may get called with NULL inputBuffer during initial setup. */
if( inputBuffer != NULL )
{
sys_ringbuf_Write( &data->inFIFO, inputBuffer,
data->inbytesPerFrame * framesPerBuffer );
}
if( outputBuffer != NULL )
{
int i;
int numBytes = data->outbytesPerFrame * framesPerBuffer;
int numRead = sys_ringbuf_Read( &data->outFIFO, outputBuffer,
numBytes);
/* Zero out remainder of buffer if we run out of data. */
for( i=numRead; i<numBytes; i++ )
{
((char *)outputBuffer)[i] = 0;
}
}
return 0;
}
/* Allocate buffer. */
static PaError PABLIO_InitFIFO( sys_ringbuf *rbuf, long numFrames, long bytesPerFrame )
{
long numBytes = numFrames * bytesPerFrame;
char *buffer = (char *) malloc( numBytes );
if( buffer == NULL ) return paInsufficientMemory;
memset( buffer, 0, numBytes );
return (PaError) sys_ringbuf_Init( rbuf, numBytes, buffer );
}
/* Free buffer. */
static PaError PABLIO_TermFIFO( sys_ringbuf *rbuf )
{
if( rbuf->buffer ) free( rbuf->buffer );
rbuf->buffer = NULL;
return paNoError;
}
/************************************************************
* Write data to ring buffer.
* Will not return until all the data has been written.
*/
long WriteAudioStream( PABLIO_Stream *aStream, void *data, long numFrames )
{
long bytesWritten;
char *p = (char *) data;
long numBytes = aStream->outbytesPerFrame * numFrames;
while( numBytes > 0)
{
bytesWritten = sys_ringbuf_Write( &aStream->outFIFO, p, numBytes );
numBytes -= bytesWritten;
p += bytesWritten;
if( numBytes > 0) NPa_Sleep(10); /* MSP */
}
return numFrames;
}
/************************************************************
* Read data from ring buffer.
* Will not return until all the data has been read.
*/
long ReadAudioStream( PABLIO_Stream *aStream, void *data, long numFrames )
{
long bytesRead;
char *p = (char *) data;
long numBytes = aStream->inbytesPerFrame * numFrames;
while( numBytes > 0)
{
bytesRead = sys_ringbuf_Read( &aStream->inFIFO, p, numBytes );
numBytes -= bytesRead;
p += bytesRead;
if( numBytes > 0) NPa_Sleep(10); /* MSP */
}
return numFrames;
}
/************************************************************
* Return the number of frames that could be written to the stream without
* having to wait.
*/
long GetAudioStreamWriteable( PABLIO_Stream *aStream )
{
int bytesEmpty = sys_ringbuf_GetWriteAvailable( &aStream->outFIFO );
return bytesEmpty / aStream->outbytesPerFrame;
}
/************************************************************
* Return the number of frames that are available to be read from the
* stream without having to wait.
*/
long GetAudioStreamReadable( PABLIO_Stream *aStream )
{
int bytesFull = sys_ringbuf_GetReadAvailable( &aStream->inFIFO );
return bytesFull / aStream->inbytesPerFrame;
}
/************************************************************/
static unsigned long RoundUpToNextPowerOf2( unsigned long n )
{
long numBits = 0;
if( ((n-1) & n) == 0) return n; /* Already Power of two. */
while( n > 0 )
{
n= n>>1;
numBits++;
}
return (1<<numBits);
}
/************************************************************
* Opens a PortAudio stream with default characteristics.
* Allocates PABLIO_Stream structure.
*
* flags parameter can be an ORed combination of:
* PABLIO_READ, PABLIO_WRITE, or PABLIO_READ_WRITE
*/
PaError OpenAudioStream( PABLIO_Stream **rwblPtr, double sampleRate,
PaSampleFormat format, int inchannels,
int outchannels, int framesperbuf, int nbuffers,
int indeviceno, int outdeviceno) /* MSP */
{
long bytesPerSample;
long doRead = 0;
long doWrite = 0;
PaError err;
PABLIO_Stream *aStream;
long numFrames;
PaStreamParameters instreamparams, outstreamparams; /* MSP */
/* fprintf(stderr,
"open %lf fmt %d flags %d ch: %d fperbuf: %d nbuf: %d devs: %d %d\n",
sampleRate, format, flags, nchannels,
framesperbuf, nbuffers, indeviceno, outdeviceno); */
if (indeviceno < 0) /* MSP... */
{
indeviceno = Pa_GetDefaultInputDevice();
fprintf(stderr, "using default input device number: %d\n", indeviceno);
}
if (outdeviceno < 0)
{
outdeviceno = Pa_GetDefaultOutputDevice();
fprintf(stderr, "using default output device number: %d\n", outdeviceno);
}
/* fprintf(stderr, "nchan %d, flags %d, bufs %d, framesperbuf %d\n",
nchannels, flags, nbuffers, framesperbuf); */
/* ...MSP */
/* Allocate PABLIO_Stream structure for caller. */
aStream = (PABLIO_Stream *) malloc( sizeof(PABLIO_Stream) );
if( aStream == NULL ) return paInsufficientMemory;
memset( aStream, 0, sizeof(PABLIO_Stream) );
/* Determine size of a sample. */
bytesPerSample = Pa_GetSampleSize( format );
if( bytesPerSample < 0 )
{
err = (PaError) bytesPerSample;
goto error;
}
aStream->insamplesPerFrame = inchannels; /* MSP */
aStream->inbytesPerFrame = bytesPerSample * aStream->insamplesPerFrame;
aStream->outsamplesPerFrame = outchannels;
aStream->outbytesPerFrame = bytesPerSample * aStream->outsamplesPerFrame;
/* Initialize PortAudio */
err = Pa_Initialize();
if( err != paNoError ) goto error;
numFrames = nbuffers * framesperbuf; /* ...MSP */
instreamparams.device = indeviceno; /* MSP... */
instreamparams.channelCount = inchannels;
instreamparams.sampleFormat = format;
instreamparams.suggestedLatency = nbuffers*framesperbuf/sampleRate;
instreamparams.hostApiSpecificStreamInfo = 0;
outstreamparams.device = outdeviceno;
outstreamparams.channelCount = outchannels;
outstreamparams.sampleFormat = format;
outstreamparams.suggestedLatency = nbuffers*framesperbuf/sampleRate;
outstreamparams.hostApiSpecificStreamInfo = 0; /* ... MSP */
numFrames = nbuffers * framesperbuf;
/* fprintf(stderr, "numFrames %d\n", numFrames); */
/* Initialize Ring Buffers */
doRead = (inchannels != 0);
doWrite = (outchannels != 0);
if(doRead)
{
err = PABLIO_InitFIFO( &aStream->inFIFO, numFrames,
aStream->inbytesPerFrame );
if( err != paNoError ) goto error;
}
if(doWrite)
{
long numBytes;
err = PABLIO_InitFIFO( &aStream->outFIFO, numFrames,
aStream->outbytesPerFrame );
if( err != paNoError ) goto error;
/* Make Write FIFO appear full initially. */
numBytes = sys_ringbuf_GetWriteAvailable( &aStream->outFIFO );
sys_ringbuf_AdvanceWriteIndex( &aStream->outFIFO, numBytes );
}
/* Open a PortAudio stream that we will use to communicate with the underlying
* audio drivers. */
err = Pa_OpenStream(
&aStream->stream,
(doRead ? &instreamparams : 0), /* MSP */
(doWrite ? &outstreamparams : 0), /* MSP */
sampleRate,
framesperbuf, /* MSP */
paNoFlag, /* MSP -- portaudio will clip for us */
blockingIOCallback,
aStream );
if( err != paNoError ) goto error;
err = Pa_StartStream( aStream->stream );
if( err != paNoError ) /* MSP */
{
fprintf(stderr, "Pa_StartStream failed; closing audio stream...\n");
CloseAudioStream( aStream );
goto error;
}
*rwblPtr = aStream;
return paNoError;
error:
*rwblPtr = NULL;
return err;
}
/************************************************************/
PaError CloseAudioStream( PABLIO_Stream *aStream )
{
PaError err;
int bytesEmpty;
int byteSize = aStream->outFIFO.bufferSize;
/* If we are writing data, make sure we play everything written. */
if( byteSize > 0 )