Manipulating Buffer Attributes

Buffer Attributes

This section lists the attributes that can be set, or queried, per Buffer. Note that some of these attributes can not be set using the Buffer commands, but are set using commands like BufferData.

Querying the attributes of a Buffer with a buffer name that is not valid throws an INVALID_OPERATION. Passing in an attribute name that is invalid throws an INVALID_VALUE error.

Table 1. Buffer FREQUENCY Attribute

NameSignatureValuesDefault
FREQUENCY float none (0, any]
Description: Frequency, specified in samples per second, i.e. units of Hertz [Hz]. Query by GetBuffer. The frequency state of a buffer is set by BufferData calls.

NoteAnnotation (No Frequency enumeration)
 

As the implementation has to support conversion from one frequency to another to implement pitch, it is feasible to offer support for arbitrary sample frequencies, instead of restricting the application to an enumeration of supported sample frequencies. Another reason not to limit frequency to an enumerated set is that future hardware might support variable frequencies as well (it might be preferable to choose the sampling frequency according to the PSD of the signal then).

However, it is desirable to avoid conversions due to differences between the sample frequency used in the original data, the frequency supported during the mixing, and the frequency expected by the output device.

NoteAnnotation (Implied Frequency)
 

To account for the possibility of future AL implementations supporting encoding formats for the application might not want, or be able, to retrieve the actual frequency from the encoded sample, the specification will be amended to guarantee the following behavior: If a nonzero frequency is specified, it will force a conversion from the actual to the requested frequency. If the application specifies a 0 frequency, AL will use the actual frequency. If there is no frequency information implied by the format or contained in the encoded data, specifying a 0 frequency will yield INVALID_VALUE. It is recommended that applications use NONE instead of the literal value.

NoteRFC: BITS not needed
 

This is not a setter. As a state query it doesn't provide useful information about the internal canonical format (which could be queried independent of the buffer).

Table 2. Buffer BITS Attribute

NameSignatureValuesDefault
BITSui8,160
Description: Bits per sample. This is a query-only attribute. The default value for an (empty) buffer is zero.

NoteAnnotation (No Format query)
 

As of this time there is no query for FORMAT, or format related state information. Query of the channels or bits of a given buffer make little sense if the query the internal (canonical, not buffer specific) format. Query of the original sample data format makes little sense unless the implementation is obliged to preserve the original data.

NoteRFC: CHANNELS needed?
 

No setter. Does this indicate the channels in the original data, or those in the (canonical) format internally used? Redundant to querying the buffer type. Should be enums as speaker configurations might have to be destribed by two integers: 5.1.

Table 3. Buffer CHANNELS Attribute

NameSignatureValuesDefault
CHANNELSuiRFC: enums or N/A?0
Description: Channels that buffer stores. Query only attribute. This is almost always 1, as applications using spatialized sound always downsample to mono. This depends on the purpose of the buffer: buffers used for spatialization have to provide single-channel data. The default value for an (empty) buffer is zero.

Table 4. Buffer SIZE Attribute

NameSignatureValuesDefault
SIZE sizei [0, MAX_UINT] 0
Description: Size in bytes of the buffer data. Query through GetBuffer, can be set only using BufferData calls. Setting a SIZE of 0 is a legal NOP. The number of bytes does not necessarily equal the number of samples (e.g. for compressed data).

NoteRFC: buffer overflow/underflow
 

If a SIZE is specified for a buffer and an attempt is made to write less or more data to the buffer, is this an error? Do we have SubData updates? Is trying to write data to a zero size buffer an error? Which error?

NoteRFC: query for samples/duration?
 

Do we need a query for samples (which does not equal memory size)? Do we prefer a duration query? As integral, for precision? Which, combined with frequency, has to guarantee accurate sample number?

NoteRFC: memory budgeting
 

SIZE comment said: Useful for memory budgeting with compressed data. Sounds bogus: the application can only announce how many bytes of data it intends to provide, it might not be able to estimate the uncompressed, decoded size in the internal format chosen by the implementation w/o decompressing, decoding, and querying for the internal format. Micromanaging memory is usually a bad idea. Using SIZE to configure a buffer might ge a mistake. Using the same enum to query the actual size internally (which might consists of two or more buffer areas and cached decoding state) will be confusing.

NoteRFC: buffer initial state
 

MikeV added: "The default attribute values for a Buffer are nonsensical insofar as a Buffer is incomplete without data having been specified." This seems wrong. An AL object will always be complete and valid, albeit useless. A Buffer in its default state might not produce any useful outout, but it can be specified and used.

Querying Buffer Attributes

Buffer state is maintained inside the AL implementation and can be queried in full. The valid values for paramName are identical to the ones for Buffer*.

void GetBuffer{n}{sifd}{v} ( uint bufferName, enum paramName , T * values );

Specifying Buffer Content

A special case of Buffer state is the actual sound sample data stored in asociation with the Buffer. Applications can specify sample data using BufferData.

void BufferData ( uint bufferName, enum format, void * data , sizei size , sizei frequency);

The data specified is copied to an internal software, or if possible, hardware buffer. The implementation is free to apply decompression, conversion, resampling, and filtering as needed. The internal format of the Buffer is not exposed to the application, and not accessible. Valid formats are FORMAT_MONO8, FORMAT_MONO16, FORMAT_STEREO8, and FORMAT_STEREO16. An implementation may expose other formats, see the chapter on Extensions for information on determining if additional formats are supported.

Applications should always check for an error condition after attempting to specify buffer data in case an implementation has to generate an OUT_OF_MEMORY or conversion related INVALID_VALUE error. The application is free to reuse the memory specified by the data pointer once the call to BufferData returns. The implementation has to dereference, e.g. copy, the data during BufferData execution.

NoteRFC: format enums
 

With the possible exception of sample frequency, all details of a sample (mono/stero, bit resolution, channels, encoding,compression) should be specified in a format parameter. In other words, I opt for an enumeration of formats. GL has a quite large number of those w/o suffering damage. Allowing parameters the way we do increases error cases and/or conversion load. The space is combinatorial to begin with, but an enumeration of valid formats seems better to impose restrictions. Using enums helps dealing with formats opaque to the application (compressed data with compressed header) where sample size and sampling frequency might not be available. There is the related issue of internal formats. A buffer used for spatialization will have to convert to mono. A buffer used to pass through to the output hardware will have to remap an n-channel format to an m-channel format (or let the hardware do it) including crosstalk handling depending on the output device (headphones vs. speaker). To prevent that every buffer has to do both AL needs to know the purpose of a buffer when dereferencing the data.

NoteRFC: Frequency woes
 

Frequency as a uint rises precision issues. Frequency might not be known for compressed data, we might need a (yuck) wildcard frequency specifier? We have a redundancy: frequency per context (mixing quality desired), frequency internally used by the implementation when storing the buffers, frequency provided in the data. We need to specify the latter in some cases and can't in others. Format enum or frequency enum again.

NoteRFC: data mover mess
 

API to copy data from output buffer to a buffer? BufferWriteData to supersede BufferData, BufferReadData as later extensions for buffer readback for those who want it? Reading the output stream reverses the problems we have with appendData: the application provides a memory buffer into which AL copies as much data as available/as fits.

NoteRFC: expose internal format
 

Implementations are free to use whatever internal data format is best suited for their hardware/software implementation, leaving the actual sample format and structure opaque to the application. Should applications be able to influence this? Through context creation? Per Buffer? Do we use Lowest Common Denominator or highest possible quality as a default?

NoteRFC: memory management with compressed data
 

If we allow for mixing from compressed data (perfectly reasonable for hardware) then it seems even more unlikely the application could estimate memory usage. If a compressed format is supported by AL, do we require support for mixing from compressed data? I daresay not - some formats might not allow for cheap incremental decompression.

NoteRFC: conversion and sample retrieval
 

To retrieve a sample, the size has to be queried first for allocating a properly sized memory segment as destination. This is dependent on the format. Conversion can be implemented as creating a buffer, and then requesting the data in a different format. Is this desirable? Even if we restrict reading from buffers to the same format they were written to, conversion from the internal format might be inevitable. Querying and setting the internal format however might be desirable for certain purposes.