audioDeviceWriter - Play to sound card - MATLAB (original) (raw)

Description

The audioDeviceWriter System object™ writes audio samples to an audio output device. Properties of the audio device writer specify the driver, the device, and device attributes such as sample rate, bit depth, and buffer size.

Data Flow of Audio Device Writer

To stream data to an audio device:

  1. Create the audioDeviceWriter object and set its properties.
  2. Call the object with arguments, as if it were a function.

To learn more about how System objects work, see What Are System Objects?

Creation

Syntax

Description

`deviceWriter` = audioDeviceWriter returns a System object, deviceWriter, that writes audio samples to an audio output device in real time.

`deviceWriter` = audioDeviceWriter(`sampleRateValue`) sets the SampleRate property tosampleRateValue.

`deviceWriter` = audioDeviceWriter(___,`Name,Value`) sets each property Name to the specified Value. Unspecified properties have default values.

Example: deviceWriter = audioDeviceWriter(48000,'BitDepth','8-bit integer') creates a System object, deviceWriter, that operates at a 48 kHz sample rate and an 8-bit integer bit depth.

Properties

expand all

Unless otherwise indicated, properties are nontunable, which means you cannot change their values after calling the object. Objects lock when you call them, and therelease function unlocks them.

If a property is tunable, you can change its value at any time.

For more information on changing property values, seeSystem Design in MATLAB Using System Objects.

Driver used to access your audio device, specified as'DirectSound', 'ASIO', or'WASAPI'.

ASIO and WASAPI drivers do not provide sample rate conversion. For ASIO and WASAPI drivers, set SampleRate to a sample rate supported by your audio device.

This property applies only on Windows machines. Linux® machines always use the ALSA driver. Mac machines always use the CoreAudio driver.

To specify nondefault Driver values, you must have an Audio Toolbox™ license.

Data Types: char | string

Device used to play audio samples, specified as a character vector or string scalar. Use getAudioDevices to list available devices for the selected driver.

Data Types: char | string

Sample rate of signal sent to audio device, in Hz, specified as a positive integer. The range of SampleRate depends on your audio hardware.

Data Types: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

Data type used by the device, specified as a character vector or string scalar. Before performing digital-to-analog conversion, the input data is cast to a data type specified by BitDepth.

To specify a nondefault BitDepth, you must have an Audio Toolbox license.

Data Types: char | string

Option to support variable frame size, specified as true orfalse.

Data Types: char

Buffer size of audio device, specified as a positive integer.

Note

If Driver is specified as 'ASIO', open the ASIO UI to set the sound card buffer size to theBufferSize value of your audioDeviceWriter System object.

Dependencies

To enable this property, set SupportVariableSizeInput to true.

Data Types: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

Source of mapping between columns of input matrix and channels of audio output device, specified as 'Auto' or 'Property'.

Data Types: char | string

Nondefault mapping between columns of input matrix and channels of output device, specified as a scalar or vector of valid channel indices.

To selectively map between columns of the input matrix and your sound card's output channels, you must have an Audio Toolbox license.

Dependencies

To enable this property, set ChannelMappingSource to 'Property'.

Data Types: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

Usage

Syntax

Description

[numUnderrun](audiodevicewriter-system-object.html#mw%5F7285c403-2b0b-4747-b542-e2047beff574)= deviceWriter([audioToDevice](audiodevicewriter-system-object.html#mw%5Fde214585-205f-44e4-b3aa-88b50a0ae85a)) writes one frame of audio samples, audioToDevice, to the selected audio device and returns the number of audio samples underrun since the last call todeviceWriter.

example

Note: When you call the audioDeviceWriter System object, the audio device specified by the Device property is locked. An audio device can be locked by only one audioDeviceWriter at a time. To release the audio device, call release on youraudioDeviceWriter System object.

Input Arguments

expand all

Audio signal to write to device, specified as a matrix. The columns of the matrix are treated as independent audio channels.

If audioToDevice is of data type 'double' or 'single', the audio device writer clips values outside the range [–1, 1]. For other data types, the allowed input range is [min, max] of the specified data type.

Data Types: single | double | int16 | int32 | uint8

Output Arguments

expand all

Number of samples by which the audio device writer queue was underrun since the last call to deviceWriter.

Data Types: uint32

Object Functions

To use an object function, specify the System object as the first input argument. For example, to release system resources of a System object named obj, use this syntax:

expand all

getAudioDevices List available audio devices
info Characteristic information about audio device writer
clone Create duplicate System object
isLocked Determine if System object is in use
release Release resources and allow changes to System object property values and input characteristics
reset Reset internal states of System object
step Run System object algorithm
setup One-time set up tasks for System objects

Examples

collapse all

Read an MP3 audio file and play it through your default audio output device.

Create a dsp.AudioFileReader object with default settings. Use the audioinfo function to return a structure containing information about the audio file.

fileReader = dsp.AudioFileReader('speech_dft.mp3'); fileInfo = audioinfo('speech_dft.mp3')

fileInfo = struct with fields: Filename: '/mathworks/devel/bat/filer/batfs2566-0/Bdoc25a.2864802/build/runnable/matlab/toolbox/dsp/dsp/samples/speech_dft.mp3' CompressionMethod: 'MP3' NumChannels: 1 SampleRate: 22050 TotalSamples: 110033 Duration: 4.9902 Title: [] Comment: [] Artist: [] BitRate: 64

Create an audioDeviceWriter object and specify the sample rate.

deviceWriter = audioDeviceWriter('SampleRate',fileInfo.SampleRate);

Call setup to reduce the computational load of initialization in an audio stream loop.

setup(deviceWriter,zeros(fileReader.SamplesPerFrame,... fileInfo.NumChannels))

Use the info function to obtain the characteristic information about the device writer.

ans = struct with fields: Driver: 'ALSA' DeviceName: 'ALSAdefault' MaximumOutputChannels: 32

In an audio stream loop, read an audio signal frame from the file, and write the frame to your device.

while ~isDone(fileReader) audioData = fileReader(); deviceWriter(audioData); end

Close the input file and release the device.

release(fileReader) release(deviceWriter)

Latency due to the output device buffer is the time delay of writing one frame of data. Modify default properties of your audioDeviceWriter System object™ to reduce latency due to device buffer size.

Create a dsp.AudioFileReader System object to read an audio file with default settings.

fileReader = dsp.AudioFileReader('speech_dft.mp3');

Create an audioDeviceWriter System object and specify the sample rate to match that of the audio file reader.

deviceWriter = audioDeviceWriter(... 'SampleRate',fileReader.SampleRate);

Calculate the latency due to your device buffer, in seconds.

bufferLatency = fileReader.SamplesPerFrame/deviceWriter.SampleRate %#ok

Set the SamplesPerFrame property of your dsp.AudioFileReader System object to 256. Calculate the buffer latency in seconds.

fileReader.SamplesPerFrame = 256; bufferLatency = fileReader.SamplesPerFrame/deviceWriter.SampleRate

Underrun refers to output signal silence, which occurs when the audio stream loop does not keep pace with the output device. Determine the underrun of an audio stream loop, add artificial computational load to the audio stream loop, and then modify properties of your audioDeviceWriter object to decrease underrun. Your results depend on your computer.

Create a dsp.AudioFileReader object, and specify the file to read. Use the audioinfo function to return a structure containing information about the audio file.

fileReader = dsp.AudioFileReader('speech_dft.mp3'); fileInfo = audioinfo('speech_dft.mp3');

Create an audioDeviceWriter object. Use the SampleRate of the file reader as the SampleRate of the device writer. Call setup to reduce the computational load of initialization in an audio stream loop.

deviceWriter = audioDeviceWriter('SampleRate',fileReader.SampleRate); setup(deviceWriter,zeros(fileReader.SamplesPerFrame,... fileInfo.NumChannels))

Run your audio stream loop with input from file and output to device. Print the total samples underrun and the underrun in seconds.

totalUnderrun = 0; while ~isDone(fileReader) input = fileReader(); numUnderrun = deviceWriter(input); totalUnderrun = totalUnderrun + numUnderrun; end fprintf('Total samples underrun: %d.\n',totalUnderrun)

Total samples underrun: 0.

fprintf('Total seconds underrun: %d.\n',double(totalUnderrun)/double(deviceWriter.SampleRate))

Total seconds underrun: 0.

Release your dsp.AudioFileReader and audioDeviceWriter objects and set your counter variable to zero.

release(fileReader) release(deviceWriter) totalUnderrun = 0;

Use pause to mimic an algorithm that takes 0.075 seconds to process. The pause causes the audio stream loop to go slower than the device, which results in periods of silence in the output audio signal.

while ~isDone(fileReader) input = fileReader(); numUnderrun = deviceWriter(input); totalUnderrun = totalUnderrun + numUnderrun; pause(0.075) end fprintf('Total samples underrun: %d.\n',totalUnderrun)

Total samples underrun: 68608.

fprintf('Total seconds underrun: %d.\n',double(totalUnderrun)/double(deviceWriter.SampleRate))

Total seconds underrun: 3.111474e+00.

Release your audioDeviceReader and dsp.AudioFileWriter and set the counter variable to zero.

release(fileReader) release(deviceWriter) totalUnderrun = 0;

Set the frame size of your audio stream loop to 2048. Because the SupportVariableSizeInput property of your audioDeviceWriter System object is set to false, the buffer size of your audio device is the same size as the input frame size. Increasing your device buffer size decreases underrun.

fileReader = dsp.AudioFileReader('speech_dft.mp3'); fileReader.SamplesPerFrame = 2048; fileInfo = audioinfo('speech_dft.mp3');

deviceWriter = audioDeviceWriter('SampleRate',fileReader.SampleRate); setup(deviceWriter,zeros(fileReader.SamplesPerFrame,fileInfo.NumChannels))

Calculate the total underrun.

while ~isDone(fileReader) input = fileReader(); numUnderrun = deviceWriter(input); totalUnderrun = totalUnderrun + numUnderrun; pause(0.075) end fprintf('Total samples underrun: %d.\n',totalUnderrun)

Total samples underrun: 0.

fprintf('Total seconds underrun: %d.\n',double(totalUnderrun)/double(deviceWriter.SampleRate))

Total seconds underrun: 0.

The increased frame size reduces the total underrun of your audio stream loop. However, increasing the frame size also increases latency. Other approaches to reduce underrun include:

Extended Capabilities

expand all

Usage notes and limitations:

Version History

Introduced in R2016a

expand all

Specify a channel mapping in the audioDeviceWriter object to play a mono signal on only one channel of a stereo device. Set theChannelMappingSource property to "Property" and set the ChannelMapping property to 1 (left) or 2 (right).

This change affects only DirectSound and CoreAudio drivers.

Previously, setting ChannelMapping to 1 would play a mono signal in both left and right stereo channels. The default behavior for the object remains the same.