Multi-stream buffer. More...
#import <ABMultiStreamBuffer.h>
Inherits NSObject.
Instance Methods | |
(id) | - initWithClientFormat: |
Initialiser. | |
(void) | - ABMultiStreamBufferEnqueue |
Enqueue audio. | |
(void) | - ABMultiStreamBufferDequeue |
Dequeue single, mixed audio stream. | |
(void) | - ABMultiStreamBufferDequeueSingleSource |
Dequeue an individual source. | |
(UInt32) | - ABMultiStreamBufferPeek |
Peek the audio buffer. | |
(void) | - ABMultiStreamBufferEndTimeInterval |
Mark end of time interval. | |
(void) | - ABMultiStreamBufferMarkSourceIdle |
Mark the given source as idle. | |
(void) | - setVolume:forSource: |
Set volume for source. | |
(float) | - volumeForSource: |
Get volume for source. | |
(void) | - setPan:forSource: |
Set pan for source. | |
(float) | - panForSource: |
Get pan for source. | |
(void) | - setAudioDescription:forSource: |
Set a different AudioStreamBasicDescription for a source. | |
(void) | - unregisterSource: |
Force the mixer to unregister a source. | |
Properties | |
AudioStreamBasicDescription | clientFormat |
Client audio format. | |
Multi-stream buffer.
This class performs buffering and synchronization of multiple audio streams, allowing you to enqueue and buffer disparate audio streams, then dequeue the synchronized audio streams for further processing.
This is primarily for use with ABAudioReceiverPort when receiving audio as separate streams, while also receiving audio from the device audio input. In this case, all audio streams may need to be synchronized for recording or processing in your app.
See the section in the Audiobus programming guide on Receiving Separate Streams Alongside Core Audio Input for discussion on using this class.
To use the class, initialize it with the client audio format you intend to use.
Then, at each time interval (such as within a Core Audio input callback), enqueue each of your input sources - for example, first, an audio buffer from the system audio input, followed by audio from each of the connected audio sources, retrieved using ABAudioReceiverPortReceive.
Each time you enqueue a source, you must pass an identifier for that source as the second argument to ABMultiStreamBufferEnqueue. This can be any value you choose - the most sensible when enqueueing ports would be a pointer to the port itself. To identify the system audio source, you may choose to use a pointer to a static variable, like so:
static ABMultiStreamBufferSource kSystemAudioInput = &kSystemAudioInput; ... ABMultiStreamBufferEnqueue(buffer, kSystemAudioInput, ...)
Next, you dequeue audio for each source using ABMultiStreamBufferDequeue
Note that you may receive less audio than you originally requested, and you must therefore deal with this scenario appropriately.
Finally, to end the time step, you must call ABMultiStreamBufferEndTimeInterval, which will prepare the buffer for the next time interval.
Note that you may use ABMultiStreamBufferEnqueue on a different thread from ABMultiStreamBufferDequeue.
- (id) initWithClientFormat: | (AudioStreamBasicDescription) | clientFormat |
Initialiser.
clientFormat | The AudioStreamBasicDescription defining the audio format used |
- (void) ABMultiStreamBufferEnqueue | (ABMultiStreamBuffer *) | multiStreamBuffer | |
(ABMultiStreamBufferSource) | source | ||
(AudioBufferList *) | audio | ||
(UInt32) | lengthInFrames | ||
(const AudioTimeStamp *) | timestamp | ||
Enqueue audio.
Feed the buffer with audio blocks. Identify each source via the source
parameter. You may use any identifier you like - pointers, numbers, etc (just cast to ABMultiStreamBufferSource).
When you enqueue audio from a new source (that is, the source
value is one that hasn't been seen before, this class will automatically reconfigure itself to start using the new source. However, this will happen at some point in the near future, not immediately, so one or two buffers may be lost. If this is a problem, then call this function first on the main thread, for each source, with a NULL audio buffer, and a lengthInFrames value of 0.
This function can safely be used in a different thread from the dequeue function. It can also be used in a different thread from other calls to enqueue, given two conditions: No two threads enqueue the same source, and no two threads call enqueue for a new source simultaneously.
multiStreamBuffer | The multi stream buffer. |
source | The audio source. This can be anything you like, as long as it is not NULL, and is unique to each source. |
audio | The audio buffer list. |
lengthInFrames | The length of audio. |
timestamp | The timestamp associated with the audio. |
- (void) ABMultiStreamBufferDequeue | (ABMultiStreamBuffer *) | multiStreamBuffer | |
(AudioBufferList *) | bufferList | ||
(UInt32 *) | ioLengthInFrames | ||
(AudioTimeStamp *) | outTimestamp | ||
Dequeue single, mixed audio stream.
Call this function to receive synchronized and mixed audio.
Do not use this function together with ABMultiStreamBufferDequeueSingleSource.
This can safely be used in a different thread from the enqueue function.
multiStreamBuffer | The multi stream buffer. |
bufferList | The buffer list to write audio to. The mData pointers may be NULL, in which case an internal buffer will be provided. You may also pass a NULL value, which will simply discard the given number of frames. |
ioLengthInFrames | On input, the number of frames of audio to dequeue. On output, the number of frames returned. |
outTimestamp | On output, the timestamp of the first audio sample |
- (void) ABMultiStreamBufferDequeueSingleSource | (ABMultiStreamBuffer *) | multiStreamBuffer | |
(ABMultiStreamBufferSource) | source | ||
(AudioBufferList *) | bufferList | ||
(UInt32 *) | ioLengthInFrames | ||
(AudioTimeStamp *) | outTimestamp | ||
Dequeue an individual source.
Call this function, passing in a source identifier, to receive separate, synchronized audio streams.
Do not use this function together with ABMultiStreamBufferDequeue.
This can safely be used in a different thread from the enqueue function.
multiStreamBuffer | The multi stream buffer. |
source | The audio source. |
bufferList | The buffer list to write audio to. The mData pointers may be NULL, in which case an internal buffer will be provided. |
ioLengthInFrames | On input, the number of frames of audio to dequeue. On output, the number of frames returned. |
outTimestamp | On output, the timestamp of the first audio sample |
- (UInt32) ABMultiStreamBufferPeek | (ABMultiStreamBuffer *) | multiStreamBuffer | |
(AudioTimeStamp *) | outNextTimestamp | ||
Peek the audio buffer.
Use this to determine how much audio is currently buffered, and the corresponding next timestamp.
multiStreamBuffer | The multi stream buffer |
outNextTimestamp | If not NULL, the timestamp of the next available audio |
- (void) ABMultiStreamBufferEndTimeInterval | (ABMultiStreamBuffer *) | multiStreamBuffer |
Mark end of time interval.
When receiving each audio source separately via ABMultiStreamBufferDequeueSingleSource (instead of mixed with ABMultiStreamBufferDequeue), you must call this function at the end of each time interval in order to inform the mixer that you are finished with that audio segment. Any sources that have not been dequeued will have their audio discarded in order to retain synchronization.
multiStreamBuffer | The multi stream buffer. |
- (void) ABMultiStreamBufferMarkSourceIdle | (ABMultiStreamBuffer *) | multiStreamBuffer | |
(ABMultiStreamBufferSource) | source | ||
Mark the given source as idle.
Normally, if the multi stream buffer doesn't receive any audio for a given source within the time interval given by the sourceIdleThreshold property, the buffer will wait, allowing no frames to be dequeued until either further audio is received for the source, or the sourceIdleThreshold limit is met.
To avoid this delay and immediately mark a given source as idle, use this function.
multiStreamBuffer | The multi stream buffer |
source | The source to mark as idle |
- (void) setVolume: | (float) | volume | |
forSource: | (ABMultiStreamBufferSource) | source | |
Set volume for source.
Note that this will only apply when using ABMultiStreamBufferDequeue, not ABMultiStreamBufferDequeueSingleSource
- (float) volumeForSource: | (ABMultiStreamBufferSource) | source |
Get volume for source.
- (void) setPan: | (float) | pan | |
forSource: | (ABMultiStreamBufferSource) | source | |
Set pan for source.
Note that this will only apply when using ABMultiStreamBufferDequeue, not ABMultiStreamBufferDequeueSingleSource
- (float) panForSource: | (ABMultiStreamBufferSource) | source |
Get pan for source.
- (void) setAudioDescription: | (AudioStreamBasicDescription) | audioDescription | |
forSource: | (ABMultiStreamBufferSource) | source | |
Set a different AudioStreamBasicDescription for a source.
Important: Do not change this property while using enqueue/dequeue. You must stop enqueuing or dequeuing audio first.
- (void) unregisterSource: | (ABMultiStreamBufferSource) | source |
Force the mixer to unregister a source.
After this function is called, the mixer will have reconfigured to stop mixing the given source. If callbacks for the source were provided, these will never be called again after this function returns.
Use of this function is entirely optional - the multi stream buffer will automatically unregister sources it is no longer receiving audio for, and will clean up when deallocated.
source | The audio source. |
|
readwritenonatomicassign |
Client audio format.
Important: Do not change this property while using enqueue/dequeue. You must stop enqueuing or dequeuing audio first.