For an audio object to play sound samples, it must
have audio samples loaded against it so that it can store them in its own
local audio memory. In order to load samples into an audio object you can
call either the AddSample or AddStream methods. For small samples under 512k
you should use AddSample, while anything over that should be supported through
AddStream.
The data source used for a stream can be located either at an accessible
file location (through the Location argument), or you can supply a reference
to a public object that has stored the data (through the ObjectID argument).
You also need to set the SeekStart argument, which refers to the byte position
at which the audio data starts within the stream source. The SampleLength
argument must also refer to the byte-length of the entire audio stream.
When creating a new stream, you need to pay attention to the audio format that
is being used for the sample data. While it is important to differentiate
between simple things such as 8-bit, 16-bit, mono and stereo, you should
also be aware of whether or not the data is little or big endian, and if the
sample data consists of signed or unsigned values. Because of the possible
variations there are a number of sample formats, as illustrated in the
following table:
SFM_U8BITMONO | 8-bit mono unsigned sample. |
SFM_S16BITMONO | 16-bit mono signed sample. |
SFM_U8BITSTEREO | 8-bit stereo unsigned sample. |
SFM_S16BITSTEREO | 16-bit stereo signed sample. |
SFM_S8BITMONO | 8-bit mono signed sample. |
SFM_U16BITMONO | 16-bit mono unsigned sample. |
SFM_S8BITSTEREO | 8-bit stereo signed sample. |
SFM_U16BITSTEREO | 16-bit stereo unsigned sample. |
By default, all samples are assumed to be in little endian format, as
supported by Intel CPU's. If the data is in big endian format, you should
OR the SampleFormat value with the flag SFM_BIGENDIAN.
It is also possible to supply loop information with the stream. The
Audio class supports a number of different looping formats, rather than just
the 'repeat from the beginning once you reach the end' style of looping that
you might normally find in audio systems. The AudioLoop structure illustrates
your options:
struct AudioLoop {
WORD LoopMode; Loop mode (single, double)
BYTE Loop1Type; First loop type (unidirectional, bidirectional)
BYTE Loop2Type; Second loop type (unidirectional, bidirectional)
LONG Loop1Start; Start of the first loop
LONG Loop1End; End of the first loop
LONG Loop2Start; Start of the second loop
LONG Loop2End; End of the second loop
};
There are three types of loop modes that you can specify in the LoopMode field:
LOOP_SINGLE Single loop: The sample will continuously loop between Loop1Start and Loop1End.
LOOP_SINGLE_RELEASE Release loop: Sample data found after Loop1End will be played when the sample is released.
LOOP_DOUBLE Double loop: When the sample is released from playback, playing shifts to the second loop.
The Loop1Type and Loop2Type fields normally determine the style of the loop,
however only unidirectional looping is currently supported for streams. For
that reason, set the type variables to either NULL or LTYPE_UNIDIRECTIONAL.
This method may not be called directly if the audio object in question is
located in a foreign task. If you try to grab the audio object and call this
method, it will detect the illegal usage and return ERR_IllegalActionAttempt.
Thus the only safe way to call this method is to use the ActionMsg()
function.
ERR_Okay | The stream was created successfully. |
ERR_Args | Invalid arguments were specified. |
ERR_IllegalActionAttempt | You attempted to call this method directly using the Action() function. Use ActionMsg() instead. |
ERR_ReallocMemory | The existing sample handle array could not be expanded. |
ERR_AllocMemory | Failed to allocate the stream buffer. |
ERR_CreateObject | Failed to create a file object based on the supplied Location. |
|