alWriteBuffers(3dm) alWriteBuffers(3dm)
alWriteBuffers - write flexibly interleaved or non-interleaved audio data
to an audio port
#include <dmedia/audio.h>
int alWriteBuffers(const ALport port, void **bufs, int *strides, const int framecount)
port is the audio output port to which you want to write samples.
This is the returned value of an alOpenPort(3dm) call.
bufs is an array of pointers to sample buffers, each element of
which corresponds to a single channel of audio output.
strides is an array of integers, one corresponding to each output
channel. Each element indicates the number of interleaved
channels in the buffer directed at that channel.
framecount is the number of sample frames that you want to write to the
audio port.
alWriteBuffers transfers data to an audio port from a set of buffers, or
from different locations in a single buffer. alWriteBuffers allows the
application to specify how the data is interleaved.
bufs is an array of pointers to sample buffers. Each element of bufs
corresponds to one output channel. If the element is 0, that channel will
be zeroed on output. This allows an application to only direct audio at
the channels of interest.
The sample buffers can be arbitrarily interleaved; the strides parameter
indicates the number of channels in each source sample buffer. For
example, if strides[n] is 1, then bufs[n] is mono; if strides[n] is 2,
then bufs[n] is interleaved stereo, and alWriteFrames will read every
other sample from that buffer. The elements of strides can have any
value. If strides is 0, all the sample buffers are considered mono, and
alWriteBuffers does non-interleaved output.
There must be exactly as many elements in bufs and strides as the number
of channels specified for the port with alSetChannels(3dm).
alWriteBuffers blocks until framecount sample frames have been written to
the port. If you do not wish to block, make sure that framecount is less
than the return value of alGetFillable(3dm).
The expected format of each sample depends upon the configuration of the
audio port. Each sample can be an 8-, 16-, or 32-bit integer, or a
single- or double-precision floating-point value or subcode data; see
alSetSampFmt(3dm) and alSetWidth(3dm) for a description of how these
Page 1
alWriteBuffers(3dm) alWriteBuffers(3dm)
formats work. By default, the sample format is 16-bit integer (short).
Note that since an audio port contains an internal queue, samples written
to the port will not immediately come out the associated audio device or
devices. For precise synchronization of audio and other media, use
alGetFrameTime(3dm) and alGetFrameNumber(3dm) to determine when samples
will actually be output.
In order to achieve the best possible performance, alWriteBuffers does
not attempt to verify that port, bufs, or strides are valid. You should
make certain these values are valid before passing them as arguments to
alWriteBuffers.
The following code fragment opens an 8-channel audio output port and
writes 8 separate mono buffers to it. Then it mutes channels 3 and 5 and
writes the same data.
ALport p;
short buf[8][1000];
void *bufs[8];
int i,j;
ALconfig c;
c = alNewConfig();
if (!c) {
printf("config create failed:%s\n", alGetErrorString(oserror()));
exit(-1);
}
alSetChannels(c, 8);
/* open a port with our configuration */
p = alOpenPort("alWriteBuffers example","w",c);
if (!p) {
printf("port open failed:%s\n", alGetErrorString(oserror()));
exit(-1);
}
/*
* Fill our buffer. This isn't real audio data here; it's DC on each
* channel. In a real application, we'd want more meaningful data in
* each of the buffers.
*/
for (i = 0; i < 8; i++) {
/* fill channel i */
for (j = 0; j < 1000; j++) {
buf[i][j] = i * 2000;
}
bufs[i] = buf[i];
}
Page 2
alWriteBuffers(3dm) alWriteBuffers(3dm)
alWriteBuffers(p, bufs, 0, 1000); /* write 1000 8-channel frames */
/*
* Now mute channels 3 and 5
*/
bufs[2] = 0; /* channel 3 */
bufs[4] = 0; /* channel 5 */
alWriteBuffers(p, bufs, 0, 1000); /* write 1000 8-channel frames */
}
The following example writes a single 16-channel buffer to 2 8-channel
devices. This is somewhat simplified, since it does not actually
synchronize the audio between the devices. For examples of how to do
that, see the example "scrub" in /usr/share/src/dmedia/audio.
#include <audio.h>
#define NPORTS 2
#define NCHANS_PER_PORT 8
#define BUF_NCHANS (NPORTS*NCHANS_PER_PORT)
main()
{
ALport p[NPORTS];
float buf[1000 * BUF_NCHANS];
void *bufs[NPORTS][NCHANS_PER_PORT];
int strides[NCHANS_PER_PORT];
ALconfig c;
int i, j, k = 0;
/*
* Set up an array of device resource ID's. To do multi-device
* I/O meaningfully, we'd want these to be different resource ID's.
* This here will open 2 ports to the same resource ID, and the
* audio system will mix the 2 ports.
*/
int device[NPORTS]={AL_DEFAULT_OUTPUT, AL_DEFAULT_OUTPUT};
for (i = 0; i < 16000; i++) {
buf[i] = (i & 15) * 1000.0;
}
c = alNewConfig();
if (!c) {
printf("config create failed:%s\n", alGetErrorString(oserror()));
exit(-1);
}
alSetChannels(c, NCHANS_PER_PORT);
alSetFloatMax(c, 32767);
Page 3
alWriteBuffers(3dm) alWriteBuffers(3dm)
alSetSampFmt(c, AL_SAMPFMT_FLOAT);
/*
* Let's assume that in this case we know our floating-point data
* to be in range. We turn limiting off for (potentially) increased
* performance.
*/
alSetLimiting(c, 0);
/*
* Set up bufs & strides to make different NCHANS-channel "windows"
* into our buffer.
*/
k = 0;
for (j=0; j < NPORTS; j++) {
for (i=0; i < NCHANS_PER_PORT; i++) {
bufs[j][i] = &buf[k++];
}
}
for (i=0; i < NCHANS_PER_PORT; i++) {
strides[i] = BUF_NCHANS; /* 16, by default */
}
/*
* Open up NPORTS audio ports. Note that we aren't doing
* anything special to synchronize the ports here; they won't
* in general be sync'ed.
*/
for (i = 0; i < NPORTS; i++) {
alSetDevice(c, device[i]);
p[i] = alOpenPort("alWriteBuffers example","w",c);
if (!p[i]) {
printf("port open failed:%s\n", alGetErrorString(oserror()));
exit(-1);
}
}
/*
* Write 1000 frames of data to all the audio ports
*/
while (1)
for (i =0; i < NPORTS; i++) {
alWriteBuffers(p[i], bufs[i], strides, 1000);
}
}
Page 4
alWriteBuffers(3dm) alWriteBuffers(3dm)
DIAGNOSTICS
alWriteBuffers always returns 0.
On output, the data from all ports on the system writing to a particular
output device will be mixed together, except in the case of subcode data.
Because subcode data is treated as inherently logical information, no
amount mathematics can be applied to perform operations such as mixing.
This function was introduced via patch to IRIX 6.3 and 6.4, and is
present by default in later OS releases. You should ensure that the
target system will have the functionality before calling this function;
otherwise, your program will crash when you attempt to make the function
call. To determine if the feature is present, check the value of
AL_VERSION on the system resource. The parameter must be present and its
value must be at least 6.
pv.param = AL_VERSION;
alGetParams(AL_SYSTEM,&pv,1);
if (pv.sizeOut < 0 || pv.value.i < 6) {
/* feature not present */
}
alOpenPort(3dm), alGetFillable(3dm), alGetFilled(3dm),
alSetChannels(3dm), alSetWidth(3dm), alReadFrames(3dm),
alZeroFrames(3dm), alSetConfig(3dm), alSetQueueSize(3dm),
alSetSampFmt(3dm), alSetFloatMax(3dm)
PPPPaaaaggggeeee 5555 [ Back ]
|